« Back to Index

Pagination: offset vs cursor

View original Gist on GitHub

Tags: #pagination #design

README.md

What is pagination?

We use pagination to request specific segments of a dataset from an API (and a database) instead of everything at once.

Offset-based pagination

The use of offset-based pagination requires passing:

Offsets allow page-specific features, and are simple to implement and use.

[!WARNING] Offsets create database performances issues:

/* First request */

/services?filter[customer_id]=123&page[number]=1&page[size]=500

/* Response */

“data” : [,...],
“meta”: {
  "current_page": 1,
  "per_page": 500,
  "record_count": 1133,
  "total_pages": 3
}

/* Next request */

/services?filter[customer_id]=123&page[number]=2&page[size]=500

Cursor-based pagination

The use of cursor-based pagination requires passing:

The response will include:

And subsequent request will pass such cursor:

[!NOTE] *example identifiers

/* First request */
/services?filter[customer_id]=123&limit=500

/* Response */
“data” : [,…],
“meta”: {
  "next_cursor": “1tkSVoL9b7VAvdIhad9aH8”,
  "limit": 500
}

/* Next request */
/services?filter[customer_id]=123&limit=500&cursor=1tkSVoL9b7VAvdIhad9aH8

[!IMPORTANT] Cursor-based pagination provides a consistent query time, ideal for vast and changing datasets, and excluding total count and number of pages makes the performance optimization even more significative.

Issues with cursor-based pagination

/* Count request */
/services?filter[customer_id]=123&total=true

/* Response */
“data” : [],
“meta”: {
  "total": 1113
}