Impact
PostgreSQL claim polling can permanently starve claimable concurrency keys whose names sort after the first 512 registered keys.
Root cause
distinctEnqueuedKeys always starts its recursive loose index scan at the lexicographically smallest key and applies LIMIT 512. There is no cursor or rotation. If those 512 keys are blocked by long-running work, every poll inspects the same blocked page and never reaches key 513 until an earlier key clears.
Regression shape
- Insert/hold 512 lexicographically early concurrency keys in a blocked state.
- Insert one independently claimable job under a later key.
- Repeated
claimReady calls must claim the later key without waiting for an early key to finish.
Acceptance criteria
- Key gathering rotates or keyset-pages beyond the first page.
- No candidate/admission query scales with pending rows.
- Existing overload query-plan/index regressions remain green.
- Add a real PostgreSQL regression with more than 512 blocked keys.
Impact
PostgreSQL claim polling can permanently starve claimable concurrency keys whose names sort after the first 512 registered keys.
Root cause
distinctEnqueuedKeysalways starts its recursive loose index scan at the lexicographically smallest key and appliesLIMIT 512. There is no cursor or rotation. If those 512 keys are blocked by long-running work, every poll inspects the same blocked page and never reaches key 513 until an earlier key clears.Regression shape
claimReadycalls must claim the later key without waiting for an early key to finish.Acceptance criteria