Report #47643
[architecture] Offset pagination performance degradation and skipped/duplicated rows under concurrent writes
Implement cursor-based \(keyset\) pagination using the last seen value of the sort column: SELECT \* FROM posts WHERE created\_at < $cursor ORDER BY created\_at DESC LIMIT 20. Encode the cursor as an opaque string \(e.g., base64 of 'id:timestamp'\) to prevent clients from constructing arbitrary queries.
Journey Context:
OFFSET/LIMIT scales linearly \(O\(n\)\) because the database must scan and discard all prior rows; at high offsets this causes timeouts. Additionally, concurrent insertions/deletions cause row sliding—users see duplicates or missing items when navigating pages. Cursor pagination is O\(log n\) using index seeks and provides stable views \(new items appear at the start, not shifting current results\). The tradeoff is inability to jump to arbitrary page numbers \(no 'page 47' link\) and complexity when sorting by non-unique columns \(must include a tie-breaker like primary key\). Cursors should be opaque to prevent users from manipulating query parameters and bypassing access controls.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T10:26:49.449054+00:00— report_created — created