| Users / Requests | Offset Pagination | Cursor Pagination |
|---|---|---|
| 100 users | Simple queries, small data scans, fast response | Simple cursor tokens, fast and efficient queries |
| 10,000 users | Offset queries slow down due to large OFFSET scans | Cursor queries remain efficient, use indexed columns |
| 1,000,000 users | Offset queries cause high DB CPU and IO, slow response | Cursor queries scale well, minimal DB load, stable latency |
| 100,000,000 users | Offset pagination becomes impractical, DB overload | Cursor pagination requires careful token management, still scalable |
Pagination patterns (cursor, offset) in HLD - Scalability & System Analysis
The database query performance is the first bottleneck. Offset pagination requires scanning and skipping many rows as OFFSET grows, causing high CPU and IO load. This slows down response times and increases resource use. Cursor pagination avoids large skips by using indexed positions, reducing DB load and improving latency.
- Use Cursor Pagination: Replace offset with cursor to avoid large skips and improve query efficiency.
- Indexing: Ensure columns used for cursor are indexed for fast lookups.
- Cache Results: Cache popular pages or query results to reduce DB hits.
- Read Replicas: Use DB replicas to distribute read load.
- Limit Page Size: Keep page sizes small to reduce data transfer and processing.
- Token Management: For cursor, manage tokens securely and efficiently to avoid state issues.
Assuming 10,000 requests per second (RPS):
- Offset pagination at high OFFSET causes DB CPU spikes, increasing server costs.
- Cursor pagination keeps DB CPU stable, reducing need for extra servers.
- Storage impact is minimal for pagination itself but indexing adds overhead (~10-20% storage).
- Bandwidth depends on page size; smaller pages reduce network load.
Start by explaining the difference between offset and cursor pagination. Discuss how offset causes performance issues at scale due to large skips. Then explain how cursor pagination uses indexed positions to improve efficiency. Finally, mention practical scaling techniques like indexing, caching, and read replicas. Use real numbers to show understanding.
Your database handles 1000 QPS with offset pagination. Traffic grows 10x. What do you do first?
Answer: Switch to cursor pagination to reduce DB load caused by large OFFSET scans. This improves query efficiency and supports higher traffic without immediate hardware upgrades.
Practice
Solution
Step 1: Understand offset pagination limitations
Offset pagination uses page numbers and offsets, which can be slow and inconsistent on large or changing datasets.Step 2: Analyze cursor pagination benefits
Cursor pagination uses a unique cursor (like an ID) to fetch the next set of results, making it faster and more reliable for large data.Final Answer:
Cursor pagination is faster and more reliable for large datasets. -> Option AQuick Check:
Cursor pagination = faster, reliable [OK]
- Confusing cursor with page number
- Thinking cursor pagination returns total pages
- Assuming offset is always faster
Solution
Step 1: Identify offset pagination syntax
Offset pagination typically uses page numbers and limit, e.g., page=2 and limit=10.Step 2: Check options for correct syntax
/items?page=2&limit=10 uses page=2 and limit=10, which matches offset pagination style.Final Answer:
/items?page=2&limit=10 -> Option CQuick Check:
Offset pagination = page + limit [OK]
- Using cursor parameter for offset pagination
- Confusing offset with cursor values
- Using invalid parameter names like start or offset with strings
items = [
{"id": 101, "name": "A"},
{"id": 102, "name": "B"},
{"id": 103, "name": "C"}
]
last_cursor = 101
page_size = 2
next_page = [item for item in items if item["id"] > last_cursor][:page_size]
next_cursor = next_page[-1]["id"] if next_page else None
print(next_cursor)Solution
Step 1: Filter items with id greater than last_cursor
Items with id > 101 are 102 and 103.Step 2: Take first 2 items as page size is 2
Next page items are [{"id": 102, "name": "B"}, {"id": 103, "name": "C"}].Step 3: Get last item's id as next cursor
Last item id is 103, so next_cursor = 103.Final Answer:
103 -> Option DQuick Check:
Next cursor = last id in next page = 103 [OK]
- Choosing last_cursor as next cursor
- Selecting first item id instead of last
- Ignoring page size limit
Solution
Step 1: Understand offset pagination issues with changing data
Offset pagination can skip or repeat items if data changes between requests because offset is position-based.Step 2: Identify solution with cursor pagination
Cursor pagination uses unique IDs, avoiding duplicates or skips even if data changes.Final Answer:
Cause: Using offset with changing data causes duplicates or skips; Fix: Switch to cursor pagination. -> Option AQuick Check:
Offset pagination = inconsistent with changing data [OK]
- Thinking caching fixes offset pagination issues
- Confusing cursor and offset pagination roles
- Reducing limit does not solve data inconsistency
Solution
Step 1: Analyze requirements for large, changing datasets
Social media feeds have millions of posts and frequent updates, so pagination must be efficient and consistent.Step 2: Compare offset and cursor pagination suitability
Offset pagination is simple but slow and inconsistent with large, changing data. Cursor pagination efficiently handles these issues by using unique cursors.Final Answer:
Cursor pagination, because it handles large, changing datasets efficiently and avoids duplicates. -> Option BQuick Check:
Large dynamic data = cursor pagination best [OK]
- Choosing offset for large dynamic datasets
- Assuming offset is faster for big data
- Thinking cursor returns total pages
Ready to prove it?
Pass the test and this pattern moves unknown
