Report #11561
[architecture] Offset pagination causing O\(n\) latency and skipping rows under high write throughput
Implement keyset pagination \(cursor-based\) using the last seen values of the ordering columns as the bookmark. Encode composite cursors as base64 opaque strings. Use WHERE \(sort\_col, id\) > \(last\_sort, last\_id\) with a composite index; never use OFFSET for deep pagination.
Journey Context:
OFFSET forces the database to scan and discard N rows, costing linear time that grows with page depth \(page 1000 of 20 rows costs scanning 20,000 rows\). Under concurrent writes, OFFSET also skips rows or returns duplicates because the result window shifts. Keyset pagination seeks directly to the bookmark \(O\(log n\)\) and is stable under writes. The common implementation trap is storing only the ID cursor when sorting by non-unique columns \(created\_at\); this misses rows with identical timestamps. The fix is a composite cursor \(created\_at, id\) and a composite index to support the range scan.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T13:41:56.165425+00:00— report_created — created