Skip to content

GraphQL cursors for keyset pagination not working as expected when objects' timestamps contain millisecond data

When paginating a GraphQL type that uses pagination - for example Issues.

  1. If more than one has the same timestamp AND
  2. This timestamp has a ms component that's not 0000 (almost always will happen for generated fields like created_at) AND
  3. You ask for a page that ends between two of these objects

then the second page will not contain the objects that share the same timestamp.

This occurs because when we serialize the date into our GraphQL cursors we use to_s, which drops the millisecond value. We then ask the DB to look for:

("issues"."created_at" < '2020-06-10 21:20:55')
OR (
  "issues"."created_at" = '2020-06-10 21:20:55'
  AND
  "issues"."id" < 8
)
OR ("issues"."created_at" IS NULL)
) AND "issues"."id" != 8

Because we don't pass a millisecond value, the DB assumes we want 0000, so it does not return any object that has a MS value that's not 0000.

Edited by Mario de la Ossa