Detect N+1 query anti-patterns specifically — Repo calls inside Enum/for
Scanned 9/5/2026
Install to Claude Code
npx -y skills add oliver-kriska/claude-elixir-phoenix --skill ecto-n1-check --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ecto N1 Check?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/oliver-kriska-ecto-n1-check-4805c52e)More formats (shields.io, HTML) on the badges page.
---
name: ecto-n1-check
description: Detect N+1 query anti-patterns specifically — Repo calls inside Enum/for
loops, missing preloads on associations. Use when N+1 is explicitly suspected, NOT
for unrelated Ecto questions or wider database performance.
---
# N+1 Query Detection
Identify and fix N+1 query anti-patterns in Ecto/Phoenix applications.
## Iron Laws - Never Violate These
1. **Never access associations without preload** - Always preload before `Enum.map`
2. **No Repo calls inside loops** - Restructure to batch queries
3. **Preload at context boundary** - Load associations in context, not controllers/views
4. **Use joins for filtering** - Use `join` + `preload` when filtering by association
## Detection Patterns
### Pattern 1: Enum.map with Repo
```elixir
# BAD: N+1 queries
users
|> Enum.map(fn user -> Repo.get(Order, user.order_id) end)
# GOOD: Single query with preload
users
|> Repo.preload(:orders)
```
### Pattern 2: Association Access Without Preload
```elixir
# BAD: Lazy loading triggers N queries
for user <- users do
user.posts # Triggers query for each user!
end
# GOOD: Eager load first
users = Repo.all(User) |> Repo.preload(:posts)
for user <- users do
user.posts # Already loaded
end
```
### Pattern 3: Nested Association Access
```elixir
# BAD: N+1 for nested associations
user.posts |> Enum.map(fn post -> post.comments end)
# GOOD: Nested preload
Repo.preload(user, posts: :comments)
```
## Quick Detection Commands
Use Grep with context lines (`-B 5 -A 5`) to find `Enum.map` near `Repo.` calls in `lib/**/*.ex`.
Use Grep to find association access patterns (`.posts`, `.comments`, `.orders`) in `lib/**/*.ex`.
Use Grep with context (`-B 3`) to find `Repo.get` or `Repo.one` near loop patterns (`for`, `Enum`) in `lib/**/*.ex`.
## Analysis Command
For a context module, run:
Use Grep to find all `Repo.` calls in the context module, then verify each has appropriate preloads.
Then verify each query has appropriate preloads.
## References
For detailed patterns, see:
- `references/preload-patterns.md` - Efficient preloading strategies
- `references/query-optimization.md` - Query batching techniques
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!