How do you design pagination for a Web API?

Web API & REST API Design Intermediate 2–3 Yrs3–5 Yrs Architecture 1 min read

Quick Answer

Accept page/pageSize (or a cursor) as query params, cap pageSize (e.g. 100), and return the items plus metadata — total count or a nextCursor, and links. Use offset pagination for simple admin lists; use cursor/keyset pagination for large datasets and infinite scroll because it stays fast at any depth.

I take page and pageSize, or a cursor, as query parameters, and I always cap the page size so a client can't ask for a million rows. The response has the items plus metadata — either a total count and page number, or an opaque nextCursor. For a straightforward admin grid, offset pagination is fine. For anything large or infinite-scroll I use cursor pagination, because offset gets slower the deeper you go and can skip or repeat rows if data changes between pages. Whatever the approach, the sort order needs a unique tiebreaker so results are stable.

  • Offset: ?page=3&pageSize=20. Simple, allows page jumps, but slow for deep pages and unstable if data changes between requests.
  • Cursor / keyset: ?cursor=<opaque>&limit=20. The cursor encodes the sort key of the last item. Fast and stable, but no arbitrary page jumps.
  • Response shape: { "items": [...], "page": 3, "pageSize": 20, "total": 512 } or { "items": [...], "nextCursor": "..." }. Optionally a Link header with rel="next"/"prev".
  • Always enforce a max page size and a default sort with a unique tiebreaker.
  • Computing total is a second query — make it optional if it's expensive.