What is the N+1 problem in GraphQL and how is it solved?
N+1 happens when fetching a list triggers one query for the list and then one extra query per item for a nested field. DataLoader batches those per-item lookups into a single query.
Explain it simply
In GraphQL each field has a resolver function. Suppose you ask for 20 posts and each post's author. The posts resolver runs 1 query. Then the author resolver runs once for each post, 20 queries: 1 + 20 = 21 queries. With 100 posts it is 101. That is the N+1 problem, and it quietly kills database performance.
Solution: batching and caching per request, usually with DataLoader.
- Each author resolver asks the loader for an author id instead of querying.
- The loader waits a tick, collects all ids requested (say 20), and runs one query: SELECT * FROM users WHERE id IN (...).
- It then hands each resolver its own result, and caches repeats within the request.
Other fixes: use joins or eager loading in the parent resolver, or look at the query's selected fields and fetch only what is needed.
The same problem exists in REST ORMs; GraphQL just makes it easy to trigger from the client side.
Example
Naive:
SELECT * FROM posts LIMIT 20; -- 1 query
SELECT * FROM users WHERE id = 3; -- x20, one per post
Total: 21 queries
With DataLoader:
SELECT * FROM posts LIMIT 20; -- 1 query
SELECT * FROM users WHERE id IN (3,7,9,...); -- 1 query
Total: 2 queriesWhat to say in the interview
"N+1 is one list query plus one query per item for a nested field. I batch with DataLoader so nested lookups become one IN query per request, and add query depth and cost limits so clients cannot build expensive queries."