This document explains the approach to implement pagination in GraphQL queries, specifically for listing resources such as funnels. The pagination is based on cursor-based pagination principles.

Pagination Query Structure

A GraphQL query for pagination includes parameters for controlling the number of items (first), and the point to start fetching items (after). Below is a template for a pagination query:

  "query": "query funnelsQuery(
    $first: Int
    $after: String
    $query: String!
  ) {

  fragment funnelsPagination on Query {
    pagination: funnels(first: $first, after: $after, query: $query) {
      edges {
        node {
          destinationTemplate {
            uid: id
      pageInfo {
  "variables": {
    "query": "order_by:id order_dir:desc",
    "first": 25

Query Parameters

  • first: The number of records to fetch.
  • after: A cursor, indicating the starting point for fetching records.
  • query: A query string to filter or sort the data.

Response Structure

  • edges: An array of edge objects, each representing an item.
    • node: The actual item with its fields.
    • cursor: A unique identifier for the item, used for pagination.
  • pageInfo: Contains pagination information.
    • endCursor: The cursor of the last item in the response.
    • hasNextPage: A boolean indicating if there are more items to fetch.

Implementing Pagination

Fetching Initial Data

  • Set the first parameter to define how many items you want to load initially.
  • Leave the after parameter empty to start from the beginning.

Fetching More Data

  • Use the endCursor from the pageInfo as the after value in the next query.
  • Check hasNextPage before making the next query to ensure there are more items to fetch.

Example Usage

Query for First Page

  "query": "...",
  "variables": {
    "query": "order_by:id order_dir:desc",
    "first": 25

Query for Subsequent Pages

To fetch subsequent pages, you will need to use the endCursor from the previous query's response. Here's how the query should be structured:

  "query": "...",
  "variables": {
    "query": "order_by:id order_dir:desc",
    "first": 25,
    "after": "[endCursor from previous response]"

In this query:

  • The first parameter remains the same, indicating the number of items you want to fetch.
  • The after parameter is set to the endCursor from the previous page's pageInfo. This tells the server to start fetching results from the next item after the given cursor.

Continuation Logic

When implementing pagination:

  1. Check hasNextPage: Before performing a subsequent query, always check the hasNextPage boolean from the pageInfo of the current response. If hasNextPage is false, there are no more items to fetch.
  2. Update after Parameter: If hasNextPage is true, use the endCursor as the after parameter in your next query.
  3. Repeat Process: Continue this process to navigate through the pages of data.

Best Practices

  • Caching: Consider caching the endCursor of each page for a smoother backward navigation experience.
  • Error Handling: Implement error handling for scenarios where the endCursor might be invalid or expired.
  • Performance Considerations: Monitor the performance impact of large first values, as fetching too many items at once can impact server performance.


Cursor-based pagination in GraphQL is an effective way to handle large datasets. By following the outlined approach and best practices, developers can implement a robust and efficient pagination system in their GraphQL APIs.