API Pagination Patterns Compared: Offset, Cursor, Keyset, and Token Pagination
api-designpaginationbackendperformancerest-api

API Pagination Patterns Compared: Offset, Cursor, Keyset, and Token Pagination

EEditorial Team
2026-06-14
11 min read

A practical comparison of offset, cursor, keyset, and token pagination for scalable, reliable API design.

Pagination is one of those API design choices that looks minor early on and becomes expensive to change once clients, datasets, and operational expectations grow. This guide compares offset, cursor, keyset, and token pagination in practical terms so engineering teams can choose a pattern that fits current needs without creating unnecessary performance or consistency problems later. If you maintain internal or external APIs for cloud-native web applications, this is the sort of decision framework worth revisiting whenever your traffic, data volume, or client experience changes.

Overview

At a high level, pagination is the contract your API uses to return large collections in smaller, predictable slices. The core job sounds simple: give clients a way to fetch “the next page” of results. In practice, pagination affects database load, query shape, client implementation, UX expectations, cache behavior, and even how reliably users can move through changing datasets.

The four patterns most teams compare are:

  • Offset pagination: requests use a page number or offset value, such as ?limit=50&offset=100.
  • Cursor pagination: requests use a pointer to a position in an ordered result set, such as ?after=cursor123.
  • Keyset pagination: requests use a known sort key, often a timestamp or ID, such as ?created_at_lt=2026-01-10T12:00:00Z.
  • Token pagination: requests use an opaque continuation token generated by the server, such as ?page_token=eyJ....

All four can be valid. The better question is not which pattern is universally best, but which pattern matches your data shape, ordering guarantees, client needs, and expected scale.

For many corporate app workflows, pagination decisions show up alongside broader API choices. If your team is also reviewing transport and schema style, it may help to compare this topic with OpenAPI vs GraphQL vs gRPC: Choosing the Right API Style for Internal and External Platforms. Pagination is not separate from API style; it is part of the usability and operability of the whole interface.

How to compare options

The fastest way to choose badly is to focus only on frontend convenience. A durable pagination choice should be evaluated across six dimensions.

1. Dataset stability

Ask how often records are inserted, updated, or deleted while users are paging through results. In a mostly static dataset, offset pagination may be acceptable for a long time. In fast-changing feeds, queues, audit logs, or event streams, offset pagination often leads to duplicates or skipped items because row positions shift between requests.

2. Ordering requirements

Every pagination scheme depends on a clear sort order. If you cannot define a stable, deterministic ordering, your pagination will become hard to reason about. Good pagination usually needs an explicit sort like created_at DESC, id DESC rather than an implied database default.

When multiple rows can share the same primary sort value, add a tie-breaker. For example, if many records have the same created_at value, include id in the ordering and in the pagination condition. This is especially important for keyset and cursor pagination.

3. Query cost at scale

Think about what the database must do to produce page 1, page 100, and page 10,000. Offset-based queries often become more expensive as the offset grows because the database may still need to scan or step through earlier rows. Keyset and cursor approaches usually avoid this pattern because they seek from a known position instead of counting forward from the beginning.

4. Client ergonomics

Some clients want page numbers because users expect them in admin grids and reports. Other clients only need “load more” or infinite scroll. Offset pagination maps naturally to page-numbered UIs. Cursor, keyset, and token approaches work better for sequential navigation but are less natural when users want to jump directly to page 37.

5. Contract simplicity and safety

If you expose raw sort keys directly, clients may gain flexibility but also become tightly coupled to your query model. Opaque tokens reduce coupling because the server controls the continuation state. This can make future changes easier, but it also makes debugging and manual API use a bit less transparent.

6. Operational change tolerance

Choose a pattern you can evolve. If you expect larger datasets, more concurrent writes, or more external API consumers over time, favor pagination that handles change with fewer surprises. Retrofitting consistency into an offset-based public API can be painful after clients depend on page-number behavior.

A practical rule: start by identifying whether your API is serving human browsing, machine traversal, or time-ordered feeds. That distinction often narrows the right pattern quickly.

Feature-by-feature breakdown

This section compares the four patterns on the attributes teams care about most: simplicity, performance, consistency, flexibility, and implementation risk.

Offset pagination

How it works: The client asks for a fixed number of records starting from a numeric position. Common forms are page=3&page_size=20 or offset=40&limit=20.

Why teams choose it: It is easy to understand, easy to test manually, and easy to map to classic paginated tables. Product managers and frontend teams often like it because it supports page numbers naturally.

Strengths:

  • Simple for clients and documentation.
  • Works well for small to medium, relatively stable datasets.
  • Natural fit for report-style UIs and back-office search screens.
  • Straightforward to implement in SQL-based systems.

Weaknesses:

  • Performance can degrade with large offsets.
  • Results can shift when rows are inserted or deleted between requests.
  • Can produce duplicates or skipped records in changing datasets.
  • Encourages “jump to arbitrary page” expectations that may be expensive to support at scale.

Best use: Internal tools, admin dashboards, and bounded datasets where page-number navigation matters more than perfect consistency across concurrent writes.

Cursor pagination

How it works: The server returns a cursor representing the last seen position in an ordered list. The client sends that cursor back to fetch the next slice.

Why teams choose it: It is a strong general-purpose option for APIs that need better consistency and scalability than offset pagination, especially for user-facing lists and mobile clients.

Strengths:

  • Handles large datasets more efficiently than deep offsets in many cases.
  • Works well with changing datasets when tied to stable ordering.
  • Good fit for infinite scroll, “next/previous,” and feed-like experiences.
  • Lets the server hide internal query details if the cursor is opaque.

Weaknesses:

  • Harder to debug manually than numeric offsets.
  • Random page jumps are usually not supported.
  • Requires careful design around sorting, tie-breakers, and cursor encoding.
  • Can become fragile if the sort order changes after release.

Best use: Public APIs, mobile apps, and high-traffic list endpoints where sequential traversal matters more than direct page access.

Keyset pagination

How it works: The client requests rows after or before a concrete key boundary from the previous page, based on the sort columns. Example: fetch the next 50 rows where (created_at, id) is less than the last item returned.

Why teams choose it: It is often the most efficient and reliable pagination style for large ordered datasets in relational databases, especially where the ordering aligns well with an index.

Strengths:

  • Very efficient for large datasets when supported by proper indexes.
  • More stable than offset pagination under inserts and deletes.
  • Clear mental model for time-ordered or ID-ordered data.
  • Excellent for logs, timelines, event lists, and append-heavy tables.

Weaknesses:

  • Requires a strong, deterministic sort key strategy.
  • Less flexible for arbitrary sorting and filtering combinations.
  • Client-visible key parameters can expose implementation details if not wrapped.
  • Backward navigation may require extra care.

Best use: Large SQL-backed APIs where performance and consistency matter, and the list is naturally ordered by indexed columns.

Token pagination

How it works: The server issues an opaque token that contains or references enough state to continue the query later. That token may encode sort position, filters, snapshot details, or internal continuation metadata.

Why teams choose it: It offers the most contract control. The server can change internal logic while preserving a stable external interface.

Strengths:

  • Decouples client contract from storage and query internals.
  • Can support complex backends, aggregated data, or federated sources.
  • Allows the server to carry continuation state without exposing raw keys.
  • Useful when the next page depends on more than one visible field.

Weaknesses:

  • Opaque by design, which can complicate troubleshooting.
  • Requires careful token lifecycle management and validation.
  • May need signing or encryption if tokens contain sensitive state.
  • Can become hard to maintain if token format evolves without discipline.

Best use: Complex APIs, multi-source queries, cloud service APIs, and cases where you want flexibility to evolve backend execution without breaking clients.

Comparison summary

PatternClient simplicityLarge-scale performanceConsistency under writesSupports page jumpsImplementation flexibility
OffsetHighLow to mediumLowYesMedium
CursorMediumHighMedium to highUsually noHigh
KeysetMediumHighHighNoMedium
TokenMediumHighMedium to highUsually noVery high

One useful distinction is that cursor describes the client-facing idea of a position marker, while keyset describes a query technique based on ordered keys. In many APIs, a cursor is implemented internally using keyset logic, then wrapped in an opaque string.

That layering is often a good design compromise: keep the backend efficient with keyset semantics, but expose a cleaner continuation contract to clients through cursors or tokens.

Best fit by scenario

There is rarely a single best pagination style for every endpoint. Many mature APIs use more than one.

Scenario: Internal admin grid with filters and page numbers

Likely fit: Offset pagination.

If users expect numbered pages, export workflows, and quick movement across a finite result set, offset is still reasonable. Bound the maximum page size, cap deep page access if needed, and make the sort order explicit. For very large internal datasets, consider hybrid behavior: offset for shallow browsing and a separate export or async job for full traversal.

Scenario: Activity feed or event stream

Likely fit: Keyset or cursor pagination.

Feeds change constantly. Users mostly need the next set of records in a stable order, not page 12. Use a deterministic descending sort such as created_at DESC, id DESC and design for duplicates only if your business logic tolerates them. If clients are external, an opaque cursor is often cleaner than exposing raw key boundaries.

Scenario: Public REST API with many clients

Likely fit: Cursor or token pagination.

Public APIs benefit from stable, evolvable contracts. Opaque continuation markers reduce coupling and give maintainers room to optimize storage later. Document token expiry behavior, sorting guarantees, and whether new writes may appear between requests.

Scenario: Large relational table with strict performance requirements

Likely fit: Keyset pagination.

If the endpoint is backed by a well-indexed SQL table and traversed heavily, keyset queries are often the most direct path to predictable performance. This becomes even more important when paired with zero-downtime schema evolution. If your team is preparing for index or schema changes, see Database Migration Checklist for Zero-Downtime Deployments.

Scenario: Aggregated data from multiple services or storage systems

Likely fit: Token pagination.

When results come from more than one backend, raw offset or keyset parameters may not represent enough state. A server-generated token can capture the continuation context without leaking internal orchestration details.

Scenario: Search results with unstable ranking

Likely fit: It depends, but be careful.

Search ranking can shift between requests due to indexing, relevance scoring, or document updates. Pagination here is often less about the classic pattern name and more about snapshot semantics. If consistency matters, you may need a token tied to a search session or snapshot rather than a simple offset. If consistency is less important, offset may be acceptable for human browsing.

Scenario: Bulk API consumers and ETL-style traversal

Likely fit: Keyset or token pagination.

Machine consumers care more about completeness, repeatability, and throughput than about page numbers. Design around stable traversal, clear ordering, and resumability after failure. If continuation state must survive long-running jobs, define token expiration and replay behavior explicitly.

Common implementation guidance regardless of pattern

  • Always define a deterministic sort order. Never rely on implicit database ordering.
  • Use bounded page sizes. Set defaults and enforce maximums.
  • Return pagination metadata carefully. Include what clients need, but avoid expensive total counts unless truly required.
  • Document consistency semantics. State whether users may see inserts, duplicates, or missing items between page fetches.
  • Validate pagination inputs. Treat cursors and tokens as untrusted input.
  • Test under concurrent writes. Many pagination bugs only appear in changing datasets.
  • Watch indexes. Pagination quality is tightly linked to query plans and index support.

Operationally, pagination behavior should be verified in delivery workflows just like any other API contract. Teams that invest in release discipline often catch edge cases earlier; related practices are covered in CI/CD Pipeline Stages Explained and Feature Flags Best Practices.

When to revisit

A pagination decision is worth revisiting when the underlying constraints change. That usually happens gradually, which is why teams leave a once-reasonable design in place longer than they should.

Review your pagination approach when any of the following becomes true:

  • Your dataset size has grown enough that deep pages are slow or expensive.
  • Your endpoint now experiences frequent inserts or deletes during active browsing.
  • Your clients need better consistency guarantees than the current pattern provides.
  • You are exposing the API to more third parties and need a more stable public contract.
  • You are changing storage engines, indexes, query layers, or aggregation strategy.
  • You need to support mobile, infinite scroll, or machine-driven traversal rather than page-number UIs.
  • Your current implementation depends on total counts that are becoming costly to compute.

The most practical next step is to create a short pagination review checklist for every collection endpoint:

  1. What is the explicit sort order?
  2. Is the ordering stable under concurrent writes?
  3. What is the worst-case query cost for deep traversal?
  4. Do clients need direct page jumps or only sequential navigation?
  5. What duplicates or gaps can occur, and are they documented?
  6. Can the contract evolve without breaking clients?
  7. Are indexes aligned with the pagination query?

If you are designing a new API, start conservative: prefer deterministic ordering, bounded limits, and a continuation model that will not box you in. If you already have offset pagination in production, do not assume you must replace it immediately. Instead, identify the endpoints where it is actively causing performance or correctness problems, then migrate selectively. In many systems, offset remains perfectly adequate for internal, bounded, low-churn views.

The durable lesson is simple: pagination is not just a response-shaping detail. It is a data access strategy with user experience consequences. Choose the pattern that fits how your data changes, how your clients navigate, and how much future flexibility your API will need.

Related Topics

#api-design#pagination#backend#performance#rest-api
E

Editorial Team

Senior SEO Editor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

2026-06-14T15:53:05.970Z