Practice · Interview · Card 3
"How do you find and fix an N+1 query?"
Every Rails interview asks this. The naive answer names includes and stops. The senior answer covers both halves of the question.
The question
"You suspect a view has an N+1. How do you confirm it, and how do you fix it?"
Your job
The question has two halves. Most candidates answer only the fix. Form an answer that covers both — diagnosis and fix — with concrete tools named.
Take a moment. Name three ways you'd confirm the N+1. Then name three variants of the fix and when you'd pick each. Bonus: how would you measure it in production.
The senior framing
Diagnose first. Three concrete ways:
- Bullet gem in development — raises (or logs) when an N+1 is detected.
- Read the dev log for repeating
SELECTlines on the same table during one request. .to_sqlon the relation to inspect the query Rails will send before it runs.
Fix. Three variants:
includesas the default — Rails picks preload or eager_load.eager_loadwhen you need to filter on the joined table.preloadwhen you specifically want two queries to avoid a giant JOIN result set.
For collections too big to load at once, switch to find_each(batch_size: ...) with batched preloading.
Bonus signal: name APM tools (Skylight, New Relic, Datadog) for production aggregates. Says you've shipped real Rails apps.
Junior framings that don't land
- "I'd add
.includes(:user)." Fix without diagnosis. The interviewer asked how you'd confirm the N+1; this skips that half. - "I look at logs and rewrite SQL by hand." Skips Rails-idiomatic tools. Bullet,
includes, and rack-mini-profiler are the standard kit. - "N+1 queries are rare in production." Wrong direction. N+1 is the single most common Rails performance bug; under-confidence reads as a red flag.
- "I'd just use
joins." A common mistake.joinsfilters by the association but doesn't load it, so accessing the joined record still N+1s.
What the rubric scores
- Two halves answered. Diagnose + fix, not just fix.
- Specific tools named. Bullet, rack-mini-profiler, the dev log,
.to_sql. - Variant awareness. Not just "use includes" but knowing when to switch to eager_load / preload / find_each.
- Production framing. APM, query logs, real measurements.
Theory
Full walkthrough at Scaling · Diagnose Before You Scale and Eager Loading.