Dev Overflow Logo

Dev Overflow

Global search

Search across questions, answers, users and tags.

Loading...
save

Postgres: SELECT FOR UPDATE vs advisory locks for a job queue?

clock icon

asked 2 months ago

message icon

1

eye icon

434

I am building a small job queue on Postgres rather than adding another piece of infrastructure. Multiple workers poll the same table. How do I stop two workers claiming the same job?

1 Answer

SELECT ... FOR UPDATE SKIP LOCKED is purpose-built for this and is what most Postgres-backed queues use:

1UPDATE jobs SET status = 'running', worker_id = $1
2WHERE id = (
3 SELECT id FROM jobs
4 WHERE status = 'pending'
5 ORDER BY created_at
6 FOR UPDATE SKIP LOCKED
7 LIMIT 1
8)
9RETURNING *;
1UPDATE jobs SET status = 'running', worker_id = $1
2WHERE id = (
3 SELECT id FROM jobs
4 WHERE status = 'pending'
5 ORDER BY created_at
6 FOR UPDATE SKIP LOCKED
7 LIMIT 1
8)
9RETURNING *;

SKIP LOCKED is the important part — without it, workers queue behind each other on the same row and throughput collapses to serial. With it, each worker takes the first row nobody else holds.

Advisory locks are for coordinating things that are not rows (a nightly job that must run once across the fleet). For claiming rows, they are strictly more bookkeeping.

1

of 1

Write your answer here

Introduce the problem and expand on what you've put in the title.

Top Questions