From rails
This skill should be used when the user wants to debug performance issues, investigate N+1 queries, analyze slow requests, profile memory usage, or understand query patterns in a Ruby on Rails application. Activates on: "debug performance", "N+1 queries", "slow request", "query analysis", "memory profiling", "rails performance", "find slow queries", "bullet", "why is this slow", "optimize queries", "eager loading", "database performance", "debug rails", "profile request", "analizzare performance", "query lente".
npx claudepluginhub fabn/claude-plugins --plugin railsThis skill uses the workspace's default tool permissions.
Investigate and resolve performance issues in Rails applications. Covers N+1 query detection, query analysis, memory profiling, and request performance investigation.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Investigate and resolve performance issues in Rails applications. Covers N+1 query detection, query analysis, memory profiling, and request performance investigation.
Reference files: Consult reference/patterns.md for detection techniques, profiling tools, and optimization patterns.
Determine what kind of performance issue the user is investigating:
| Symptom | Problem Type | Investigation Path |
|---|---|---|
| Slow page/endpoint | Query N+1 or missing index | Step 2 |
| High memory usage | Object allocation or large dataset | Step 3 |
| Slow background job | Inefficient queries or external calls | Step 2 + Step 4 |
| General "it's slow" | Need profiling data first | Step 4 |
If the user describes a specific endpoint or action, read the relevant controller and model code first.
Analyze the code path for N+1 patterns:
Read the controller action to identify which models are loaded
Trace the association chain:
has_many through chains?Search for missing eager loads:
Grep for: .each, .map, .select, .find_each in the controller/service
Then check: does each iteration access an association not in includes/preload?
Check existing eager loading:
Grep for: .includes(, .preload(, .eager_load( in the relevant scope/controller
Propose fix with the appropriate loading strategy:
includes — lets Rails decide (usually preload, switches to eager_load if WHERE references the association)preload — always separate queries (one per association), best for has_manyeager_load — LEFT OUTER JOIN, needed when filtering/sorting by associationFor GraphQL APIs: Check for DataLoader/BatchLoader usage:
app/graphql/loaders/ for existing batch loadersGraphQL::Batch or dataloader usageWhen investigating memory issues:
Identify large dataset loading:
Grep for: .all, .to_a, .load on large tables
Grep for: .pluck vs .select (pluck avoids AR instantiation)
Check for unbounded queries:
.limit on user-facing queries.find_each / .in_batches not used for bulk operationsincludes chains loading entire association treesSuggest memory-efficient alternatives:
.find_each(batch_size: 1000) instead of .each for large sets.pluck(:id, :name) instead of .select(:id, :name).map { ... }.in_batches.update_all(...) instead of loading + iterating + savingFor background jobs: Check if the job loads more data than needed. Suggest passing IDs and re-querying with scoped selects.
When the user needs to profile a specific request:
Check if profiling tools are available:
Grep Gemfile for: rack-mini-profiler, bullet, memory_profiler, benchmark-ips, stackprof
If Bullet is configured, guide the user to check Bullet output:
Bullet.enable in development configlog/bullet.log for detected N+1sconfig/environments/development.rb for Bullet settingsIf rack-mini-profiler is available, suggest:
?pp=flamegraph for request flamegraph?pp=profile-gc for GC profiling?pp=analyze-memory for memory analysisFor production issues (no profiling tools):
/datadog:traces)log/development.log for query counts and timingsActiveSupport::Notifications to instrument specific code pathsQuick benchmarking for isolated code:
# In rails console
require 'benchmark'
Benchmark.bm do |x|
x.report("current") { current_implementation }
x.report("optimized") { optimized_implementation }
end
When queries are slow due to missing indexes:
Find the slow query from logs or Datadog traces
Check existing indexes:
Read db/schema.rb, search for the table name
Look at add_index lines for the relevant columns
Analyze query patterns:
Generate migration for missing indexes:
add_index :table_name, :column_name
add_index :table_name, [:col1, :col2] # composite covers col1 queries too
Warn about redundant indexes (per project conventions):
[:email, :locale] already covers queries on email aloneadd_index :t, :email and add_index :t, [:email, :locale]Summarize the investigation with:
Suggest follow-up actions:
| Situation | Action |
|---|---|
| No profiling gems installed | Suggest adding bullet/rack-mini-profiler to Gemfile development group |
| Cannot reproduce in development | Suggest using Datadog APM traces from production (/datadog:traces) |
| Complex association chain | Draw the association path as a diagram before suggesting fixes |
| Multiple N+1s in same endpoint | Prioritize by frequency (most iterations first), fix in one includes chain |
| Schema file not found | Check for db/structure.sql as alternative to db/schema.rb |
reference/patterns.md — Common N+1 patterns, eager loading strategies, memory optimization techniques, and profiling tool configurations