API Pagination: The Right Way to Handle Large Datasets
As of February 2026, poorly paginated APIs remain one of the top causes of client frustration and performance issues. Here is how to do it right.
The Problem
When your API returns thousands of records, sending everything at once is a disaster waiting to happen. Clients timeout, servers choke, and everyone has a bad time.
5 Pagination Best Practices
1. Use Cursor-Based Pagination
Offset pagination seems easier but falls apart at scale.
// Bad: Offset pagination breaks with large datasets
GET /users?page=2&limit=50
// Good: Cursor-based is reliable
GET /users?cursor=eyJpZCI6MTAwfQ&limit=50
Cursor pagination uses an opaque token (usually the last ID or a timestamp) instead of page numbers. It is faster and will not skip items when new data is inserted.
2. Always Return Metadata
Clients need to know there is more data:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTAwfQ",
"has_more": true,
"total": 1247
}
}
3. Set Reasonable Limits
Do not let clients request 100,000 records. Cap it:
const MAX_LIMIT = 100;
const DEFAULT_LIMIT = 20;
const limit = Math.min(req.query.limit || DEFAULT_LIMIT, MAX_LIMIT);
4. Support Both Directions
Power users need to navigate backward too:
GET /users?cursor=abc&limit=20&direction=forward
GET /users?cursor=xyz&limit=20&direction=backward
5. Be Consistent Across Endpoints
Do not use page numbers on one endpoint and cursors on another. Pick one strategy and use it everywhere.
Quick Implementation in Node.js
app.get(/api/users, async (req, res) => {
const { cursor, limit = 20 } = req.query;
const query = cursor
? { _id: { $lt: cursor } }
: {};
const users = await User.find(query)
.sort({ _id: -1 })
.limit(parseInt(limit) + 1);
const hasMore = users.length > parseInt(limit);
const data = hasMore ? users.slice(0, -1) : users;
const nextCursor = hasMore ? data[data.length - 1]._id : null;
res.json({ data, pagination: { next_cursor: nextCursor, has_more: hasMore } });
});
The Bottom Line
Cursor-based pagination is the winner for production APIs. It scales, stays fast, and handles real-world data changes gracefully.
What is your pagination strategy? Drop a comment below.
Top comments (0)