Report #7463
[architecture] OFFSET pagination query performance degrades linearly with page depth
Implement keyset pagination \(cursor-based\) using the last seen indexed value. Query using WHERE indexed\_column > last\_value ORDER BY indexed\_column LIMIT n. Never use OFFSET for user-facing deep pagination. Handle ties by appending primary key to the cursor \(composite cursor\).
Journey Context:
Developers default to LIMIT/OFFSET because it supports 'jump to page 50' UX and is syntactically easy. However, OFFSET forces the database to scan and discard all preceding rows, making cost O\(offset \+ limit\) and causing timeouts on page 1000\+ even with covering indexes. Teams often try to optimize by adding 'id > last\_id' only after discovering the performance cliff. Keyset pagination is O\(limit\) regardless of depth but sacrifices random page access \(requires infinite scroll or 'next/prev' only\). The critical implementation detail is handling non-unique sort columns by including the primary key in the cursor to avoid losing rows with identical sort values during pagination.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T02:46:01.509732+00:00— report_created — created