timestamp-order-requires-tiebreaker
Bounded store SQL whose final result-order key looks like a *_at timestamp should include a deterministic secondary key.
Why
Timestamp columns are not necessarily unique, so bounded reads can choose different rows at a page or top-N boundary. Keyset pagination also needs the same secondary key in its cursor predicate.
Fix
Add a deterministic unique key after the timestamp. For keyset pagination, include the key in both the ORDER BY tuple and cursor predicate, such as (created_at, id) < (%s, %s).
Examples
QUERY = ( "SELECT id, created_at FROM task " "WHERE created_at < %s " "ORDER BY created_at DESC LIMIT 50")QUERY = ( "SELECT id, created_at FROM task " "WHERE (created_at, id) < (%s, %s) " "ORDER BY created_at DESC, id DESC LIMIT 50")Formerly: created-at-order-requires-tiebreaker