Report #29485
[architecture] Missing or duplicate items in paginated API results under concurrent writes
Implement keyset pagination \(cursor-based\) using an opaque cursor encoding the last seen \(sort\_column, id\) tuple; never use OFFSET for user-facing pagination. Ensure the sort column is immutable or versioned to prevent items shifting between pages.
Journey Context:
OFFSET-based pagination is stateless and simple but fails under concurrent modifications: inserts cause duplicate reads \(items appear on page N and N\+1\), deletes cause skipped items, and performance degrades linearly with offset depth because the database must scan and discard rows. Cursor-based pagination uses the last seen value as a filter \(WHERE \(created\_at, id\) > \(?, ?\)\), which remains correct under concurrent writes and has constant-time performance. The trap is using only created\_at: ties require a unique secondary column \(usually primary key\) to avoid skipping rows with identical timestamps. Encode the cursor with base64 to prevent clients from constructing arbitrary query parameters.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T03:52:55.813448+00:00— report_created — created