hermes

Fix N+1 queries

Finds N+1 database queries behind an endpoint, page or job by counting real queries, fixes them with eager loading or batching, and adds a query-count test so they do not return.

context

An N+1 query happens when code loads a list with one query and then runs one more query per item, usually through lazy-loaded relations inside a loop or a serializer. It looks fine with test data and collapses with real data. The fix must be proven by counting queries, not by reading the code.

task

Find and fix N+1 queries in: Only if [QUERY_LOG] is given: Start from this log or trace:

  1. Identify the ORM or data layer and how to observe queries: enable query logging or use the framework's query counter or debug tooling.
  2. Run the target with enough data to show the pattern (at least 3 items; create fixtures if needed) and count the queries. Record the count and, if available, the time.
  3. Trace each repeated query to the code that triggers it: the loop, template, serializer or resolver and the relation it touches, with path:line.
  4. Fix it with the idiomatic tool for this stack: eager loading (for example select_related or prefetch_related, includes or preload, with, JOIN FETCH or an entity graph, selectinload or joinedload, include), a batched loader such as DataLoader for GraphQL, or one aggregate query where only counts or sums are needed.
  5. Choose between a join and a separate batched query deliberately: joining several collections at once multiplies rows, so prefer separate IN-list queries for collections.
  6. Re-run and count again. Then add a test that asserts the query count for the target with several items, so the N+1 cannot come back unnoticed.
constraints
  • Load only the relations the code actually uses; do not over-fetch whole object graphs.
  • Keep the response shape and ordering identical.
  • Do not add caching as the fix for an N+1.
  • Report real query counts from runs, not from reading the code.
  • Before saying the work is done, run the check that proves it (tests, build, type check or the command the user gave) and report the real result.
  • If you could not run a check, say so plainly and say which one.
  • Do only what was asked. If you notice something else worth changing, mention it in one line at the end instead of changing it.
  • Keep the change as small as it can be while still being correct.
output format

Result

One line: queries before and after for N items, and time if measured.

Cause

Each N+1: path:line — the loop or serializer — the relation loaded per item.

Fix

The diff, then one sentence per change on why it removes the extra queries.

Regression guard

The test added and its result.

Other N+1 patterns spotted

Bullets with path:line, not fixed. Or "None".

1 required value still a placeholder; the assistant will ask for it.

details

kind
Prompt: a task you run by name to get one finished thing back
domain
Software engineering
category
Performance
level
Intermediate
made for
Backend engineer, Full-stack engineer, Software engineer
needs
repo-read, file-write, shell
risk
runs-commands
version
v1.0.0 · experimental
reviewed
2026-10-02
works in
Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md

Edit on GitHubReport a problem

use in

Hodios CLI
npx @hermes-hq/hodios install fix-n-plus-one-queries --target claude-code
Agent Skills
npx skills add hermes-hq/hodios-dist --skill fix-n-plus-one-queries -a claude-code
Add the Hodios marketplace (once)
claude plugin marketplace add hermes-hq/hodios-dist
Install the software-engineering plugin
claude plugin install hodios-software-engineering@hodios

The plugin brings every entry in this domain at once.

more in performance

All of Performance
PromptPerformance

Profile and speed up a hot path

Measures a slow operation, profiles where the time goes, and makes it faster one verified change at a time, with before-and-after numbers. Use when an endpoint, command or function is too slow.

profile-hot-path
PromptPerformance

Reduce JavaScript bundle size

Measures a web app's JavaScript bundles, finds the largest avoidable contributors, and shrinks them with verified changes ranked by bytes saved. Use when page load is slow or a size budget is blown.

reduce-bundle-size
PromptPerformance

Find a memory leak

Finds a memory leak from heap snapshots, memory metrics and code, naming the retaining path and the minimal fix with a regression check. Use when memory grows until a process is killed or restarted.

find-memory-leak
PromptPerformance

Improve Core Web Vitals

Diagnoses poor Core Web Vitals (LCP, INP, CLS) from a Lighthouse, field-data or trace report and ranks fixes by expected improvement. Use when a page fails the vitals thresholds.

improve-web-vitals
PromptPerformance

Optimise a slow SQL query

Speeds up a slow SQL query from its execution plan, proposing rewrites and indexes with expected gains and their write-cost trade-offs. Use when one query dominates latency or database load.

optimize-sql-query
PersonaPerformance

Performance engineer

Acts as a performance engineer who profiles before optimising, changes one thing at a time and reports gains with numbers and variance. Use for latency, throughput or memory work.

performance-engineer