Skip to content
← Insights

Cursor or Offset Pagination in an API: How to Choose for Your Use Case and Data Growth

Compare offset and cursor pagination by stability, navigation, data volume, and cost. Choose the contract your API needs and plan a migration without breaking clients.

Conceptual diagram of an API navigating results with offset-based pages and cursors.

An API that returns lists needs to limit how many items it sends in each response. Without pagination, a query can consume unnecessary resources, increase latency, and become difficult for integrators to handle. The decision is about more than syntax: the mechanism affects which items consumers see as data changes, how they navigate, and what guarantees they can expect.

The two most common options are offset pagination, which specifies how many records to skip, and cursor pagination, which uses a reference to continue from a position. The right choice depends on usage patterns and required guarantees, not on one strategy being universally better.

What a paginated response should guarantee

What a paginated response should guarantee

Before choosing a mechanism, define the collection’s contract. At a minimum, decide the maximum page size, the order of items, how to request the next page, and what happens when there are no more results. It is also worth specifying how pagination interacts with filters and sorting.

Ordering must be deterministic. Sorting only by a date, for example, can leave multiple records tied. If the order does not define how to resolve ties, separate requests may return items in different positions. Adding a unique criterion, such as the record ID, establishes an unambiguous sequence.

A useful response can include the items and a reference for continuing, along with metadata such as the effective page size. Not every client needs the total result count: calculating it can be costly, and in frequently changing collections it may become outdated quickly. Include only the information the use case requires.

Offset pagination: easy to jump to a position

With offset, the client requests a limit and the number of items to skip. A conceptual request might be “return 20 items starting at record 40.” This model is easy to explain and fits interfaces with numbered pages, jumps to a specific page, or direct access to results farther down the list.

Its main advantage is a simple contract. Clients can build links to pages, and teams can reason about ranges. It can also be sufficient for small or relatively stable collections, especially when direct navigation is a genuine requirement.

The limitation appears when data changes between requests. Suppose the client loads the first page and, before requesting the next, an item is inserted at the beginning of the order. The next offset may include a record the client has already seen. If an item is deleted before the requested position, the client may skip one that has not yet been returned. Offset alone does not guarantee a consistent view of a changing collection.

Requests for very deep positions may also require scanning or discarding many records, depending on the database, query, and indexes. This is not the same for every system, so measure performance with representative queries. If deep pages become slow, limit how far clients can jump or evaluate another mechanism.

Cursor pagination: continue from a position

With cursor pagination, the response provides a reference that the client sends to retrieve the next set of results. The cursor represents a position in an ordering; for example, it might be based on the sort value and an ID that resolves ties. The client does not need to know how the reference is constructed internally.

For predictable behavior, the query must preserve the same order between requests. A cursor based on a date needs an additional criterion if several rows share that date. Concurrent changes can still affect what appears on later pages, but a strategy based on ordered position usually avoids the shifts caused by skipping a number of rows. It is not necessarily an immutable snapshot: that guarantee requires additional behavior to be designed and documented.

The cursor should be treated as opaque to the consumer. It may encode position data, but encoding does not mean encryption or protection. Do not include sensitive information without suitable safeguards, and validate that the cursor is valid for the relevant query, user, and authorization context. Also define whether it expires and what response the client receives when it can no longer be used.

This option suits sequential browsing, feeds, large catalogs, and processes that move through results without jumping to an arbitrary page. In exchange, it makes direct navigation harder and requires care with cursor format, validation, and compatibility.

Practical criteria for choosing

Evaluate the experience consumers need and the properties of the data set. The decision can be summarized as follows:

  • Choose offset when numbered pages or direct jumps matter, the collection is bounded, or changes during navigation have an acceptable impact.
  • Choose cursor when results are browsed sequentially, the collection may grow substantially, or insertions and deletions make page shifts undesirable.
  • Compare actual costs using representative queries and page sizes. The strategy, indexes, filters, and database all affect performance.
  • Consider the integration pattern: a batch export may need to advance reliably, while an administration interface may value jumping to a specific page.

Do not mix the two models without explaining their scope. Offering offset for some queries and cursor for others can make sense, but each collection should document its contract clearly. Nor should a cursor be presented as a guarantee of full consistency if the design only preserves a position while the collection continues to change.

Filters, sorting, and limits: the complete contract

The cursor and next-page request must correspond to the same filters and ordering that produced the initial response. If the client changes those parameters, it should start a new traversal rather than reuse a reference for a different query. The API can reject that combination or issue cursors that include the context needed for validation.

Document a default page size and a per-request maximum. A limit prevents oversized responses, but it should fit expected consumption and should not force clients to make an excessive number of calls. Specify what happens when values are missing, invalid, or above the maximum: enforcing a limit or returning an error are both possible; consistency is what matters.

User-requested sorting also needs clear restrictions. Accept only supported fields and directions, establish a deterministic tie-breaker, and prevent a changed sort order from being combined accidentally with an earlier cursor. These details reduce repeated results, omissions, and queries that are difficult to optimize.

Migrating without breaking existing consumers

If an API already exposes offset pagination, changing the response or removing parameters can break applications and integrations. Before migrating, identify clients, usage patterns, deep-page requests, and observed errors. If telemetry is insufficient, instrument requests to learn which parameters are used, while respecting applicable privacy and retention policies.

  1. Define the new contract: ordering, filters, maximum page size, opaque cursor format, and behavior for invalid cursors.
  2. Introduce compatibility explicitly: for example, with a new route or parameter, or a documented transition that temporarily preserves the old mechanism.
  3. Test concurrent changes, tied sort values, the last page, changed filters, and malformed cursors or cursors reused out of context.
  4. Monitor adoption and performance before removing the old option. Communicate the changes and provide consumers with upgrade instructions.

Avoid silently changing the meaning of a response based on the client, or having the server interpret an ambiguous parameter in two ways. Compatibility should be verifiable, and deprecation dates or conditions should be documented rather than assumed.

Decision checklist

Decision checklist
  • Do consumers need to jump directly to a numbered page?
  • Does data change during browsing, and what is the impact of repeated or omitted results?
  • Is the ordering deterministic, with a unique tie-breaker?
  • Have deep queries and realistic page sizes been measured?
  • Are filters, limits, errors, and cursor reuse clearly defined?
  • Is there a compatibility strategy and a way to monitor adoption?

If direct navigation is central and the collection is manageable, offset can be a reasonable choice. If sequential browsing is the norm and volume or data changes make offsets fragile, cursor pagination is often a better fit. Document the guarantees you need first, then choose the mechanism: this helps the API meet consumers’ actual needs and evolve without surprises.

Fuentes y referencias

  1. Web standardsW3C
  2. OWASP Cheat Sheet SeriesOWASP Foundation
  3. Web performanceweb.dev