All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

Offset vs Cursor Pagination in Rails: What to Choose and Why

Post cover: Offset vs Cursor Pagination in Rails: What to Choose and Why
Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
In web applications with large data sets, sooner or later the question of pagination arises. Displaying thousands of entries in a table or list at once is a bad idea for both performance and the user. The most common approaches in Rails are offset pagination and cursor pagination. Next, we will analyze what it is, what are the advantages and disadvantages, as well as see examples of implementation.

Offset pagination

What is it
The Offset approach uses SQL statements OFFSET and LIMIT. He tells the base, "Skip N records and take the next M's".
An example in Rails
# Get a second page with 20 entries
users = User.order(:id).offset(20).limit(20)
SQL that will execute:
SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 20 OFFSET 20;
Advantages
  • Easy to implement.
  • Integrates well with ready-made gems (for example, kaminari, will_paginate).
  • User-friendly: You can quickly go to any page (eg №50 page).
Disadvantages
  • Performance problem: the bigger the offset, the slower the query runs. The DB still has to pass N records to skip them.
  • Instability of results: If entries are added or deleted in the table when browsing, the pages "move down". The user can skip or see the same data twice.

Cursor pagination

What is it
The Cursor approach uses a "pointer" (cursor) to the last element of the previous page. Instead of counting from the beginning, we say, "Show the next 20 entries after ID = X".
An example in Rails
Suppose we have users sorted by id.
# Get the first 20 entries
users = User.order(:id).limit(20)

# Get the next ones after the last id
last_id = users.last.id
next_users = User.where("id > ?", last_id).order(:id).limit(20)
SQL will look like this:
SELECT "users".* FROM "users" WHERE (id > 20) ORDER BY "users"."id" ASC LIMIT 20;
Advantages
  • High performance: the base does not go through thousands of records to search, but immediately jumps to the right place.
  • Stable results: When adding or removing entries, the cursor ensures that you do not see duplicates or omissions.
Disadvantages
  • No "arbitrary pages". You can only move forward or backward.
  • More difficult to implement, especially if the cursor should not be based on one field (id), but on complex sorting conditions.

When to use which approach?

Use offset pagination, if:
  • your tables are relatively small;
  • it is important to be able to go to a specific page (for example, "Page 50");
  • users rarely work with very deep lists.
Use cursor pagination, if:
  • you work with large amounts of data;
  • performance is critical;
  • you have enough Back/Next buttons instead of specific page numbers;
  • display stability is required with frequent data updates.
Offset-pagination easier to implement, but it is slow and less reliable for large amounts of data. Cursor-pagination faster and more stable, but limits navigation.
The choice depends on the task: if you are building a blog or catalog with thousands of entries - offset is suitable. If you are creating an API for a mobile application or working with constantly changing data (chats, news feeds) —, choose cursor.

This post doesn't have any additions from the author yet.

What is integer overflow?
15 Aug 08:28

What is integer overflow?

meme code
meme code@memecode
What is HAR file (HTTP Archive)?
25 Aug 18:23

What is HAR file (HTTP Archive)?

meme code
meme code@memecode
What is Bubble Sort (algorithm explanation)?
16 Sep 18:42

What is Bubble Sort (algorithm explanation)?

meme code
meme code@memecode
What is exponential growth?
16 Sep 18:57

What is exponential growth?

meme code
meme code@memecode
What is factorial complexity?
16 Sep 19:03

What is factorial complexity?

meme code
meme code@memecode
What is NP-complexity?
16 Sep 19:31

What is NP-complexity?

meme code
meme code@memecode
What is Row Security in PostgreSQL and why is it Rails developers
04 Oct 19:06

What is Row Security in PostgreSQL and why is it Rails developers

meme code
meme code@memecode
What is ivar in Ruby /Rails?
19 Oct 20:12

What is ivar in Ruby /Rails?

meme code
meme code@memecode
Basic methods of authentication in the API
19 Oct 20:26

Basic methods of authentication in the API

meme code
meme code@memecode
How do OAuth 1 differ from OAuth 2
19 Oct 20:34

How do OAuth 1 differ from OAuth 2

meme code
meme code@memecode
What is ORM and why is it needed?
26 Oct 14:00

What is ORM and why is it needed?

meme code
meme code@memecode
MCP: A new internet where sites communicate with AI
04 Nov 11:43

MCP: A new internet where sites communicate with AI

meme code
meme code@memecode