Report #53797
[architecture] Offset pagination performance degradation on large datasets
Implement keyset pagination \(cursor-based\) using the last seen value of an indexed column: 'WHERE id > last\_id ORDER BY id LIMIT n' instead of 'OFFSET x LIMIT n'. This allows the database to use an index seek \(range scan\) rather than scanning and discarding rows, maintaining O\(log n\) performance regardless of page depth. For non-unique sorts \(created\_at\), use composite cursors \(created\_at, id\).
Journey Context:
OFFSET requires the database to scan, sort, and discard all rows up to the offset before returning data. On page 10,000 with page size 20, the database processes 200,000 rows to return 20, resulting in linear degradation \(O\(n\) per page\) and eventual timeouts. Cursor pagination passes the last seen value from the previous page, allowing the query planner to jump directly to the start position via the index \(B-tree range scan\), yielding logarithmic cost regardless of depth. Tradeoffs: 1\) Cannot jump to arbitrary page numbers \(no 'go to page 50'\), only next/previous. 2\) Requires a stable, indexed sort column \(preferably unique PK\). 3\) Handling updates during pagination \(tuples moving between pages\) requires careful cursor design or accepting minor inconsistencies. 4\) Complex when sorting by multiple columns or nullable columns \(requires composite encoding\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T20:47:39.615275+00:00— report_created — created