Report #65548
[architecture] OFFSET pagination returns duplicate or missing rows under concurrent writes
Implement keyset pagination \(cursor-based\) using the last seen value of an indexed, immutable column \(e.g., created\_at, id\). Encode the column value as the 'next\_page' cursor and use WHERE \(created\_at, id\) > \(last\_created\_at, last\_id\) in subsequent queries.
Journey Context:
OFFSET requires the database to scan and discard N rows, which is O\(offset\) complexity and becomes slow beyond page 1000. More critically, if rows are inserted/deleted between page fetches, the window shifts: a row might appear twice \(if inserted before the current offset\) or be skipped \(if deleted before the offset\). Keyset pagination is O\(log n\) using the index but sacrifices the ability to jump to arbitrary page numbers \(e.g., 'go to page 50'\) and requires a strictly sortable, immutable column \(using UUIDv4 with random order fails without a secondary timestamp\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T16:30:16.439906+00:00— report_created — created