Topic 34

Pagination: Data Comes in Pages

Scale

Vera asks Tandem for the stations and gets fifty back. Riverport has two hundred and fourteen. Nothing failed, nothing was refused, and the status line says 200 — because the response also carried the two fields she has been politely ignoring since Chapter 4: "page": 1 and "total_pages": 5. The envelope was telling her all along that she was holding one fifth of the answer.

No API hands over its entire warehouse in one response. Data arrives in pages — fixed-size slices of a longer list, one slice per request. This page teaches the two ways an API asks you to turn the page, and the habit that keeps a Thursday report from being quietly built on page one of five.

Walking a list of 214 in slices of 50
Ask for page 1?page=1&limit=50
50 stations + total_pages: 5the envelope answers
Ask again for 2, 3, 4one request per page
Page 5: all 214, assembledand you know you are done

Why Servers Send Pages

Two hundred and fourteen stations is a small list, and a server could send it whole without breaking a sweat. But the same endpoint pattern serves /rides, where a busy month in Riverport runs to hundreds of thousands of trips. One response holding all of them would be slow for the server to assemble, slow to travel, expensive to hold in memory at both ends, and — if you asked for it from a terminal — a wall of text scrolling past for a minute and a half.

So the server sets a size and hands the list out a slice at a time. Tandem's default is fifty items per response and its documented maximum is two hundred. That is not stinginess; it is the same instinct as a shop that sells flour in bags rather than tipping the silo into your car. The cost of the whole thing at once is paid by everybody on the line, including you.

The Numbered Dialect: page and limit

The first dialect uses plain counting. Two query parameters do the work: page says which slice you want, and limit says how big a slice is. Ask for page two with a limit of fifty and you get stations fifty-one through one hundred. Both are ordinary query parameters, exactly the grammar from Chapter 3, and they compose with everything else on the endpoint's menu.

The second slice of the station list, asked for by number
curl "https://api.tandem.example/v1/stations?page=2&limit=50"

Think of an archive counter with a clerk who hands you a box at a time: "records 1 to 50 of 214 — come back for the next box." You can ask for box four without touching boxes two and three, which is the strength of this dialect. Numbered pages are predictable, jumpable, and trivially explained to a colleague.

They have one honest flaw, and it is worth a calm paragraph rather than fear. A page number describes a position in a list, and the list can move while you are walking it. Suppose Tandem adds a station while Vera is between page two and page three. Everything after the new arrival shifts one place later, so the station that was last on page two — already recorded — slides to the top of page three, and she records it twice. A deletion does the opposite: a station slides backward into a page she has already read, and she never sees it. On 214 slow-changing stations this almost never bites. On a live ride log, it is the reason the second dialect exists.

The Bookmark Dialect: Cursors

The second dialect replaces the page number with a cursor — a short string the response hands you that means "resume exactly here". You do not compute it and you do not read it. You copy it into the next request, unchanged, and the server continues from precisely where it stopped.

The cursor comes back in the envelope, and goes out again untouched
{"data": [ … 50 stations … ], "next_cursor": "c3RfMDUw"}

curl "https://api.tandem.example/v1/stations?cursor=c3RfMDUw"

That string of letters is deliberately opaque — not a page number in disguise, and not yours to decode or build. (Underneath, many cursors are an encoded position; the contract is that the encoding is the provider's to change without warning, so you treat it as a token.) It is the librarian's bookmark: it marks the record you stopped at, not the shelf position, so nothing shifts underneath it when items are added or removed. The trade is that you cannot jump. There is no way to leap to the fourth slice; you walk them in order, or not at all.

You never have to guess which dialect an endpoint speaks. The parameters table in its reference page lists either page and limit or a cursor parameter, and the response shape confirms it. Some APIs offer both on the same endpoint. Recognizing the two shapes is the whole skill, and after this page no pagination scheme you meet will be genuinely new.

Walking All Five Pages

The loop, in words: ask for the first slice, read the metadata, ask for the next, and stop when the metadata says you are finished. With numbers, finished means the page you just received equals total_pages. With cursors, finished means the next cursor came back empty or absent. Both dialects tell you when to stop — the failure mode is not asking.

For the Thursday report that means five commands instead of one, each identical except for a single number, and a station count of 214 at the end that Vera can check against what she knows about Riverport. That last check is the cheap insurance: if the total does not match, you stopped early somewhere.

One thing to carry to the next page. Each of those five requests is a request, and Tandem allows sixty of them a minute. Pagination is the first mechanism in this book that quietly multiplies how often you knock on the door, which is exactly why the rate-limit topic follows it rather than the other way around.

Common Confusions
  • "I got fifty results, so that is all there are." The envelope says otherwise, in writing, on every response. Ignoring total_pages or the next cursor is the classic silent truncation: no error, no warning, and a report that is quietly one fifth of the truth.
  • "I will set limit to ten thousand and skip the loop." Tandem documents a maximum of two hundred, and a documented cap is a term of the contract rather than a suggestion. Ask Tandem for more and you get the cap, not the moon — other APIs refuse such a request outright. Either way the documented maximum is the real one.
  • "Cursors are just page numbers with the numbers hidden." They encode a position in a list that may be moving, which is why they survive insertions and deletions that renumber pages. Treat one as a token to hand back, never as something to read or invent.
  • "Page one is the newest data, so it is the only page that matters." Page one is the first slice in whatever order the endpoint uses, which is usually not "most recent" unless you asked for that order. Sorting is the next topic, and it is what actually decides what lands on page one.
Why It Matters
  • Reports built on an unwalked list are among the most common data errors in offices anywhere, and they are invisible: every number present is correct, and only the missing ones are wrong. The envelope habit prevents Vera's version of that, permanently.
  • Both dialects appear on documentation pages everywhere. Once you can recognize numbered pages and cursors on sight, you can start using an unfamiliar API's list endpoint correctly on the first attempt instead of the third.

Knowledge Check

Why does Tandem hand back fifty stations instead of all 214?

  • Whole lists are costly to build, to send, and to read
  • Fifty items is the largest a JSON response may hold
  • Stations past the fiftieth are reserved for paying partners
  • The other stations are inactive and left out of results

A response says "page": 1 and "total_pages": 5. What does that tell you?

  • The server has split the answer into five downloadable files
  • Four more slices remain and you have fetched only the first
  • Five other partners requested this same list this minute
  • Your request was attempted five times before succeeding

What is a cursor, in pagination?

  • A page number the server scrambles so partners cannot count
  • A pointer into the docs showing where the parameters begin
  • An opaque marker you send back to continue the list
  • The id of the last station, for building the next request

Vera sets limit=10000 to avoid walking five pages. What happens?

  • Her key is suspended for the rest of the hour as a penalty
  • The address becomes invalid, because no such parameter exists
  • All 214 arrive at once and the extra size is billed to her
  • The documented cap of 200 applies, so she receives 200 rows

You got correct