Modern examples of diverse examples of pagination in REST API design

If you work with APIs for more than five minutes, you’ll hit the question: **how should we paginate this thing?** And that’s where real-world, concrete examples of diverse examples of pagination in REST API design become incredibly useful. Instead of vague theory, you want to see how actual platforms structure their URLs, parameters, and responses. In this guide, we’ll walk through practical examples of diverse examples of pagination in REST API implementations from well-known services, plus patterns you can safely reuse in your own projects. These examples include page-based, cursor-based, offset-based, keyset, and hybrid approaches, along with the trade-offs that matter in 2024 and 2025: performance at scale, consistency under heavy writes, and developer experience. You’ll see how to shape links, how to expose metadata, and how to avoid the classic traps that turn a simple list endpoint into an operational headache. If you’re looking for the best examples of pagination patterns to copy, adapt, or improve, you’re in the right place.
Written by
Jamie
Published

Real-world examples of diverse examples of pagination in REST API

Let’s start where engineers actually live: concrete APIs. These examples of diverse examples of pagination in REST API design show how different teams solved the same problem with different constraints.

Example of classic page/size pagination (GitHub-style)

The most familiar pattern is page-based pagination using page and per_page (or limit) query parameters. GitHub’s REST API is a widely cited model here.

A typical request to list issues might look like:

GET /repos/{owner}/{repo}/issues?page=2&per_page=50
Accept: application/vnd.github+json
``

Key characteristics:

- The client selects `page` and `per_page`.
- The server returns headers like `Link` with `rel="next"`, `rel="prev"`, and so on.
- The response body is just the array of resources; pagination metadata lives in headers.

This is one of the best examples when you’re building admin dashboards or internal tools where data sets are modest and strict consistency is less important than simplicity. It’s also friendlier for UI components that think in “pages” rather than cursors.

The trade-off: under heavy writes, page numbers can shift. If new issues are created while a user is paging, items may appear on more than one page or be skipped entirely.

### Offset/limit pagination: SQL-friendly but not always scale-friendly

Offset-based pagination is another early favorite. A request might look like:

```http
GET /products?offset=200&limit=50

This maps directly onto SQL patterns like:

SELECT * FROM products ORDER BY id LIMIT 50 OFFSET 200;

This example of pagination is intuitive for backend engineers and works fine for small to medium tables. Many older APIs and internal microservices still expose this style because it matches relational databases so neatly.

However, once you hit millions of rows, OFFSET becomes expensive: the database has to scan and discard rows before returning the requested slice. That’s why newer examples of diverse examples of pagination in REST API design often move away from raw offset for high-traffic, high-volume lists.

Cursor-based pagination (Facebook/Twitter-style)

Cursor-based pagination uses an opaque token that represents a position in the result set. Instead of saying “give me page 3,” the client says “give me the next page after this cursor.”

A typical request might look like:

GET /users?limit=25&after=eyJpZCI6IjEwMDAifQ==

The response includes a next_cursor (and sometimes prev_cursor) value:

{
  "data": [
    { "id": "1001", "name": "Aisha" },
    { "id": "1002", "name": "Diego" }
  ],
  "paging": {
    "next_cursor": "eyJpZCI6IjEwMDIifQ==",
    "has_more": true
  }
}

Here, the cursor is an encoded representation of the last item in the page, often based on a stable sort key like id or created_at. Facebook’s Graph API and Twitter’s APIs are well-known real examples of this approach.

Why this matters in 2024–2025:

  • Large social and streaming platforms rely heavily on cursor-based pagination because it scales better and avoids the inconsistency of shifting pages.
  • It plays nicely with append-only event streams and time-ordered feeds.

When you’re building anything feed-like—activity streams, event logs, timelines—cursor-based pagination is one of the best examples to follow.

Keyset pagination: performance-focused example for large datasets

Keyset pagination is essentially cursor-based pagination with a very explicit key. Instead of OFFSET, you filter on a WHERE clause like id > last_seen_id.

A REST API might expose it like this:

GET /transactions?limit=100&after_id=900000

Under the hood, the database query might be:

SELECT * FROM transactions
WHERE id > 900000
ORDER BY id
LIMIT 100;

This pattern shows up in fintech APIs, analytics platforms, and logging systems. It’s fast because the database can use an index on id or created_at instead of scanning from the beginning every time.

When people talk about examples of diverse examples of pagination in REST API that scale into billions of rows, keyset pagination is usually part of the conversation. It trades user-friendly page numbers for predictable performance.

Time-based pagination for logs and analytics

Some APIs paginate by time window rather than record count. Think logs, metrics, or sensor data.

A request could look like:

GET /logs?start=2025-11-01T00:00:00Z&end=2025-11-01T01:00:00Z&limit=1000

The next page might advance the start to the timestamp of the last log entry returned. This is effectively a time-based cursor.

Real examples include logging and monitoring APIs from cloud providers, which often combine time filters with cursor tokens. This style works well when you care more about covering a time range than about a specific number of pages.

Mixed strategy: combining page numbers with cursors

Some teams adopt a hybrid approach: they expose page numbers for humans and cursors for machines.

For example:

GET /orders?page=3&page_size=50

The response might include both numeric metadata and a cursor for efficient follow-up requests:

{
  "data": [ /* 50 orders */ ],
  "page": 3,
  "page_size": 50,
  "total_pages": 40,
  "cursor": {
    "next": "eyJpZCI6IjE1MDAifQ==",
    "prev": "eyJpZCI6IjEwMDAifQ=="
  }
}

This gives dashboards and reports the comfort of page counts while allowing background jobs to use the cursor for long-running exports. It’s a good example of meeting two different use cases with one API.

Designing your own examples of diverse examples of pagination in REST API

Looking across these patterns, a few design questions shape which example you should copy or adapt.

How stable does the order need to be?

If your dataset changes rapidly—social feeds, event logs, streaming data—page-based and offset-based pagination can feel unreliable. Items shift around as new records arrive.

In those cases, cursor-based or keyset pagination offers more predictable behavior. You effectively say, “start after this specific record,” instead of “start at position 200.” That’s why many of the best examples from large platforms favor cursors.

For relatively static data—reference tables, configuration lists, archival content—page/size or offset/limit examples include everything you need without the complexity of cursor tokens.

How important is total count?

Product managers love to see “Page 2 of 20” and “Showing 51–100 of 2,000 results.” But counting rows at scale can be expensive.

Some APIs avoid total counts entirely, returning only a has_more flag. Others provide an approximate count, updated periodically. For data-heavy systems, this is a pragmatic compromise.

If you really need exact totals, page-based examples of diverse examples of pagination in REST API can work, but you may need caching, background jobs, or precomputed aggregates to keep latency under control.

How do you expose pagination metadata?

You have a few common patterns:

  • HTTP headers (like GitHub’s Link header)
  • A top-level meta or paging object in the JSON
  • Hypermedia-style links arrays

A clean example of a metadata-rich response might be:

{
  "data": [ /* items */ ],
  "meta": {
    "page": 2,
    "page_size": 25,
    "total_items": 612,
    "total_pages": 25
  },
  "links": {
    "self": "/items?page=2&page_size=25",
    "next": "/items?page=3&page_size=25",
    "prev": "/items?page=1&page_size=25"
  }
}

This style is one of the best examples for public-facing APIs because it’s explicit, self-documenting, and easy to consume from front-end frameworks.

Pagination might feel like a solved problem, but current patterns show some clear shifts.

More cursor-based examples in high-scale APIs

As datasets grow, more teams are moving to cursor and keyset patterns. They avoid performance cliffs and keep behavior stable under heavy writes.

Modern examples of diverse examples of pagination in REST API from large SaaS platforms often:

  • Use opaque cursors that encode primary keys and filters.
  • Tie cursors to a specific sort order and filter set, invalidating them if the client changes those parameters.
  • Provide short-lived cursors to avoid storing server-side state indefinitely.

Stronger contracts around ordering and filters

A subtle but important trend: APIs now document exactly how results are ordered and how that affects pagination. For example, an API might guarantee ordering by created_at descending, and require that clients keep the same sort when using a cursor.

This is not just pedantic. It avoids the confusing behavior where a cursor suddenly returns unexpected results because the client changed a filter mid-stream.

More explicit rate limiting and page size guidance

Because pagination interacts directly with rate limits, many APIs now publish recommended page sizes and patterns. For instance, they might encourage smaller pages for interactive UIs and larger pages for background exports.

Public documentation from organizations like the U.S. federal government’s open data initiatives, such as data.gov, reflects this trend: they often show concrete examples of pagination parameters, limits, and recommended usage so developers don’t accidentally hammer the service.

Practical examples include different resource types

To make this less abstract, consider a few domain-specific real examples of pagination patterns you might implement.

Medical research articles API

Imagine an API that lists peer-reviewed medical articles sourced from repositories like PubMed or NIH. A request might look like:

GET /articles?query=diabetes&sort=published_at&order=desc&page=1&page_size=20

The response could return total_results so clinicians and researchers see the overall volume of evidence. Since new articles don’t arrive every second, page-based pagination is reasonable here.

For inspiration, you can look at how research databases and government-backed resources structure their search endpoints, such as those linked from the National Institutes of Health.

Health information content API (consumer-focused)

A health information provider similar to Mayo Clinic or MedlinePlus from the National Library of Medicine might offer an API for articles on conditions, symptoms, and treatments.

Here, you might mix page-based pagination for consumer apps with cursor-based pagination for internal analytics. Public endpoints could use:

GET /conditions?alphabetical=A&page=2&page_size=30

Internal tools that analyze engagement might use a cursor tied to updated_at so they can scan content efficiently.

Patient-facing portal data

For a patient portal that lists lab results, appointments, or messages, you’d likely use cursor or keyset pagination on secure endpoints. A request might be:

GET /me/lab-results?limit=25&after=2025-01-01T00:00:00Z

This allows mobile apps to sync incrementally without downloading the entire history each time. While you won’t see raw examples from providers like CDC.gov in public APIs for protected data, the patterns echoed in healthcare interoperability standards often favor incremental, time-based retrieval.

Common pitfalls when copying examples of diverse examples of pagination in REST API

Looking at the best examples is helpful, but copying them blindly can cause problems.

Ignoring sort order

If you paginate without a deterministic ORDER BY, you invite chaos. Two identical requests can return different results, and cursors become meaningless.

Always pair pagination with a documented sort order. Many real examples include ordering by a stable field like id or created_at and disallow pagination without it.

Letting clients pick any page size

If clients can request page_size=100000, they eventually will. Set sane maximums and document them. Many public APIs cap pages at 100 or 1,000 items and return an error or silently clamp larger requests.

Mixing filters mid-pagination

If a client fetches page 1 with one filter set and page 2 with a different filter, results become unpredictable. That’s why some cursor-based APIs encode filters into the cursor itself and reject mismatched requests.

When you publish your own examples of diverse examples of pagination in REST API, show clearly that clients should keep filters and sort parameters stable while paginating.

FAQ: common questions and examples

What are some practical examples of pagination parameters in REST APIs?

Practical examples of parameters include:

  • page and page_size for page-based pagination.
  • offset and limit for SQL-style pagination.
  • cursor, before, and after for cursor-based pagination.
  • after_id or after_timestamp for keyset/time-based pagination.

Most modern APIs pick one primary style and use consistent names across endpoints.

Which example of pagination style is best for large datasets?

For very large, frequently updated datasets, cursor-based or keyset pagination is usually the best example to follow. They avoid the performance problems and shifting results that come with offset-based pagination.

Can I show total pages when using cursor-based pagination?

You can, but it’s often expensive or misleading. Many cursor-based APIs skip total pages and instead return has_more or an approximate count. If you absolutely need totals, you might precompute them or limit that feature to smaller datasets.

Do I have to expose cursors as readable IDs?

No. In fact, many of the best examples hide implementation details behind opaque, encoded cursors. Clients treat them as black boxes, which gives you freedom to change internals later.

How many items should I return per page?

There’s no single right answer, but many real examples include defaults like 20–50 items per page for interactive views, with upper bounds around 100–1,000 for export-style endpoints. Document your defaults and maximums so clients can plan around them.


If you treat these real-world patterns as examples of diverse examples of pagination in REST API design rather than one-size-fits-all rules, you can choose the approach that fits your data, your scale, and your users—without reinventing the wheel every time.

Explore More REST API Examples

Discover more examples and insights in this category.

View All REST API Examples