You cannot have concurrent jobs (in parallel) and keep everything working. Unless you implement a job monitoring system you cannot guarantee a job finishing before the next pipe is called. Instead I solved this in two ways. My first was was to an asynchronous job to call synchronous jobs (jobs without the implements ShouldQueue).
PrepareDownload::dispatch($payload);
AssembleDownload::dispatch($payload);
MoveDownload::dispatch($payload);
CleanUp::dispatch($payload);
However, I realized this was really a pipeline so my next was to use an asynchronous job to call a pipeline. I preferred this method because I could pass along a payload to each pipe and the pipe could build on that payload.
$pipeline = app(Pipeline::class);
$pipeline->send($payload)
->through([
PrepareDownload::class,
AssembleDownload::class,
MoveDownload::class,
CleanUp::class,
])->then(function ($payload) {
Mail::to($user)->send(new SendUserFile($payload));
});