Problem
You are debugging a REST API endpoint that returns a list of blog posts with their authors. The endpoint is painfully slow, taking 3-5 seconds to return 50 posts. Upon inspection, you discover the classic N+1 query problem.
The Scenario
Your application uses an ORM (e.g., Prisma, Sequelize, or TypeORM) to fetch blog posts. The code looks clean:
// Controller
async function getPosts() {
const posts = await prisma.post.findMany({ take: 50 });
const result = [];
for (const post of posts) {
const author = await prisma.user.findUnique({
where: { id: post.authorId }
});
result.push({ ...post, author });
}
return result;
}
This generates 51 SQL queries: 1 to fetch posts + 50 individual queries to fetch each author.
Your Task
- Identify all the places where N+1 queries can occur in a typical application (not just this example).
- Fix the example above using at least three different approaches.
- Prevent N+1 queries in the future with tooling and patterns.
Constraints
- The fix must maintain the same API response shape.
- Solutions should work with common ORMs (Prisma, Sequelize, TypeORM).
- Consider cases where the related data is nested multiple levels deep (e.g., posts -> comments -> users).
- Your solution should handle the case where some posts share the same author (deduplication).
What to Deliver
- Explain why N+1 happens and why it is hard to catch in development
- Provide three concrete fix approaches with code examples
- Describe how to detect N+1 queries in production
- Explain trade-offs between eager loading, data loaders, and joins