Queue-SQL: Parallel Mass Deletes &amp; Updates in Laravel | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. Queue-SQL: Run Mass Deletes and Updates Across Parallel Laravel Queue Jobs

   [Laravel](https://www.msaied.com/public/articles?category=laravel) [Composer Pacakge](https://www.msaied.com/public/articles?category=composer-pacakge) 

 Queue-SQL: Run Mass Deletes and Updates Across Parallel Laravel Queue Jobs
===========================================================================

 Queue-SQL is a Laravel package that splits large UPDATE and DELETE statements into parallel queued jobs using key-range chunking, preventing long database locks, replication lag, and query timeouts.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 27 Jul 2026 · Updated 31 Jul 2026 · 2 min read

ShareCopy linkCopied

 ![Queue-SQL: Run Mass Deletes and Updates Across Parallel Laravel Queue Jobs](https://cdn.msaied.com/492/8fe3dd45d6d400fe5fd7d8ed1dd0e98b.png) 

  On this page +1. [The Problem with Mass Database Writes in Laravel](#the-problem-with-mass-database-writes-in-laravel)
2. [How Queue-SQL Works](#how-queue-sql-works)
3. [Queueing a Write Query](#queueing-a-write-query)
4. [Previewing the Execution Plan](#previewing-the-execution-plan)
5. [Monitoring Batches from the CLI](#monitoring-batches-from-the-cli)
6. [Installation](#installation)
7. [Key Takeaways](#key-takeaways)

 The Problem with Mass Database Writes in Laravel
------------------------------------------------

Running a single `UPDATE` or `DELETE` across millions of rows is a common source of production pain. Long-held database locks, replicas falling behind, and deployment timeouts are all symptoms of the same root cause: trying to do too much in one query.

**Queue-SQL**, a Laravel package by [Kamran Atayev](https://github.com/kamranata), solves this by splitting large write operations into parallel queued jobs backed by Laravel's native `Illuminate\Bus\Batch`.

How Queue-SQL Works
-------------------

The package registers a `queue()` macro on both the Query Builder and Eloquent, making it available anywhere you'd normally write a query. When you call `dispatch()`, Queue-SQL:

1. Calculates the minimum and maximum primary key values for your query.
2. Divides that ID range into bounded slices.
3. Dispatches a `Bus\Batch` where each job targets one slice independently.

Because each job targets a fixed key range, retrying an `UPDATE` or `DELETE` job is idempotent—it operates on the same rows every time.

Queueing a Write Query
----------------------

Chain `queue()` before your write method and call `dispatch()` at the end. Nothing is queued until `dispatch()` is invoked:

```php
use App\Models\Order;

Order::where('status', 'complete')
    ->queue(chunk: 25000, tries: 2, onQueue: 'maintenance', throttle: 4)
    ->update(['status' => 'completed'])
    ->then(fn (Batch $batch) => Log::info("Backfill finished in {$batch->totalJobs} jobs"))
    ->catch(fn (Throwable $e) => report($e))
    ->dispatch();

```

The `throttle` argument caps the batch at a given number of jobs per second, preventing worker saturation and replication lag during large backfills.

Deletes follow the same pattern:

```php
PersonalAccessToken::where('expires_at', '
