RMRM Full Stack & AI Engineer · All guides · Roadmaps
Backend · guide

API Pagination Explained

API pagination is the technique of splitting large datasets into smaller, manageable chunks called pages, returned sequentially across multiple API requests. It prevents servers from being overwhelmed and keeps client applications fast and responsive.

What Is API Pagination?

When an API endpoint could return thousands or millions of records, returning all of them in a single response is impractical and dangerous. Pagination breaks the result set into discrete pages, each containing a fixed number of items. The client requests one page at a time, optionally moving forward or backward through the full dataset. This mirrors how traditional search engines or e-commerce sites display results across multiple numbered pages.

Why Pagination Matters

Without pagination, a single API call could transmit gigabytes of data, exhaust server memory, and time out the client connection. Limiting response size reduces latency, lowers bandwidth costs, and protects backend databases from runaway queries. It also enables the server to apply query optimizations like index-range scans rather than full-table reads. For clients, smaller payloads mean faster rendering and a better user experience.

Common Pagination Strategies

Offset-based pagination uses a numeric skip value and a limit — for example, `?offset=40&limit=20` — and is the simplest approach but degrades in performance on large offsets. Cursor-based (keyset) pagination passes an opaque pointer to the last-seen record, such as `?after=eyJpZCI6MTAwfQ`, making each query equally fast regardless of depth. Page-number pagination (`?page=3&per_page=25`) is a user-friendly variant of offset pagination common in REST APIs. Time-based pagination uses a timestamp anchor and is popular in event streams and social-media feeds.

How Cursor-Based Pagination Works

The server encodes the last record's unique, indexed field — typically an ID or timestamp — into a cursor, often Base64-encoded. On each subsequent request the client sends this cursor, and the server executes a `WHERE id > :cursor ORDER BY id LIMIT n` query, which hits an index efficiently. The response includes both the data page and a `next_cursor` value for the following request. When `next_cursor` is null or absent, the client knows it has reached the end of the dataset.

Key Gotcha: Offset Pagination and Data Drift

Offset pagination has a well-known consistency problem: if records are inserted or deleted between requests, items can be duplicated or skipped across pages. For example, deleting a row while a client is on page 2 shifts all subsequent rows, causing the client to miss one record on page 3. This makes offset pagination unsuitable for frequently mutating datasets. Cursor-based pagination largely avoids this issue because it anchors to a stable, indexed value rather than a positional offset.

Best Practices

Always enforce a maximum page size server-side so clients cannot request unlimited records by passing a very large limit. Include metadata such as `total_count`, `has_next_page`, and cursor values in every response to help clients navigate without extra requests. Use cursor-based pagination for any dataset that grows beyond tens of thousands of rows or that mutates frequently. Document your pagination contract clearly in your API spec, including what happens when a cursor expires or a requested page is out of range.

Go deeper with an AI tutor that teaches this in context — and quizzes you on it.
Open the app — free to start

© RM Full Stack & AI Engineer · All guides · Roadmaps · Open the app