Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk3 min

Why a Postgres Job-Claim Query Can Claim the Same Job Twice

A single statement does not guarantee an exclusive Postgres job claim. Learn why concurrent workers can select the same row and how to lock candidates safely.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A single SQL statement is not automatically an exclusive job claim. Under PostgreSQL’s default READ COMMITTED isolation, a worker can select a pending row and then update it after another worker has changed it, if the query does not lock the candidate row as part of selection. The exact diagnosis depends on the SQL, schema, transaction boundaries and server version; the pattern below shows how to make queue claims contend by locking candidates and skipping rows already locked by another worker.

How two workers can both appear to claim one job

PostgreSQL uses READ COMMITTED by default. A plain SELECT sees a snapshot taken when its command starts. For an UPDATE that encounters a row concurrently changed by another transaction, PostgreSQL may wait for that transaction to finish and then re-evaluate the update’s WHERE condition against the changed row. Those behaviors make the query’s shape important: selecting a candidate in a subquery does not, by itself, mean that the candidate row is exclusively reserved for that worker.

As an Amazon Associate I earn from qualifying purchases.

If two workers can select the same pending job, and the outer update can still match that row after waiting, both statements may report it as claimed. Whether that is what a particular query does depends on its predicates and structure; without the exact SQL, it is a conditional diagnosis, not a conclusion about a specific statement. PostgreSQL describes the relevant behavior in its transaction-isolation documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a row lock when selecting the candidate

For queue consumers, PostgreSQL’s FOR UPDATE SKIP LOCKED lets a worker lock a candidate row while selecting it, and skip rows another worker has already locked. Put the locking clause inside the CTE that selects the candidate:

WITH candidate AS (
  SELECT id
  FROM jobs
  WHERE status = 'pending'
  ORDER BY priority DESC, id
  FOR UPDATE SKIP LOCKED
  LIMIT 1
)
UPDATE jobs AS j
SET status = 'running', claimed_at = now()
FROM candidate AS c
WHERE j.id = c.id
RETURNING j.*;

Adapt the table, columns, eligibility rules and update to the application. This is an illustrative pattern, not a tested query. The CTE locks the selected row; the outer update changes that same row and returns its updated data. A unique ordering, such as priority DESC, id when id is unique, makes the intended choice predictable when the query uses LIMIT. PostgreSQL documents both the row-locking syntax and the need for a unique ordering when a limited result must be predictable in its SELECT documentation.

What changes when workers lock or skip candidates

Approach Concurrent behavior Ordering Abandoned jobs
Candidate selection without a row lock Workers may select the same candidate; the exact outcome depends on the query’s update predicates and structure. A unique ORDER BY with LIMIT makes selection predictable, but does not reserve the row. Recovery behavior is not provided by the selection itself; the application must define it.
Candidate selection with FOR UPDATE SKIP LOCKED A worker skips rows locked by another worker rather than waiting on those rows. A unique ORDER BY with LIMIT makes candidate order predictable. Locking does not define recovery if a worker crashes; the application must decide what happens to work left incomplete.

SKIP LOCKED intentionally produces an inconsistent view of the table, so it is suited to avoiding contention among consumers of a queue-like table, not to general-purpose reads that require a consistent view. It also does not guarantee fairness or exactly-once execution of external side effects. PostgreSQL’s documentation explains the queue-use trade-off; job retries, leases or other crash-recovery policies remain application decisions.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check the actual statement before changing it

To confirm whether this race applies, inspect the complete statement and the context in which it runs:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Does the candidate-selection query lock the row, or does it only read a pending job?
  • Can the outer UPDATE still match a row after another transaction changes it?
  • What are the transaction boundaries and isolation level?
  • Do schema constraints or application rules affect whether more than one claim can be recorded?
  • Which PostgreSQL server version is running? The cited explanations describe behavior documented in PostgreSQL 16 and 17.

Without those details, the query pattern identifies a plausible cause and a queue-oriented fix, but cannot establish that it is the cause of a particular duplicate claim.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.