Back to results for “GraphQL”
Node.js › GraphQL

What is the N+1 query problem in GraphQL specifically, and how does DataLoader solve it?

Advanced

Answer

Because each field in a GraphQL query has its own independent resolver, a query returning a list of parent objects (like 100 posts) followed by each post's author field naturally triggers a separate resolver call (and potentially a separate database query) for each post's author individually -- resulting in 101 total queries. DataLoader solves this by batching and deduplicating requests made within a single tick of the event loop, collecting all the individual author IDs requested during that tick and issuing a single batched query for all of them at once, then distributing the results back to each individual resolver call.
const DataLoader = require('dataloader');

const userLoader = new DataLoader(async (userIds) => {
  const users = await db.users.find({ id: { $in: userIds } }); // single batched query
  return userIds.map(id => users.find(u => u.id === id));
});

// Each individual resolver call transparently benefits from batching
const resolvers = {
  Post: { author: (post) => userLoader.load(post.authorId) },
};
Real-world example A social media API's post-listing query, which previously issued 101 separate database queries to resolve 100 posts' individual author fields, drops to just 2 total queries (one for the posts, one batched query for all needed authors) after introducing DataLoader for the author field's resolver.

Common follow-ups: How does DataLoader's batching mechanism actually work using microtask timing to collect requests within a single tick?;What's the difference between DataLoader's batching and caching behaviors, and why does DataLoader typically need to be instantiated fresh per request?