Skip to content
Preptima
mediumCodingDesignMidSenior

You need a work queue with priorities and you are told to build it in Postgres, not Kafka. What does the dequeue statement have to do, and what happens when ten workers run it at once?

The dequeue has to pick the highest-priority ready row, lock it, and mark it claimed in one statement, using FOR UPDATE SKIP LOCKED so ten workers each take a different row instead of queueing behind the same one. The lock only lasts as long as the transaction, so the claim must be written or the transaction held.

6 min readUpdated 2026-10-09

Answer

Short answer

A job queue's dequeue has one task: claim exactly one row nobody else holds. In Postgres that is a single UPDATE whose target is chosen by a subquery ending FOR UPDATE SKIP LOCKED, ordered by priority, returning the claimed payload. With ten workers, each one's subquery skips rows the others have locked, so they claim ten different jobs without waiting on each other. Without SKIP LOCKED they all wait on the same head row; without any lock they can claim the same job twice.

Was this answer helpful?

Likely follow-ups

  • A worker claims a job under a five-minute lease and is still running at minute six. What stops two workers from completing it?
  • Low-priority jobs have not run for a day because high-priority work never stops arriving. How do you change the ORDER BY?
  • Workers poll every second and the queue is empty most of the night. How would LISTEN and NOTIFY change that, and what do you still need polling for?
  • Finished rows are never deleted and the table has grown to forty million rows. What does that do to the dequeue, and how do you clean it up?

Related questions

Further reading