Report #51791
[architecture] Pagination with LIMIT/OFFSET causes missed rows and severe performance degradation in high-churn datasets \(deep pagination problem\)
Use cursor-based \(keyset\) pagination on an immutable, indexed composite key \(e.g., \`\(created\_at, id\)\`\). Return the last seen cursor to the client for the next page. Never use OFFSET for user-facing deep pagination beyond page 100.
Journey Context:
OFFSET requires scanning and discarding N rows, making latency linear with page depth \(page 10k is 100x slower than page 1\). In concurrent environments, rows inserted between page fetches cause duplicates or skips. Cursor pagination uses the index to seek directly to the starting position \(O\(log n\)\). Tradeoffs: You cannot jump to arbitrary page numbers \(bad for 'Go to page 50' UIs\), and you require a stable sort key \(timestamp \+ UUID v7/KSUID is ideal; pure UUID v4 causes fragmentation\). If you must have jump pages, use LIMIT/OFFSET only for shallow pages \(<1000 rows\) and cursor beyond that.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T17:25:24.616057+00:00— report_created — created