Report #4136
[architecture] Duplicate or missed records during pagination when using OFFSET/LIMIT on high-churn datasets
Implement keyset pagination \(cursor-based\) using a composite tuple comparison on indexed columns \(e.g., WHERE \(created\_at, id\) > \(last\_created\_at, last\_id\) ORDER BY created\_at, id\). Ensure the columns used in the cursor are immutable \(or append-only\) and indexed as a composite index in the same order. Never use OFFSET for user-facing deep pagination; reserve it only for small admin datasets.
Journey Context:
OFFSET-based pagination suffers from 'drift' where newly inserted rows shift the window, causing items to appear on multiple pages or be skipped entirely when concurrent writes occur during pagination. Using a simple cursor on created\_at alone fails when multiple rows share the same timestamp \(common with batch inserts\), requiring a unique tie-breaker \(usually the primary key\). The composite tuple comparison syntax varies by database \(PostgreSQL supports row constructors, MySQL requires explicit AND/OR logic\), but the pattern is universal. The performance gain comes from the database using the index to seek directly to the starting position \(O\(log n\)\) versus scanning and discarding OFFSET rows \(O\(n\)\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:52:27.674214+00:00— report_created — created