stackademic

The leading education platform for anyone with an interest in software development.

Pagination

Returning large collections in manageable pages using offset or cursor strategies

Overview

When a collection has thousands of items, returning them all at once is slow and wasteful. Pagination breaks results into smaller pages so clients fetch only what they need. The two common approaches are offset-based (page numbers) and cursor-based (a pointer to the next item), each with trade-offs.

Syntax / Usage

Offset pagination uses limit and offset (or page). Cursor pagination returns a token pointing to the next page.

# Offset-based
GET /products?limit=20&offset=40

# Page-based (a friendlier offset)
GET /products?page=3&limit=20

# Cursor-based
GET /products?limit=20&cursor=eyJpZCI6MTAwfQ

Examples

An offset response includes metadata so clients know the total and current page:

{
  "data": [{ "id": 41, "name": "Item" }],
  "pagination": { "limit": 20, "offset": 40, "total": 137 }
}

A cursor response returns an opaque token for the next request:

{
  "data": [{ "id": 100, "name": "Item" }],
  "pagination": { "nextCursor": "eyJpZCI6MTIwfQ", "hasMore": true }
}

Common Mistakes

  • Returning entire collections with no pagination, causing slow responses
  • Using large offsets on big tables, which get slower the deeper you page
  • Skipping or duplicating rows when data changes during offset paging
  • Not returning total or hasMore, so clients can't build navigation
  • Letting clients request unbounded limit values with no maximum

See Also

api-design-rest-basics api-design-versioning api-design-http-methods