fan_outSingle request triggered too many database queries
Request fans out into many DB queries, indicating architectural issues or missing data aggregation. High query fan-out increases latency and puts pressure on connection pools.
Common Causes
- —Missing aggregation — data fetched piecemeal
- —No DataLoader for nested resolvers
- —Redundant queries for the same data
- —Missing joins or batch operations
How to Fix
- 1.Use batch queries or DataLoader
- 2.Implement response caching
- 3.Aggregate data on the backend
- 4.Redesign data model for fewer round-trips
Multiplied by request volume
10 queries per request at 100 req/s is 1,000 DB queries per second. Fan-out makes your database load proportional to your traffic spikes.
Example
typescript
// BAD — fan-out: one query per post author
const posts = await Post.find({ published: true });
const postsWithAuthors = await Promise.all(
posts.map(post => User.findById(post.authorId))
);
// GOOD — single joined query
const posts = await Post.find({ published: true }).populate('author');Prisma field selection
typescript
// BAD — selects all columns including large text fields
const users = await prisma.user.findMany();
// GOOD — only what the caller needs
const users = await prisma.user.findMany({
select: { id: true, name: true, email: true },
});
// GOOD — Mongoose projection
const users = await User.find().select('name email -_id');Multiplied by request volume
10 queries per request at 100 req/s is 1,000 DB queries per second. Fan-out makes your database load proportional to traffic spikes.
Parallel fan-out with Promise.all
typescript
// BAD — sequential fan-out (slow + many queries)
for (const id of userIds) {
const profile = await Profile.findOne({ userId: id });
}
// BETTER — parallel but still N queries
const profiles = await Promise.all(
userIds.map(id => Profile.findOne({ userId: id }))
);
// BEST — single IN query
const profiles = await Profile.find({ userId: { $in: userIds } });
// Then map back to userIds order if needed
const profileMap = new Map(profiles.map(p => [p.userId.toString(), p]));