Cookbook recipe

Keyset pagination instead of OFFSET

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source
Estimated investigation4 min

Scenario

Page 5000 of an OFFSET-paginated list is painfully slow because the database still scans and discards every skipped row. Keyset pagination is O(1) per page. Diagnose it Replace OFFSET with a WHERE on the last seen…

Investigation Path

Page 5000 of an OFFSET-paginated list is painfully slow because the database still scans and discards every skipped row. Keyset pagination is O(1) per page.

Diagnose it

Replace OFFSET with a WHERE on the last seen key:

-- slow: OFFSET 100000 LIMIT 20
-- fast keyset:
SELECT * FROM posts
WHERE (created_at, id) < ('2026-01-01', 9999)
ORDER BY created_at DESC, id DESC
LIMIT 20;

Why it happens

OFFSET N must still read and throw away N rows before returning results, so cost grows with page depth. Keyset uses an index range starting just past the last row you saw.

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • How to fix it
  • Prevent it next time
  • Related & next steps
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Career Impact

This scenario builds production judgment and operational confidence under pressure.

Open Career Dashboard →

Keep going

Related & next steps

Was this helpful?

← All cookbook recipes