Report #16308
[architecture] Offset pagination \(LIMIT/OFFSET\) performs O\(n\) then discards rows, causing timeouts and inconsistent results on large tables with high churn
Implement keyset pagination using the last seen value of an indexed column \(usually created\_at \+ id\) as a cursor in the WHERE clause; encode the cursor as an opaque string to prevent API consumers from constructing arbitrary queries
Journey Context:
OFFSET works by scanning and counting rows, then throwing away the offset—this gets exponentially slower as users paginate deeper \(page 10,000 requires scanning 10,000 \* page\_size rows\). It also suffers from 'drift': if a new row is inserted at the top while the user is paginating, the entire result set shifts, causing skipped or duplicate items. Keyset pagination \(also called seek method\) uses the last seen value to fetch the next page: WHERE \(created\_at, id\) > \(last\_created\_at, last\_id\) ORDER BY created\_at, id LIMIT 100. This uses the index efficiently \(O\(log n\) seek\) and is stable against insertions. The tradeoff is you cannot jump to an arbitrary page number \(no 'go to page 50'\), and sorting by non-unique columns requires a tie-breaker \(usually primary key\). Cursors should be base64-encoded tuples to prevent users from tampering with the internal values.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T02:21:22.176119+00:00— report_created — created