Heimdall Scan logo, AI security scanner for vibe coders
Heimdall ScanOpen Beta
WarningPerformance

N+1 database queries running inside a loop

An N+1 query happens when your code fetches a list of items with one query, then runs a separate query for each item in that list to get related data, instead of fetching everything in one go.

#What goes wrong

A common pattern is fetching a list of posts, then looping over them and querying for each post's author separately. It's the natural way to write the logic, and an ORM makes it easy to write without noticing you've turned one request into a hundred.

#Why it matters

With ten posts, ten extra queries are invisible. With ten thousand posts, that's ten thousand round trips to the database for a single page load, slow enough to time out or make the page unusable. This is one of the most common reasons an app that felt fast in testing crawls once it has real users and real data.

#How Heimdall checks for this

Heimdall looks for a database query inside a for loop, .map(), or .forEach() where the query depends on a value from the loop, a strong signal that the same relation could be fetched in a single batched query instead.

#How to fix it

Replace the per-item query with your ORM's relation-loading feature: Prisma's include, Drizzle's with, or a single query using a WHERE IN clause covering all the IDs at once. This turns N+1 queries into exactly one or two.

Frequently asked questions

Does every loop with a query inside it count?

How do I know if this is actually slowing my app down?

Does Prisma have a built-in fix for this?

Run this check on your own repo

Heimdall scans your GitHub repo for this and 29 other issues in under a minute.