Stackbook Logo
architecture-descriptionestablished · low operational burden

Pagination (Cursor vs Offset)

Also known as: cursor-pagination, offset-pagination, keyset-pagination

Intent

Return large result sets in pages efficiently, avoiding performance cliffs and consistency issues.

Problem

Offset pagination (LIMIT/OFFSET) gets slower with each page, skips/duplicates on concurrent writes. Cursor pagination is consistent and fast.

Forces

  • •Result sets can be millions of rows
  • •Clients need predictable performance per page
  • •Concurrent writes must not cause skipped/duplicate items
  • •API must be simple for clients

Solution

✓ When to Use

  • •Any list endpoint returning >100 items
  • •Concurrent writes to collection
  • •Performance matters (mobile, infinite scroll)

✗ When Not to Use

  • •Small, static datasets (<100 items)
  • •Random access required (page 50 directly)
  • •Simple admin tools

Pros

  • +Constant performance: page 1 = page 10000
  • +Consistent: no skips/duplicates on writes
  • +Scales: works at billions of rows
  • +Stateless: cursor encodes position

Cons

  • −No random access (can't jump to page 50)
  • −Cursor opaque: client can't construct
  • −Bidirectional complex (reverse sort)
  • −Sort key must be unique + immutable

Cost Profile

Infrastructure

None — query pattern

Operational

Low — index on sort keys

Cognitive

Medium — cursor encoding, sort keys

Failure Modes

  • Non-unique sort key → unstable ordering, duplicates

  • Mutable sort key (updated_at) → items move between pages

  • Cursor tampering → invalid decode, 400

  • Reverse pagination without reverse index → slow

Real-World Examples

Alternatives

  • offset-pagination
  • page-numbers
  • infinite-scroll
  • load-more

Related Patterns

  • api-design
  • cursor-pagination
  • keyset-pagination
  • database-indexing
  • ulid

Competency Domains

distribution communicationdata statereliability opseconomics evolution