Bird
Raised Fist0
GraphQLquery~10 mins

Cursor-based pagination in GraphQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Cursor-based pagination
Start Query with cursor=null
↓
Fetch first N items after cursor
↓
Return items + new cursor
↓
User requests next page with new cursor
↓
Repeat fetch with updated cursor
↓
Stop when no more items
Cursor-based pagination fetches a set number of items after a given cursor, returning a new cursor for the next page until no more items remain.
Execution Sample
GraphQL
query {
  posts(first: 3, after: "cursor123") {
    edges {
      node { id title }
      cursor
    }
    pageInfo { hasNextPage endCursor }
  }
}
Fetch 3 posts after the cursor 'cursor123', returning posts and info for next page.
Execution Table
StepInput CursorActionItems FetchedNew CursorHas Next Page
1nullFetch first 3 posts from start[Post1, Post2, Post3]cursor3true
2cursor3Fetch next 3 posts after cursor3[Post4, Post5, Post6]cursor6true
3cursor6Fetch next 3 posts after cursor6[Post7]cursor7false
4cursor7No more posts after cursor7[]nullfalse
💡 No more items after cursor7, pagination ends.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4
input_cursornullcursor3cursor6cursor7null
items_fetched[][Post1, Post2, Post3][Post4, Post5, Post6][Post7][]
has_next_pagefalsetruetruefalsefalse
Key Moments - 3 Insights
Why do we use a cursor instead of page numbers?
Cursor points to a specific item, so pagination is stable even if data changes. See execution_table steps 1-3 where cursor moves forward instead of page numbers.
What happens if the cursor is null at the start?
It means fetch from the beginning. Execution_table step 1 shows input_cursor null fetches first items.
Why does the last fetch return fewer items?
Because fewer items remain than requested. Step 3 fetches only one post, showing end of data.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the input_cursor at Step 2?
Acursor6
Bnull
Ccursor3
Dcursor7
💡 Hint
Check the 'Input Cursor' column at Step 2 in execution_table.
At which step does hasNextPage become false?
AStep 1
BStep 3
CStep 2
DStep 4
💡 Hint
Look at the 'Has Next Page' column in execution_table to find when it changes to false.
If we change the first fetch to 5 items, how would items_fetched at Step 1 change?
AIt would fetch 5 posts instead of 3
BIt would fetch 3 posts as before
CIt would fetch no posts
DIt would fetch all posts
💡 Hint
Refer to the code sample where 'first: 3' controls number of items fetched.
Concept Snapshot
Cursor-based pagination:
- Uses a cursor to mark position in data
- Query fetches items after cursor
- Returns items + new cursor for next page
- Stable with data changes
- Stops when no more items
Full Transcript
Cursor-based pagination is a way to get data in chunks using a cursor that points to a specific item. We start with no cursor to get the first items. Each response gives a new cursor to fetch the next chunk. This continues until no more items are left. This method is better than page numbers because it handles data changes smoothly. The example query fetches posts after a cursor, returning edges with nodes and cursors, plus page info. The execution table shows how the cursor moves forward and when pagination ends.

Practice

(1/5)
1. What is the main purpose of cursor-based pagination in GraphQL?
easy
A. To fetch all data at once without limits
B. To sort data alphabetically
C. To fetch data in small parts using a cursor to mark position
D. To delete data from the database

Solution

  1. Step 1: Understand pagination purpose

    Pagination is used to split large data into smaller parts for easier handling.
  2. Step 2: Identify cursor role

    Cursor marks the position in the data to fetch the next part without overlap or missing items.
  3. Final Answer:

    To fetch data in small parts using a cursor to mark position -> Option C
  4. Quick Check:

    Cursor-based pagination = fetch data in parts [OK]
Hint: Cursor marks position to fetch next data chunk [OK]
Common Mistakes:
  • Thinking pagination fetches all data at once
  • Confusing cursor with sorting
  • Assuming pagination deletes data
2. Which of the following is the correct way to request the first 5 items after a cursor in GraphQL?
easy
A. { items(fetch: 5, cursor: "cursor123") { edges { node } } }
B. { items(limit: 5, startAfter: "cursor123") { edges { node } } }
C. { items(take: 5, afterCursor: "cursor123") { edges { node } } }
D. { items(first: 5, after: "cursor123") { edges { node } } }

Solution

  1. Step 1: Recall GraphQL cursor pagination syntax

    The standard uses first to limit items and after to specify the cursor.
  2. Step 2: Match options with correct syntax

    { items(first: 5, after: "cursor123") { edges { node } } } uses first and after correctly; others use incorrect argument names.
  3. Final Answer:

    { items(first: 5, after: "cursor123") { edges { node } } } -> Option D
  4. Quick Check:

    Use first and after arguments [OK]
Hint: Use first and after arguments for cursor pagination [OK]
Common Mistakes:
  • Using limit instead of first
  • Using startAfter or afterCursor which are invalid
  • Confusing argument names
3. Given this GraphQL query:
{ users(first: 3, after: "YXJyYXljb25uZWN0aW9uOjE=") { edges { node { id name } } pageInfo { hasNextPage endCursor } } }
What does the endCursor represent in the result?
medium
A. The cursor of the last item in the current page
B. The total number of items in the database
C. The cursor of the first item in the current page
D. The number of pages available

Solution

  1. Step 1: Understand pageInfo fields

    endCursor marks the cursor of the last item returned in the current page.
  2. Step 2: Differentiate from other fields

    hasNextPage shows if more pages exist; endCursor is not a count or first item cursor.
  3. Final Answer:

    The cursor of the last item in the current page -> Option A
  4. Quick Check:

    endCursor = last item cursor [OK]
Hint: endCursor points to last item fetched [OK]
Common Mistakes:
  • Confusing endCursor with total count
  • Thinking endCursor is first item cursor
  • Assuming endCursor is page count
4. You wrote this GraphQL query for cursor pagination:
{ posts(first: 10, afterCursor: "abc123") { edges { node { title } } } }
Why does this query fail?
medium
A. The argument should be named after, not afterCursor
B. The first argument must be a string, not a number
C. The edges field is invalid in cursor pagination
D. The cursor value cannot be a string

Solution

  1. Step 1: Check argument names for cursor pagination

    The correct argument to specify the cursor is after, not afterCursor.
  2. Step 2: Validate other parts

    first accepts a number; edges is valid; cursor values are strings.
  3. Final Answer:

    The argument should be named after, not afterCursor -> Option A
  4. Quick Check:

    Use 'after' argument name [OK]
Hint: Use 'after' not 'afterCursor' for cursor argument [OK]
Common Mistakes:
  • Using incorrect argument names
  • Thinking first must be string
  • Misunderstanding edges field usage
5. You want to fetch all comments in batches of 4 using cursor-based pagination. The first query is:
{ comments(first: 4) { edges { node { id text } } pageInfo { hasNextPage endCursor } } }
To fetch the next batch, which query should you use?
hard
A. { comments(limit: 4, after: "endCursor_value") { edges { node { id text } } } }
B. { comments(first: 4, after: "endCursor_value") { edges { node { id text } } pageInfo { hasNextPage endCursor } } }
C. { comments(last: 4, after: "endCursor_value") { edges { node { id text } } } }
D. { comments(first: 4, before: "endCursor_value") { edges { node { id text } } } }

Solution

  1. Step 1: Understand how to continue pagination

    Use the after argument with the endCursor value from the previous page to fetch the next batch.
  2. Step 2: Check argument correctness

    first: 4 limits to 4 items; after moves cursor forward; before or last are for backward pagination.
  3. Final Answer:

    { comments(first: 4, after: "endCursor_value") { edges { node { id text } } pageInfo { hasNextPage endCursor } } } -> Option B
  4. Quick Check:

    Use first and after with endCursor for next batch [OK]
Hint: Use first and after with endCursor to paginate forward [OK]
Common Mistakes:
  • Using before instead of after for next page
  • Using last instead of first for forward pagination
  • Using limit instead of first argument
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard