Skip to content

[13.x] Introduce Bus::bulk()#60297

Merged
taylorotwell merged 7 commits into
laravel:13.xfrom
jackbayliss:13.x-bus-dispatch-bulk
May 30, 2026
Merged

[13.x] Introduce Bus::bulk()#60297
taylorotwell merged 7 commits into
laravel:13.xfrom
jackbayliss:13.x-bus-dispatch-bulk

Conversation

@jackbayliss
Copy link
Copy Markdown
Contributor

@jackbayliss jackbayliss commented May 27, 2026

Tip

This is purely for the most optimized way of getting jobs into a queue, it does not check for uniqueness, debounce etc.. ie the same as Bus::batch, but without the increment.

When you need to dispatch multiple jobs at once, ie when a user has done a mass import, export etc.. the only option today (at least to my knowledge 🌚) is:

  • looping over dispatch()
  • Bus::batch,
  • Queue::bulk (if you know the internals)

Having to squeeze every bit of resources I can, one thing I've noticed is:

  • Doing a dispatch() in a foreach is very resource intensive on the driver, as its 1x insert, if you have a lot of other operations going on (jobs etc) .. do this 80k times it adds up
  • Bus::batch is great if we care about the tracking of the batch/jobs, but it also writes to the database on every job completion to track progress meaning 1x insert so similar to the above tbh

So, to counter this currently we end up doing something like (I have done this, Im sorry):

Queue::bulk(
      array_map(fn (User $user) => new ProcessUser($user), $users),
      '',
      'some-queue'
  ); 
  
  // Similar logic below for other queues.

The Queue::bulk way above works, but it doesn't feel the best as we have to handle different queues, etc and the signature seems a bit odd.

All we want to do is basically put the jobs on the queue in the most efficient way possible, if they fail that's fine they'll go to failed_jobs.

SO this PR adds Bus::bulk to just let us do:

  Bus::bulk(array_map(fn (User $user) => new ProcessUser($user), $users));

The method groups by queues and connections automatically, so you dont have to handle it in userland, with the added efficiency of calling bulk() underneath and a nicer DX.

This is extremely useful as it avoids the one dispatch per job and is completely safe cause the bulk method is needed by the Queue interface 😎

This is the same as Bus::batch in the sense it just sends the jobs to the queue, just without the incrementing.

This made sense in my head rather than adding a flag like withoutIncrementing() on Bus::batch, but open to your guidance as I'm just shootin my shot to try make this more obvious, feel free to adjust 🫡

@github-actions
Copy link
Copy Markdown

Thanks for submitting a PR!

Note that draft PRs are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@shaedrich
Copy link
Copy Markdown
Contributor

  Bus::dispatchBulk(array_map(fn (User $user) => new ProcessUser($user), $users));

It would be nice to even have a shorthand like this when one doesn't need any imperative logic at all:

    Bus::dispatchBulk(ProcessUser::class, $users);

@jackbayliss jackbayliss marked this pull request as ready for review May 28, 2026 08:29
@jackbayliss
Copy link
Copy Markdown
Contributor Author

@shaedrich Seems like a good idea, will leave it for a follow up PR, as don't wanna overcomplicate it just incase 👍🏻

@taylorotwell taylorotwell merged commit 0f326e4 into laravel:13.x May 30, 2026
52 checks passed
@jackbayliss jackbayliss changed the title [13.x] Introduce Bus::dispatchBulk() [13.x] Introduce Bus::bulk() May 30, 2026
@jackbayliss jackbayliss deleted the 13.x-bus-dispatch-bulk branch May 31, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants