Backend & Node.js · APIs, data and failure
What is the N+1 query problem and how do you fix it?
Short answer
N+1 happens when code loads a list with one query and then issues one additional query per item. Fix it with a join, eager loading, batched lookups or a dataloader that collects ids into one request.
The first query returns N rows. A lazy relationship then triggers a query for each row, producing N+1 round trips. The result may be correct, but latency grows linearly and the database sees far more queries than necessary.
const users = await db.user.findMany();
for (const user of users) {
user.orders = await db.order.findMany({
where: { userId: user.id },
});
}The fixes
- Use a join or an eager-loading option that fetches the relation in one query
- Batch the child ids into a single IN query and group the results in memory
- Use a dataloader in GraphQL or similar APIs to coalesce requests per tick
- Select only the columns you need to reduce payload and memory
- Add an index on the foreign key used by the child lookup
- Watch nested serializers, which can reintroduce N+1 outside the original query
Eager loading is not automatically better. Joining a one-to-many relation can duplicate the parent row, so some ORMs split it into two queries. That is still fine if it is a constant number of queries. The goal is bounded query count, not a single query at any cost.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1How do you detect an N+1 query in production?
- 2When is eager loading worse than batching?
- 3How does a dataloader solve N+1?
- 4Why do serializers sometimes reintroduce the problem?
Say it in the interview
N+1 is one query to load a list followed by one query per item for a relation. I fix it by eager loading, joining, or batching the ids into a single lookup and grouping in memory. The goal is a bounded number of queries, not necessarily one. I also add query-count checks to tests because N+1 often sneaks back in through serializers or new fields.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Backend & Node.js mock interview and get scored feedback on depth, clarity and confidence.