Skip to content
GreenSnippets

Keyset (cursor) pagination instead of OFFSET

Page through large tables quickly and stably by filtering on the last seen sort key.

SQL
SELECT id, title, created_at
FROM posts
WHERE (created_at, id) < ($1, $2)
ORDER BY created_at DESC, id DESC
LIMIT 20;

How it works

OFFSET 100000 makes the database read and discard 100,000 rows, and results shift if rows are inserted while paging. Keyset pagination remembers the last row's sort key and asks for rows after it, which uses an index and stays fast on deep pages.

The sort must be unique and deterministic: add id as a tie-breaker. Back it with an index on (created_at DESC, id DESC). Parameters $1 and $2 are the previous page's last created_at and id (omit the WHERE for the first page).