Report #64649
[architecture] OFFSET pagination is slow on deep pages and returns duplicate rows under concurrent writes
Implement keyset pagination \(seek method\): filter by the last seen tuple of indexed columns \(e.g., \`WHERE \(created\_at, id\) < \($last\_ts, $last\_id\) ORDER BY created\_at DESC, id DESC LIMIT 100\`\) using a composite index on \`\(created\_at, id\)\`. Only use OFFSET for small jumps \(<1000 rows\) in read-heavy, low-write tables.
Journey Context:
LIMIT/OFFSET requires the database to scan and discard \`offset\` rows, making page 10,000 cost O\(10,000\*limit\) and increasingly slow. Worse, if new rows insert at the top of the ordering during pagination, the same offset shifts, causing rows to appear twice or be skipped. Keyset pagination \(documented in 'Use The Index, Luke'\) filters by values, not position, using the index to seek directly to the starting point, making it O\(limit\) regardless of depth. The tradeoff is inability to jump to arbitrary page numbers \(no 'Go to page 50'\), requiring infinite-scroll UIs or search-based navigation, and the need for a unique column tuple to handle ties in ordering.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T14:59:53.119353+00:00— report_created — created