Rajtík's blog

← Back to home

Programming 2 min read

Laravel queues without Redis

Most projects get by with the database driver and never need Redis. Here is how to run a queue on MySQL, where it hits its limits and how to tell it is time to move on.

Redis looks like the obvious choice for a queue. But why add another service when you already have a database you back up and watch? For most small projects, it is enough.

What you need

A table of jobs and a worker that reads from it. Laravel does this out of the box:

php artisan make:queue-table
php artisan migrate
php artisan queue:work --tries=3

Then switch the driver to database in .env. Nothing else to install.

A job that may run twice

Every job should be safe to run more than once. The worker retries after a failure, so keep it idempotent:

class SendInvoice implements ShouldQueue
{
    public int $tries = 3;

    public function handle(InvoiceMailer $mailer): void
    {
        $mailer->sendOnce($this->invoice);
    }
}

Where it starts to hurt

The database queue has limits. This is what I measured on a small server:

Driver Jobs per second Latency Note
database 120 1 s fine for invoices and emails
redis 2,400 5 ms overkill until you hit the wall

As long as workers do not wait on a table lock, you have no problem. Once they do, move to Redis.

The switch is boring, which is good. You change the driver and the rest of the code stays the same.


When to move on

  1. The queue grows faster than workers drain it.
  2. Jobs must run within a few milliseconds.
  3. The database is already busy and the queue takes its performance.

If none of that applies, stay on the database. Details are in the Laravel docs, and you can watch the backlog with php artisan queue:monitor.