Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

A pagination function divides a large result set into smaller, navigable portions. Depending on the system, it may accept a page number, offset, marker, or cursor and return items plus a way to request the next portion. There is no single universal pagination function: the parameter names, ordering rules, response fields, and navigation options are defined by each API, database, framework, or content system.

What is pagination?

Pagination limits how many records an application fetches or displays at once. A request selects a slice of an ordered collection; the response contains that slice and, often, a next-page link, continuation marker, or opaque cursor.

For example, one API might use start and limit, while Cursor’s Origin API uses pageSize and pageToken. In that API, pageSize defaults to 30 and is capped at 100, and continuation tokens are opaque and tied to the originating resource and filters. Clients should follow the documented token or URL rather than decode or construct it themselves (Cursor Origin API documentation).

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How does a pagination function work?

  1. Choose a stable order. Sort by a defined field, such as creation time plus a unique ID tie-breaker.
  2. Send a position and size. The position can be a page number, offset, marker, or cursor; the size is usually a requested maximum, subject to the server’s default and maximum.
  3. Fetch the slice. The database or service applies the ordering and position, then returns up to the requested number of items.
  4. Return continuation information. The response may contain a next URL, marker, cursor, or page metadata. A client uses that value for the next request while keeping required filters and sort settings unchanged.

Because these contracts differ, a token called pageToken in one service is not automatically interchangeable with a cursor from another service.

#1 Best Overall
API Design Patterns
  • API Design Patterns
  • ABIS BOOK
  • Manning Publications

Page-number and offset pagination

How it is calculated

Page-number pagination converts a page number into an offset. For a zero-based page index, the usual relationship is offset = page × pageSize; a SQL-like query then limits the result count and skips that offset. An API may instead expose the offset directly.

Advantages

  • Users can jump directly to a numbered page.
  • Traditional “Previous,” “Next,” and page-number controls are straightforward to render.
  • It fits reports and mostly stable collections where users expect a known page count.

Costs and consistency problems

Deep offsets can become slower because the database may scan earlier results before returning the requested rows. MongoDB’s documentation specifically warns that skip() scans from the beginning of the input result set and takes longer as the offset increases (MongoDB cursor.skip() manual).

Offset boundaries can also move while a user is paging. If records are inserted or deleted between requests, an item can appear twice or be skipped. Laravel documents this limitation when contrasting offset pagination with cursor pagination (Laravel 13.x pagination documentation).

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Cursor pagination

How a cursor works

A cursor represents a position in an ordered result set. The server returns an opaque value after one page; the client sends it back to request the following page. Implementations commonly compare ordered column values in a WHERE clause instead of counting and skipping every preceding row.

Laravel’s cursorPaginate is one documented implementation. Laravel says it can perform better on large datasets when the ordered columns are indexed, but it requires a unique column or unique combination for ordering, does not support null-valued ordering columns, and does not generate numbered-page links (Laravel 13.x pagination documentation).

When cursors are a good fit

  • Feeds, activity streams, and “load more” interfaces.
  • Large collections where users normally move forward or backward rather than jump to page 47.
  • Frequently changing data, where a stable sort key reduces offset drift.

A cursor still depends on a deterministic order. If many rows share the same timestamp, add a unique tie-breaker such as an ID, provided the API or framework supports that ordering.

Marker and continuation-token pagination

Marker-based pagination is conceptually similar to cursor pagination: the response supplies a value that identifies where to continue. The difference is naming and implementation. Some services expose a readable marker; others issue an opaque, signed, or resource-bound token. Treat the value as an implementation detail unless the service explicitly documents its format.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For example, Cursor’s Origin API binds continuation tokens to the resource and filters used to create them. Reusing a token with different filters or a different resource is therefore not a portable technique (Cursor Origin API documentation).

Offset vs. cursor: which should you choose?

Decision factor Page number or offset Cursor or marker
Navigation Direct jumps to numbered pages Next/previous or load-more flow
Deep traversal May slow as the offset grows Designed to continue from a known position
Concurrent inserts/deletes Can cause skipped or repeated records Usually less sensitive when ordering is stable
Ordering requirement Must still use a defined order for predictable results Requires a stable, sufficiently unique order; Laravel disallows null ordering values
Numbered-page links Natural fit Not inherent; Laravel’s cursor paginator does not provide them
Client behavior Client can calculate a page or offset Client should return the supplied token without interpreting it

Choose based on navigation needs, dataset size, write activity, ordering guarantees, and the API contract—not on the word used for the parameter.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Pagination in common systems

Laravel

Laravel 13.x provides paginate, simplePaginate, and cursorPaginate. The first two support conventional page navigation; cursor pagination is intended for large datasets with suitable indexed ordering. Follow Laravel’s documented ordering and uniqueness constraints rather than assuming every Eloquent query can use a cursor.

MongoDB

MongoDB’s skip() can form the offset portion of a paginated query, but its scan-from-the-start behavior makes very large offsets increasingly expensive. For high-volume feeds, evaluate a range or cursor-style query based on an indexed sort key (MongoDB cursor.skip() manual).

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

WordPress

WordPress supplies post-list pagination helpers for previous/next links and numbered links. The Theme Handbook describes pagination patterns, and paginate_links() can generate links for other configured areas as well; these are WordPress-specific functions, not general-purpose language features (WordPress Pagination – Theme Handbook; WordPress paginate_links() reference).

GraphQL connections

GraphQL connection conventions commonly expose edges and pageInfo. Forward navigation often uses first with after; backward navigation commonly uses last with before. Spring GraphQL and API Platform document this cursor-oriented model, but individual schemas may add different fields or limits (Spring GraphQL request execution; API Platform GraphQL documentation).

Designing a reliable pagination contract

Define request parameters

  • State whether the position is a page index, one-based page number, raw offset, marker, or opaque cursor.
  • Document the default and maximum page size.
  • Specify whether filters and sort order must remain unchanged when following a continuation value.

Define response metadata

  • Return the requested items in a deterministic order.
  • Provide a next value or URL when more data exists; omit it or return an explicit end condition when it does not.
  • Include total counts only when they are accurate enough for the use case and affordable to compute.

Handle edge cases

  • Validate negative, zero, and excessive page sizes according to the API’s documented rules.
  • Decide what an expired, malformed, or filter-mismatched cursor returns.
  • Keep the sort key indexed when the chosen database and framework benefit from index-backed pagination.
  • Test behavior when records are inserted, deleted, or updated between requests.

Practical decision checklist

  1. Need “go to page” links or a page count? Start with page-number or offset pagination.
  2. Expect deep traversal, infinite scroll, or a rapidly changing feed? Prefer a cursor or continuation design if the system supports a stable unique order.
  3. Only have an opaque token from the service? Pass it back exactly as documented.
  4. Using a framework helper? Check its current version’s rules for ordering, nulls, limits, and link generation.
  5. Changing filters or sort order? Start a new pagination sequence instead of reusing the old continuation value.

The right pagination function is therefore the one whose contract matches the reader’s navigation needs and the data store’s consistency and performance characteristics.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.