Skip to content

Decision

Queues against cron, and when cron is still the right answer

Replacing cron with a queue is treated as an obvious modernisation. It is a trade, and there are systems where cron is the correct answer and the queue is a liability.

The short answer

Use cron when the work is idempotent, cheap to repeat, and nobody will ever ask whether a specific run happened. Use a queue the moment you need per item retry, per item history, or the ability to answer what happened at four in the morning.

Verdict

Queue, once the work matters enough that somebody will ask about a specific run. Cron until then, and cron for the sweep that drives the queue.

The real difference

Cron fires a process on a schedule. It has no memory, no notion of individual work items, no retry, and no record. That is not a criticism, it is the design, and for a large class of jobs it is exactly enough.

A queue has all four. It also has infrastructure, a failure mode of its own, and a meaningful amount of operational surface you now own.

When cron is correct

Three conditions, and you want all three.

The work is idempotent and cheap to repeat. Rebuilding a cache, recomputing a summary, cleaning up temporary files. Running it twice costs nothing.

There are no individual items. The job is one indivisible thing, not a loop over ten thousand records where each one can independently succeed or fail.

Nobody will ever ask about a specific run. If the only question anyone asks is whether it is broadly working, a monitor on the outcome is enough.

Under those conditions a queue adds a dependency, a dashboard, and a new way for things to break, in exchange for capabilities the work does not need.

When you have outgrown it

The clearest signal is a question you cannot answer. Somebody asks whether a particular thing was processed last Tuesday, and answering means reading logs, if they still exist.

That question means the work is now important, and cron has no memory of important things.

The others follow the same shape. When a failure affects one item out of thousands and you have to rerun everything to fix it, you need per item retry. When the process dies halfway and nobody can say which half completed, you need per item state. When a single slow item delays everything behind it, you need lanes.

The hybrid, which is what most mature systems actually run

Not either. Both, with a clear division.

Cron does one job: it fires a sweep. The sweep looks at durable state, finds work that is due, and enqueues it. The queue then does the execution, the retries, and the record.

That gives you a scheduler with memory while keeping the trigger boringly simple. The sweep is also what makes the whole thing recoverable: flush the queue entirely and the next sweep rebuilds it from the durable rows.

The mistake is not using cron. It is using cron as the executor, so the record of what happened lives only in a log file that rotates.

What the queue costs

Worth stating plainly, because the upgrade is not free.

You are now running Redis or equivalent, and it is on the critical path for work that used to depend on nothing. You need to watch queue depth, worker health and dead letters, which is a monitoring surface that did not previously exist. Every unit of work must be idempotent, because at least once is the only guarantee available, and retrofitting that is considerably harder than designing it in.

And the failure modes are less obvious. A cron job that stops running is loud. A queue that is draining slower than it fills looks completely healthy right up until it does not.

The verdict

Cron until the work matters enough that somebody will ask about a specific run. A queue from that point on. And cron underneath the queue forever, doing the one thing it is genuinely excellent at.

Questions people actually ask

Can you use both?
You should. A queue still needs something to fire the sweep that promotes due work and catches stragglers, and cron is the right tool for that one job. The mistake is using cron as the executor rather than the trigger.
What is the strongest signal you have outgrown cron?
Somebody asks whether a particular run happened and the honest answer requires reading logs. At that point the work has become important and the tool has no memory of it.

Published March 2026, updated July 2026.

Hiring someone to own work like this?

I am open to senior backend and full stack roles, remote and permanent.

Get in touch / Read the CV