---
title: "API pagination: cursor vs offset"
slug: api-pagination-cursor-vs-offset
canonical_url: https://oreoro.github.io/posts/api-pagination-cursor-vs-offset/
published_at: 2026-06-04T00:00:00.000Z
updated_at: 2026-06-04T00:00:00.000Z
tags: 
  - Guide
  - Tools
excerpt: "When to use cursor pagination and how to implement it safely."
author: "Unknown Author"
---

## Navigation Context

- Canonical URL: https://oreoro.github.io/posts/api-pagination-cursor-vs-offset/
- You are here: Home > Posts > API pagination: cursor vs offset

### Useful Next Links
- [Home](https://oreoro.github.io/)
- [Contact](https://oreoro.github.io/contact/)
- [Donate](https://oreoro.github.io/donate/)
- [Personal Notes](https://oreoro.github.io/collections/personal-notes/)

### Cursor pagination (recommended)

-   Stable under inserts/deletes
-   Uses an opaque cursor (e.g., last seen id + sort key)
-   Easy to cache and resume

```
SELECT *
FROM items
WHERE (created_at, id) < (:created_at, :id)
ORDER BY created_at DESC, id DESC
LIMIT 50;
```

### Offset pagination (avoid at scale)

-   Can skip/duplicate rows when data changes
-   Gets slower as offset grows

![](https://app.notion.com/icons/info_blue.svg)

If you need “page numbers”, store cursors per page server-side.