Report #76865
[architecture] Slow pagination on large tables with OFFSET/LIMIT
Implement keyset pagination \(cursor-based\) using the last seen values of the ordering columns. Query: SELECT \* FROM items WHERE \(created\_at, id\) < \(last\_created\_at, last\_id\) ORDER BY created\_at DESC, id DESC LIMIT 20;. Ensure composite index on \(created\_at, id\).
Journey Context:
OFFSET scans and discards N rows; at page 10,000 this reads 200,000 rows just to return 20. Keyset pagination is O\(log n\) regardless of page depth. The trap: simple cursor implementations fail when sort values are not unique \(ties cause skipped/duplicate rows\). Solution is adding the primary key as tie-breaker in the ORDER BY and WHERE clause. Another trap: navigating to arbitrary page numbers \(like page 57\) is impossible with cursors - you must choose between deep pagination performance vs random access. For go to page UI, use offset for shallow pages \(< 1000\), cursor for deep. The hard lesson: you cannot efficiently have both bidirectional navigation \(next/prev\) and arbitrary jumps; if you need both, maintain a materialized page index or accept O\(N\) costs.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T11:37:03.870838+00:00— report_created — created