The Daily Commit · Section Edition Front Page PHP AI Dev EN DE FR ES

The Php Times

Reads — Ecosystem

Queue-SQL Package Splits Large Laravel Updates and Deletes into Parallel Queue Jobs


Queue-SQL, a Laravel package by Kamran Atayev, breaks massive UPDATE and DELETE statements into key-range slices processed as parallel queued jobs via Laravel's native batching.

LARAVEL NEWS, July 28, 2026 curated by Sönke

It offers a queue() query builder macro, CLI monitoring, dry-run previews, and Horizon tagging, requiring PHP 8.1+ and Laravel 10-13.

Running a single UPDATE or DELETE over millions of rows can hold database locks for minutes, leave replicas lagging, or time out during deployments. Queue-SQL, a Laravel package by Kamran Atayev, addresses this by splitting large writes into parallel queued jobs: it determines the minimum and maximum primary keys for a query, cuts the ID range into bounded slices, and dispatches an Illuminate\Bus\Batch to process each slice independently.

The package registers a queue() macro on both the Query Builder and Eloquent, exposing update, delete, insert, and upsert. Constraints are compiled into SQL fragments and bindings, so nested closures, whereHas, whereExists, and sub-selects survive the trip to workers without closure serialization problems. Job sizing works via chunk (rows per job) or maxJobs (a target total across the key range); the two are mutually exclusive and passing both throws an InvalidArgumentException. dispatch() returns a native Illuminate\Bus\Batch supporting then, catch, finally, and allowFailures.

Usage chains queue() onto a query before the write method and ends with dispatch() — nothing is queued until then. Example: Order::where('status', 'complete')->queue(chunk: 25000, tries: 2, onQueue: 'maintenance', throttle: 4)->update(['status' => 'completed'])->dispatch(). The throttle option caps jobs per second, protecting database connections and replicas during big backfills. Deletes use identical syntax, while bulk inserts skip key-range planning and split the record array across jobs instead.

Because each update or delete job targets a fixed key slice, retries are idempotent. Retried insert jobs are not, and can create duplicates — the docs recommend a unique index or upsert() where retry safety matters. Compared to Laravel's Prunable trait and model:prune command, which delete sequentially in one process, Queue-SQL runs concurrently, tracks progress as a batch, and also handles arbitrary updates and bulk inserts.

Replacing dispatch() with dryRun() previews the batching plan (operation, table, job count, ranges, estimated rows) without queueing anything. Key-range chunking uses min/max primary key values rather than exact row counts, so tables with large ID gaps produce uneven job sizes while the total job count stays fixed.

The CLI monitors batches directly against the framework's batch table: queue-sql:status lists or inspects batches, queue-sql:cancel stops one, --watch refreshes every two seconds in interactive terminals (printing once in non-interactive contexts), and --json formats output. Status output shows total, pending and failed jobs, progress percentages, and batch state. Horizon users get automatic tags with queue-sql, the operation type, and target tables. Global defaults for chunk size, retries, backoff, throttling, delays, and queue names live in config/queue-sql.php.

Requirements are PHP 8.1+ and Laravel 10 through 13, with SQLite, MySQL, and PostgreSQL supported. Installation is composer require kamranata/queue-sql, followed by queue:batches-table and migrate, since the package relies on native job batching. Two caveats: slicing needs an incrementing integer primary key (other tables fall back to a single queued job), and key boundaries are fixed at dispatch time, so rows inserted afterward with higher IDs are not covered. A benchmark script (benchmarks/lock_duration.php) ships with the repo; in a 20,000-row SQLite delete test, an un-batched DELETE held a lock 3.6 times longer than Queue-SQL's longest recorded lock.

Read the original source ↗

Rate this article: 0

Readers’ Forum

No contributions yet — open the debate.

← Ecosystem — Page B1

"All the Code That's Fit to Ship" · The Daily Commit · Screen edition · Imprint · Privacy Policy