DataLoader and N+1 problem in GraphQL
From the GraphQL cheat sheet · Resolvers · verified Jul 2026
DataLoader and N+1 problem
javascript
// N+1 Problem Example (BAD)
const resolvers = {
Query: {
posts: async (parent, args, { db }) => {
return await db.post.findMany(); // 1 query
}
},
Post: {
author: async (parent, args, { db }) => {
// This runs once per post! (N queries)
return await db.user.findUnique({
where: { id: parent.authorId }
});
}
}
};
// Result: 1 + N queries (if 100 posts, 101 queries!)
// Solution with DataLoader (GOOD)
const DataLoader = require('dataloader');
// Create loaders
function createLoaders(db) {
return {
user: new DataLoader(async (userIds) => {
// Batch load all users in one query
const users = await db.user.findMany({
where: { id: { in: userIds } }
});
// Map back to original order
const userMap = new Map();
users.forEach(user => userMap.set(user.id, user));
return userIds.map(id => userMap.get(id));
}),
postsByUser: new DataLoader(async (userIds) => {
// Batch load all posts
const posts = await db.post.findMany({
where: { authorId: { in: userIds } }
});
// Group by user
const postMap = new Map();
userIds.forEach(id => postMap.set(id, []));
posts.forEach(post => {
const userPosts = postMap.get(post.authorId);
userPosts.push(post);
});
return userIds.map(id => postMap.get(id));
})
};
}
// Use in context - loaders attach via the integration (Apollo Server 4+)
const server = new ApolloServer({ typeDefs, resolvers });
app.use('/graphql', cors(), express.json(), expressMiddleware(server, {
context: async ({ req }) => ({
db,
loaders: createLoaders(db) // New instance per request
})
}));
// Use in resolvers
const resolvers = {
Post: {
author: async (parent, args, { loaders }) => {
// Automatically batched!
return await loaders.user.load(parent.authorId);
}
},
User: {
posts: async (parent, args, { loaders }) => {
// Batched and cached
return await loaders.postsByUser.load(parent.id);
}
}
};
// Result: Just 2 queries total!💡 DataLoader batches and caches requests
⚡ Solves N+1 query problem
📌 Automatic request deduplication
🔥 Per-request caching