Backend & Node.js · APIs, data and failure

What is the N+1 query problem and how do you fix it?

Mediumn+1ormquery performanceUpdated Oct 2026
Quiz this track

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.

js
const users = await db.user.findMany();

for (const user of users) {
  user.orders = await db.order.findMany({
    where: { userId: user.id },
  });
}
One query for users plus one query per user. With 500 users, that is 501 queries.

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.

Add query-count assertions to tests for critical endpoints. N+1 often appears when a new field is serialized, long after the original endpoint was reviewed.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1How do you detect an N+1 query in production?
  2. 2When is eager loading worse than batching?
  3. 3How does a dataloader solve N+1?
  4. 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.