Laravel Magazine
Laravel's New Bus::bulk() Dispatches Huge Job Batches in One Insert

Laravel's New Bus::bulk() Dispatches Huge Job Batches in One Insert

Eric Van Johnson ·

In its June 2026 product updates, published on July 2nd, the Laravel team announced Bus::bulk(), a framework addition aimed squarely at the cost of dispatching very large numbers of queued jobs. If you have ever pushed tens of thousands of jobs onto a database-backed queue and watched the dispatch loop crawl, this one is for you.

The Problem It Solves

When you dispatch jobs one at a time to a database queue driver, each dispatch is its own INSERT into the jobs table. Enqueue fifty thousand jobs and that is fifty thousand round trips to the database, each with its own write overhead. The work of enqueuing can end up taking longer than you would like, and it puts avoidable pressure on the database.

What Bus::bulk() Does

According to the changelog, Bus::bulk() queues large batches of jobs with a single bulk database insert per queue and connection, removing the per-job write cost of dispatching one at a time. Instead of a loop that inserts row by row, the framework groups the jobs and writes them together.

use Illuminate\Support\Facades\Bus;

$jobs = $users->map(fn ($user) => new SendMonthlyStatement($user));

Bus::bulk($jobs);

Because the grouping happens per queue and per connection, jobs destined for different queues are still routed correctly. You hand the framework a collection of job instances, and it works out how to write them efficiently.

Where This Fits

This sits alongside Laravel's existing job batching, which groups related jobs so you can track their combined progress and run completion callbacks. The distinction is worth keeping straight. Batching, via Bus::batch(), is about coordinating a set of jobs and knowing when they all finish. Bus::bulk() is about the raw efficiency of getting a large number of jobs onto the queue in the first place. The two solve different problems and can be used together.

Should You Care?

If your app dispatches jobs in modest numbers, the per-job insert cost was never your bottleneck and you will not notice a difference. The teams that will feel this are the ones fanning out large workloads: sending statements to an entire customer base, reindexing a catalog, or importing a large dataset and spawning a job per record. For those workloads, collapsing thousands of inserts into a handful is a meaningful win at the exact moment your system is under the most pressure.

The feature shipped as part of the framework alongside Postgres transaction pooler support and expanded MCP client and server tooling. As always, check the official changelog for the precise version and behavior before relying on it in production.

Further Reading

Stay Updated

Subscribe to our newsletter

Get latest news, tutorials, community articles and podcast episodes delivered to your inbox.

Weekly articles
We send a new issue of the newsletter every week on Friday.
No spam
We'll never share your email address and you can opt out at any time.