// This scans ALL 10,000 documents
const images = await Image.find({
owner: userId
});
// Response time: ~800ms
app.get('/api/images', authenticate,
async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const skip = (page - 1) * limit;
const sort = req.query.sort || '-createdAt';
const [images, total] = await Promise.all([
Image.find({ owner: req.userId })
.select('name thumbnail width ' +
'height format createdAt')
.sort(sort)
.skip(skip)
.limit(limit),
Image.countDocuments({
owner: req.userId
}),
]);
res.json({
images,
pagination: {
page, limit, total,
totalPages: Math.ceil(total / limit),
hasMore: page * limit < total,
},
});
});
// Compound index
imageSchema.index({
owner: 1, createdAt: -1
});
// Text search index
imageSchema.index({
name: 'text', tags: 'text'
});
// Before index: 800ms for 10,000 docs
// After index: 2ms for 20 docs (paginated)
const explanation = await Image.find({
owner: userId
}).explain('executionStats');
console.log('Docs examined:',
explanation.executionStats
.totalDocsExamined);
// Before index: 10000 (full scan)
// After index: 20 (index scan)
Implement infinite scroll with React Query's useInfiniteQuery. Load 20 images, scroll to bottom, automatically load the next page.
git switch -c perf/PIXELCRAFT-052-pagination-indexes
git add server/ src/
git commit -m "Add pagination + DB indexes — 400x faster (PIXELCRAFT-052)"
git push origin perf/PIXELCRAFT-052-pagination-indexes
# PR → Review → Merge → Close ticket ✅
B-trees are the data structure behind virtually all database indexes.
A B-tree indexing 10 million records has a depth of only 3-4 levels.