Contents

Backend Development › Backend Basics · also in API Design

Pagination

Returning large result sets one page at a time.

Also known as: paging, paginate, limit and offset, page size

Pagination means returning a big list in pages instead of all at once. It protects your server, database and the client from huge responses, and gives users something fast to look at.

GET /orders?limit=20&offset=40       →  items 41-60
GET /orders?page=3&per_page=20       →  the same, by page number
GET /orders?limit=20&after=ord_917   →  the 20 items after one ID (cursor)
SELECT * FROM orders ORDER BY id DESC LIMIT 20 OFFSET 40;

A typical response includes the items and what’s needed to get the next page:

{
  "items": [ ... ],
  "next_cursor": "ord_897",
  "has_more": true
}

Two styles

Offset / page numberCursor (keyset)
Requestoffset=40 or page=3after=<last item's id>
Jump to page NYesNo
Stable while data changesNo: new rows shift pages, so items repeat or get skippedYes
Speed on deep pagesSlower: the database scans past all skipped rowsConstant

See offset vs cursor pagination for the trade-offs.

Rules

  • Always paginate lists that can grow, and set a default and a maximum page size (clients can ask for limit=1000000). See unbounded result sets.
  • Use a stable ORDER BY, ideally with a unique tie-breaker such as id. Without one, rows can appear on two pages or none.
  • Tell the client how to get more (next link, cursor or has_more).
  • Counting everything is expensive on big tables. Return a total only if you need it, or an approximate one.
  • Combine with filtering and sorting, and keep the parameter names consistent across your API.

Pagination also applies to reading from other APIs: loop until there’s no next page, and don’t assume everything comes in one response.