On this page
The core idea
Offset pagination is straightforward for many small or stable collections. Cursor pagination can work better for large or changing result sets when it uses a stable ordering and continuation boundary. Neither approach removes the need to define sorting, filters and what happens when records change between requests.
A practical approach
Step 1
Choose a deterministic order with a tie-breaker, such as creation time plus a unique ID. Document how filters interact with that order.
Step 2
For cursor pagination, encode the continuation position and validate it on the server. Do not treat a cursor as permission to access records outside the current user’s scope.
Step 3
Test inserts and deletions between page requests. Decide whether the interface needs a live view or a consistent snapshot.
Worked example
An activity feed sorts by newest event. A cursor based on timestamp and event ID can continue below the last item seen even when newer events arrive. Using only a timestamp can skip or duplicate records when several events share the same value.
A mistake to avoid
Changing the sort order while reusing an old cursor makes the continuation ambiguous. Bind the cursor to the relevant query shape or require the client to restart pagination.
Try it yourself
Create a dataset with repeated timestamps. Fetch two pages, insert a new record between requests and check for duplicates or omissions under your chosen pagination contract.
Your implementation checklist
- Ordering has a unique tie-breaker.
- Cursors are validated and scoped.
- Filter changes reset continuation.
- Concurrent data changes have defined behaviour.
Share or cite this guide
Innovate with Ajay Editorial (2026-10-04). Choose Pagination around How Your Data Changes. https://innovatewithajay.com/blogs/choose-cursor-pagination-deliberately
