Thuta Learning
GraphQL
IntermediateWeb Developmentbeginner

Pagination — Offset vs Cursor-Based Connections

What you'll walk away with

  • Explain the core ideas behind Pagination — Offset vs Cursor-Based Connections
  • Run the sample GraphQL query or code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

Offset pagination (`skip`, `limit`) is simple but can skip or repeat items when the underlying data changes between page loads. Cursor-based pagination uses an opaque cursor — a string encoding a stable sort key — as a "continue from here" pointer, making it more stable. The Relay-style connection pattern standardizes this shape as `edges` (each with a `cursor` and `node`) plus `pageInfo` (`hasNextPage`, `endCursor`).

Connect it to a real scenario

Expose the Tutorial Platform's catalog list as `tutorials(first: 20, after: $cursor): TutorialConnection!`. When the frontend's "Load more" button is clicked, it passes `pageInfo.endCursor` as the next request's `after` argument, continuing until `pageInfo.hasNextPage` is `false`.

Try the working example

graphql
type TutorialEdge {
  cursor: String!
  node: Tutorial!
}

type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}

type TutorialConnection {
  edges: [TutorialEdge!]!
  pageInfo: PageInfo!
}

type Query {
  tutorials(first: Int!, after: String): TutorialConnection!
}
You should see
You can write a Relay-style connection schema and explain a cursor-based "load more" flow.

5-minute try-it

Write a `commentsConnection(first: Int!, after: String): CommentConnection!` schema and describe how a frontend loop would use `pageInfo.hasNextPage`.

One important caution

Exposing the cursor as a plain, readable row ID invites clients to do cursor arithmetic (id+1); keep cursors as opaque, encoded strings.

GraphQL — PaginationGraphQL

Easy traps

  • Exposing the cursor as a plain, readable row ID invites clients to do cursor arithmetic (id+1); keep cursors as opaque, encoded strings.
  • Validate sample queries and mutations on a local or test server with recoverable data before applying them to production.

Exercise

Write a `commentsConnection(first: Int!, after: String): CommentConnection!` schema and describe how a frontend loop would use `pageInfo.hasNextPage`.

You'll know it worked when: You can write a Relay-style connection schema and explain a cursor-based "load more" flow.

Pagination — Offset vs Cursor-Based Connections | Thuta Learning