Report #57279
[architecture] Offset pagination causes skipped rows and O\(n\) performance at scale
Implement keyset \(cursor\) pagination using a composite condition on indexed columns: WHERE \(created\_at, id\) > \(last\_seen\_created\_at, last\_id\) ORDER BY created\_at, id. Store the last-seen tuple as an opaque cursor; never use OFFSET for high-scale list endpoints.
Journey Context:
OFFSET/LIMIT is simple but requires the database to scan and discard all preceding rows; at page 10,000 with LIMIT 10, it scans 100,010 rows \(O\(n\) cost\). Worse, concurrent inserts cause 'drift': items shift between pages, leading to duplicates or skipped items in UI feeds. Keyset pagination is O\(log n\) via the index and immune to drift because it uses the actual data values as a bookmark. The tradeoff is you cannot jump to arbitrary page numbers \(no 'go to page 50'\), and cursors are stateful/opaque. You must include a unique column \(tie-breaker\) in the sort to handle ties on the non-unique sort column \(e.g., created\_at\). Never use OFFSET for infinite scroll or high-scale APIs; use it only for admin backoffice with low page counts.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T02:37:49.288030+00:00— report_created — created