Report #6630
[architecture] Slow pagination on large tables using LIMIT/OFFSET
Use cursor-based \(keyset\) pagination instead of offset-based pagination for large datasets. Implement by ordering on a unique indexed column \(or composite of columns\) and using a WHERE clause to fetch the next page, e.g., SELECT \* FROM posts WHERE \(created\_at, id\) < \(?, ?\) ORDER BY created\_at DESC, id DESC LIMIT 20; store the last seen values as the 'cursor' for the next page.
Journey Context:
OFFSET becomes O\(n\) as the offset value grows because the database must scan and discard all preceding rows. At millions of rows, page 1000\+ becomes impossibly slow and memory-intensive. Cursor pagination is O\(log n\) using index seeks. The tradeoff: cursor pagination cannot jump to arbitrary page numbers \(no 'go to page 50'\), and implementation is complex with multi-column sorts or non-unique sort keys \(requires tie breaker like primary key\). It's unsuitable for use cases requiring random access pagination. For small tables \(<10k rows\), offset is simpler and acceptable.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T00:37:42.015803+00:00— report_created — created