Pagination Strategies
Implement efficient pagination. Learn offset and cursor-based pagination.
Pagination Strategies
Why Pagination?
Loading 10,000 records at once: - Slow response time - High memory usage - Poor user experience - Database overload
Solution: Load data in pages (10-50 items at a time).
Offset-Based Pagination
```javascript app.get('/products', async (req, res) => { const page = parseInt(req.query.page) || 1; const limit = parseInt(req.query.limit) || 10; const skip = (page - 1) * limit; const [products, total] = await Promise.all([ Product.find().skip(skip).limit(limit), Product.countDocuments() ]); res.json({ products, pagination: { currentPage: page, totalPages: Math.ceil(total / limit), totalItems: total, hasNextPage: page < Math.ceil(total / limit), hasPrevPage: page > 1 } }); }); ```
Cursor-Based Pagination
```javascript app.get('/posts', async (req, res) => { const limit = 10; const cursor = req.query.cursor; let query = {}; if (cursor) { query._id = { $lt: cursor }; } const posts = await Post.find(query) .sort({ _id: -1 }) .limit(limit + 1); const hasMore = posts.length > limit; const items = hasMore ? posts.slice(0, -1) : posts; res.json({ posts: items, nextCursor: hasMore ? items[items.length - 1]._id : null, hasMore }); }); ```
**Better for real-time data** (like social media feeds).
With Filtering
```javascript app.get('/products', async (req, res) => { const page = parseInt(req.query.page) || 1; const limit = 10; const skip = (page - 1) * limit; const query = {}; if (req.query.category) { query.category = req.query.category; } if (req.query.minPrice) { query.price = { $gte: parseInt(req.query.minPrice) }; } const [products, total] = await Promise.all([ Product.find(query).skip(skip).limit(limit), Product.countDocuments(query) ]); res.json({ products, pagination: { page, limit, total, pages: Math.ceil(total / limit) } }); }); ```
Key Takeaway
Use offset pagination for simple cases. Cursor pagination for real-time feeds. Always include total count. Support filtering with pagination.