{
  "about": "An entry of UpFork's ledger. Check it by hand as https://upfork.dev/docs/ledger says, or at https://upfork.dev/verify/E-59",
  "entry": {
    "seq": 59,
    "kind": "lesson-version",
    "record": "{\"ai\":{\"apps\":[\"Claude\"],\"models\":[\"Claude Opus 5.5\"]},\"article\":\"telegram-bots-on-postgresql-alone-sponsor-bot-s-queues-forced-join-gate-and\",\"articleRevision\":1,\"assumed\":\"a claim query that picks candidates in one CTE and then locks them with `FOR UPDATE SKIP LOCKED` in the next could never hand the same row to two workers.\",\"author\":{\"account\":\"a_9d470b566acab5f65bdc\",\"handle\":\"ramin-valadan\"},\"evidence\":\"commit 7eecc9f (phase 12, \\\"a race that let two workers handle the same update\\\").\",\"fix\":\"the locking step repeats the status conditions (`status = 'Pending' AND next_attempt_at <= @now`, or an expired Processing lock). Exactly one answer per update since.\",\"happened\":\"under load, a worker's claim that finished between another worker's two steps had already set the row to Processing; the second worker's lock step, which only said `WHERE id IN (candidates)`, took it anyway. 24% more messages went out than people came in.\",\"kind\":\"my-mistake\",\"learnedBy\":\"ai\",\"lesson\":\"L-9DDS\",\"packages\":\"\",\"product\":\"telegram-uploader-bot-forced-join\",\"productRevision\":null,\"publishedAt\":\"2026-10-26T08:26:45.701Z\",\"site\":\"https://upfork.dev\",\"title\":\"FOR UPDATE SKIP LOCKED rechecks only the conditions written in its own step: two workers can claim the same row\",\"type\":\"lesson-version\",\"url\":\"https://upfork.dev/lessons/L-9DDS\",\"version\":1,\"why\":\"after waiting for or skipping a lock, PostgreSQL rechecks only the conditions written in that same step, not the ones in an earlier CTE.\"}",
    "recordHash": "ea1b42cf8faad8eebbd82741d99c2a1d87cd12de8d80cbbddadfebd3640adbd4",
    "prevHash": "356d62f1a990fa0704831c0db515a1a8c73016694319c6cfc1308bc0e72f546a",
    "entryHash": "990183cb0316e5a078720983468a78f60a89416399ce85aac15d732fb59e672f",
    "keyId": "k1",
    "signature": "SqvRFmikohIi5B2HcpF243RQmzAFaqxH+hjh2f3oniC6ASHQezECUWo38Xa5eELR5zCYqpd7JbOJTKfJml/dAQ==",
    "recordedAt": "2026-10-26T08:27:08.802433+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "path": [],
  "checkpoint": null,
  "keys": "https://upfork.dev/ledger/keys.json"
}