diff --git a/deploy/compile/perform_compilation.go b/deploy/compile/perform_compilation.go
index 8f14d4f49dd536f2d266e961307d86b105522417..dd2a385cc1ecfb1130f3c495e57664e99d4b9229 100644
--- a/deploy/compile/perform_compilation.go
+++ b/deploy/compile/perform_compilation.go
@@ -94,6 +94,10 @@ func RequestBinaryLinkage(file string, libraries map[string]string) (*BinaryResp
 	if err != nil {
 		return &BinaryResponse{}, err
 	}
+	return BinaryLinkage(contract, libraries)
+}
+
+func BinaryLinkage(contract SolidityOutputContract, libraries map[string]string) (*BinaryResponse, error) {
 	bin := contract.Evm.Bytecode.Object
 	if !strings.Contains(bin, "_") {
 		return &BinaryResponse{
@@ -103,7 +107,7 @@ func RequestBinaryLinkage(file string, libraries map[string]string) (*BinaryResp
 		}, nil
 	}
 	var links map[string]map[string][]struct{ Start, Length int }
-	err = json.Unmarshal(contract.Evm.Bytecode.LinkReferences, &links)
+	err := json.Unmarshal(contract.Evm.Bytecode.LinkReferences, &links)
 	if err != nil {
 		return &BinaryResponse{}, err
 	}
diff --git a/deploy/jobs/job_manager.go b/deploy/jobs/job_manager.go
index 2fdf62d5863333359a1458f43c396424500b47b5..1c6a9096cb22d739801642f1b4ea1d784da77afc 100644
--- a/deploy/jobs/job_manager.go
+++ b/deploy/jobs/job_manager.go
@@ -2,13 +2,28 @@ package jobs
 
 import (
 	"fmt"
+	"path/filepath"
 	"strings"
 
+	compilers "github.com/hyperledger/burrow/deploy/compile"
 	"github.com/hyperledger/burrow/deploy/def"
 	"github.com/hyperledger/burrow/deploy/util"
 	log "github.com/sirupsen/logrus"
 )
 
+type trackJob struct {
+	payload      def.Payload
+	job          *def.Job
+	compilerResp *compilers.Response
+	err          error
+	done         chan struct{}
+}
+
+func compile(contract string, track *trackJob) {
+	(*track).compilerResp, (*track).err = compilers.RequestCompile(contract, false, nil)
+	close(track.done)
+}
+
 func RunJobs(do *def.Packages) error {
 
 	// Dial the chain if needed
@@ -40,21 +55,51 @@ func RunJobs(do *def.Packages) error {
 		return fmt.Errorf("error validating Burrow deploy file at %s: %v", do.YAMLPath, err)
 	}
 
+	intermediateJobs := make([]*trackJob, 0, len(do.Package.Jobs))
+
 	for _, job := range do.Package.Jobs {
 		payload, err := job.Payload()
 		if err != nil {
 			return fmt.Errorf("could not get Job payload: %v", payload)
 		}
-		err = util.PreProcessFields(payload, do)
+
+		track := trackJob{job: job, payload: payload}
+		intermediateJobs = append(intermediateJobs, &track)
+
+		// Do compilation first
+		switch payload.(type) {
+		case *def.Build:
+			track.done = make(chan struct{})
+			go compile(job.Build.Contract, &track)
+		case *def.Deploy:
+			if filepath.Ext(job.Deploy.Contract) == ".sol" {
+				track.done = make(chan struct{})
+				go compile(job.Deploy.Contract, &track)
+			}
+		}
+	}
+
+	for _, m := range intermediateJobs {
+		job := m.job
+
+		err = util.PreProcessFields(m.payload, do)
 		if err != nil {
 			return err
 		}
 		// Revalidate with possible replacements
-		err = payload.Validate()
+		err = m.payload.Validate()
 		if err != nil {
 			return fmt.Errorf("error validating job %s after pre-processing variables: %v", job.Name, err)
 		}
-		switch payload.(type) {
+
+		if m.done != nil {
+			<-m.done
+			if m.err != nil {
+				return m.err
+			}
+		}
+
+		switch m.payload.(type) {
 		// Meta Job
 		case *def.Meta:
 			announce(job.Name, "Meta")
@@ -88,13 +133,13 @@ func RunJobs(do *def.Packages) error {
 		// Contracts jobs
 		case *def.Deploy:
 			announce(job.Name, "Deploy")
-			job.Result, err = DeployJob(job.Deploy, do)
+			job.Result, err = DeployJob(job.Deploy, do, m.compilerResp)
 		case *def.Call:
 			announce(job.Name, "Call")
 			job.Result, job.Variables, err = CallJob(job.Call, do)
 		case *def.Build:
 			announce(job.Name, "Build")
-			job.Result, err = BuildJob(job.Build, do)
+			job.Result, err = BuildJob(job.Build, do, m.compilerResp)
 
 		// State jobs
 		case *def.RestoreState:
diff --git a/deploy/jobs/jobs_contracts.go b/deploy/jobs/jobs_contracts.go
index ce6427418cf1519e83556318d67843862b8131af..0686d3ce38b5f5b77efbb8c5ab12525a6ae1b597 100644
--- a/deploy/jobs/jobs_contracts.go
+++ b/deploy/jobs/jobs_contracts.go
@@ -18,7 +18,7 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
-func BuildJob(build *def.Build, do *def.Packages) (result string, err error) {
+func BuildJob(build *def.Build, do *def.Packages, resp *compilers.Response) (result string, err error) {
 	// assemble contract
 	contractPath, err := findContractFile(build.Contract, do.BinPath)
 	if err != nil {
@@ -28,10 +28,9 @@ func BuildJob(build *def.Build, do *def.Packages) (result string, err error) {
 	log.WithField("=>", contractPath).Info("Contract path")
 
 	// normal compilation/deploy sequence
-	resp, err := compilers.RequestCompile(contractPath, false, make(map[string]string))
-	if err != nil {
-		log.Errorln("Error compiling contracts: Compilers error:")
-		return "", err
+	if resp == nil {
+		log.Errorln("Error compiling contracts: Missing compiler result")
+		return "", fmt.Errorf("internal error")
 	} else if resp.Error != "" {
 		log.Errorln("Error compiling contracts: Language error:")
 		return "", fmt.Errorf("%v", resp.Error)
@@ -78,7 +77,7 @@ func BuildJob(build *def.Build, do *def.Packages) (result string, err error) {
 	return "", nil
 }
 
-func DeployJob(deploy *def.Deploy, do *def.Packages) (result string, err error) {
+func DeployJob(deploy *def.Deploy, do *def.Packages, resp *compilers.Response) (result string, err error) {
 	deploy.Libraries, _ = util.PreProcessLibs(deploy.Libraries, do)
 	// trim the extension
 	contractName := strings.TrimSuffix(deploy.Contract, filepath.Ext(deploy.Contract))
@@ -153,11 +152,10 @@ func DeployJob(deploy *def.Deploy, do *def.Packages) (result string, err error)
 		contractPath = deploy.Contract
 		log.WithField("=>", contractPath).Info("Contract path")
 		// normal compilation/deploy sequence
-		resp, err := compilers.RequestCompile(contractPath, false, libs)
 
-		if err != nil {
-			log.Errorln("Error compiling contracts: Compilers error:")
-			return "", err
+		if resp == nil {
+			log.Errorln("Error compiling contracts: Missing compiler result")
+			return "", fmt.Errorf("internal error")
 		} else if resp.Error != "" {
 			log.Errorln("Error compiling contracts: Language error:")
 			return "", fmt.Errorf("%v", resp.Error)
@@ -172,7 +170,7 @@ func DeployJob(deploy *def.Deploy, do *def.Packages) (result string, err error)
 			log.WithField("=>", string(response.Binary.Abi)).Info("Abi")
 			log.WithField("=>", response.Binary.Evm.Bytecode.Object).Info("Bin")
 			if response.Binary.Evm.Bytecode.Object != "" {
-				result, err = deployContract(deploy, do, response)
+				result, err = deployContract(deploy, do, response, libs)
 				if err != nil {
 					return "", err
 				}
@@ -184,7 +182,7 @@ func DeployJob(deploy *def.Deploy, do *def.Packages) (result string, err error)
 				if response.Binary.Evm.Bytecode.Object == "" {
 					continue
 				}
-				result, err = deployContract(deploy, do, response)
+				result, err = deployContract(deploy, do, response, libs)
 				if err != nil {
 					return "", err
 				}
@@ -205,7 +203,7 @@ func DeployJob(deploy *def.Deploy, do *def.Packages) (result string, err error)
 				if matchInstanceName(response.Objectname, deploy.Instance) {
 					log.WithField("=>", string(response.Binary.Abi)).Info("Abi")
 					log.WithField("=>", response.Binary.Evm.Bytecode.Object).Info("Bin")
-					result, err = deployContract(deploy, do, response)
+					result, err = deployContract(deploy, do, response, libs)
 					if err != nil {
 						return "", err
 					}
@@ -241,9 +239,14 @@ func findContractFile(contract, binPath string) (string, error) {
 }
 
 // TODO [rj] refactor to remove [contractPath] from functions signature => only used in a single error throw.
-func deployContract(deploy *def.Deploy, do *def.Packages, compilersResponse compilers.ResponseItem) (string, error) {
+func deployContract(deploy *def.Deploy, do *def.Packages, compilersResponse compilers.ResponseItem, libs map[string]string) (string, error) {
 	log.WithField("=>", string(compilersResponse.Binary.Abi)).Debug("Specification (From Compilers)")
-	contractCode := compilersResponse.Binary.Evm.Bytecode.Object
+
+	linked, err := compilers.BinaryLinkage(compilersResponse.Binary, libs)
+	if err != nil {
+		return "", err
+	}
+	contractCode := linked.Binary
 
 	// Save
 	if _, err := os.Stat(do.BinPath); os.IsNotExist(err) {