back to blog

What is the N+1 Query Problem and How to Solve it?

Written by Namit Jain·August 4, 2025·4 min read

You’ve written the code. It works. But the page loads slowly, the database is doing way too much work, and you're staring at the query logs thinking, “Why are there so many SELECTs here?”

That moment when everything should be working but feels sluggish is when you might be meeting the N+1 query problem for the first time.

It’s not a bug. It’s not an error. It’s a pattern. And it’s quietly eating your performance.


What Is the N+1 Query Problem?

Let’s say you want to list all blog posts along with their comments.

So you do this:

  1. Fetch the posts.
  2. For each post, fetch its comments.

Seems fine, right?

But under the hood, this happens:

-- Step 1
SELECT * FROM posts;

-- Step 2
SELECT * FROM comments WHERE post_id = 1;
SELECT * FROM comments WHERE post_id = 2;
SELECT * FROM comments WHERE post_id = 3;
-- and so on...

If you have 100 posts, that’s 1 query for the posts and 100 more for the comments: N+1 queries in total.

That’s the problem.

It starts small. Feels innocent. But once your data grows, this turns into a flood of unnecessary database traffic and your app crawls.


Why Does It Happen?

Because it’s easy.

It happens when you’re thinking about data in terms of objects or loops instead of query efficiency. It happens when you reach for a simple solution without noticing what’s happening behind the scenes.

And yes, it happens with raw SQL too not just with ORMs. The problem isn’t the tools. It’s the pattern.


How to Tell You’re Doing It

Here’s what to watch for:

  • You’re running a loop in your code that includes a query.
  • Your query log is filled with the same SELECT statement, repeated with different IDs.
  • Your app is fast with 5 records but starts dragging with 50.
  • A profiler or database monitor shows a growing number of similar queries.

If your backend touches the database inside a loop, stop and look again. You might be doing more work than you think.


How to Solve It

The fix is about shifting your thinking: batch the data access, then organize it in memory.

  1. Use a Single Query with a JOIN

This works when the related data is lightweight and belongs in the same result set.

SELECT posts.id, posts.title, comments.body
FROM posts
LEFT JOIN comments ON comments.post_id = posts.id;

Now you’ve done in one query what used to take 101.

  1. Use an IN Clause to Fetch Related Data

Sometimes you don’t want a big JOIN. Maybe the data is complex or you need to process it differently.

In that case:

-- First: get the posts
SELECT * FROM posts WHERE ...;

-- Then: get all related comments at once
SELECT * FROM comments WHERE post_id IN (1, 2, 3, 4, 5);

Now you’ve done it in two queries, not 100.

  1. Build the Relationship in Your Code

Once you’ve got both sets of data, use code to group the related records by foreign key:

# Pseudocode
grouped = group_by(comments, key=lambda c: c.post_id)
for post in posts:
    post.comments = grouped.get(post.id, [])

Should You Care?

Yes, especially if your app is growing or handles lots of data.

The N+1 problem often hides until it becomes painful. You’ll think your logic is fine, your queries are clean, and yet performance keeps slipping. That’s why this issue is worth learning early.

Fixing it is often the difference between a system that “feels fine for now” and one that scales without surprise slowdowns.


Best Habits to Avoid N+1

  • Don’t query the database inside a loop. Ever.
  • Think in sets, not rows. How can you get everything you need at once?
  • Use profiling tools and query logs often.
  • If you’re using a framework or ORM, learn how it handles data fetching under the hood.
  • Watch for slowdowns even when the code is “technically correct.”

Interactive Demo

N+1 Query Simulator

N+1: 1 query + N individual queries | Batched: 2 optimized queries | JOIN: 1 single query

The N+1 query problem isn’t a bug in your code. It’s a lesson in how computers think about data and how to outsmart that inefficiency before it slows you down.