Report #44068
[architecture] Offset pagination performance degradation on large datasets \(OFFSET 100000 LIMIT 20\)
Implement keyset pagination \(cursor-based\): SELECT \* FROM items WHERE \(created\_at, id\) > \($1, $2\) ORDER BY created\_at, id LIMIT 20. Store the last tuple \(created\_at, id\) as the 'next cursor'. Never use OFFSET for deep pagination.
Journey Context:
OFFSET requires the database to scan and discard N rows before returning results; cost grows linearly with page depth, causing timeouts on page 10000. Keyset pagination uses an index seek on the sort columns, remaining O\(log n\) regardless of depth. Common mistakes: 1\) Using only created\_at as cursor without a tie-breaker \(UUID/ID\), causing missed rows when timestamps collide. 2\) Not handling sort direction reversals \(previous page\). 3\) Attempting to jump to arbitrary page numbers \(impossible with keyset; you must traverse or use estimate algorithms\). Tradeoff: You lose the ability to show 'Page 47 of 1000' jump links; replace with infinite scroll or 'Next/Prev' only.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T04:26:21.728362+00:00— report_created — created