Rails_ai_agents performance-optimization

install
source · Clone the upstream repo
git clone https://github.com/ThibautBaissac/rails_ai_agents
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ThibautBaissac/rails_ai_agents "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/performance-optimization" ~/.claude/skills/thibautbaissac-rails-ai-agents-performance-optimization && rm -rf "$T"
manifest: .claude/skills/performance-optimization/SKILL.md
source content

Performance Optimization for Rails 8

Overview

Performance optimization focuses on:

  • N+1 query detection and prevention
  • Query optimization
  • Memory management
  • Response time improvements
  • Database indexing

Quick Start

# Gemfile
group :development, :test do
  gem 'bullet'           # N+1 detection
  gem 'rack-mini-profiler' # Request profiling
  gem 'memory_profiler'  # Memory analysis
end

N+1 Query Detection and Prevention

N+1 queries occur when code loads a collection then makes a separate query for each associated record. The Bullet gem detects these automatically. Fix them with eager loading via

includes
,
preload
, or
eager_load
.

Eager Loading Decision Table

MethodUse When
includes
Most cases (Rails chooses best strategy)
preload
Forcing separate queries, large datasets
eager_load
Filtering on association, need single query
joins
Only need to filter, don't need association data

Key patterns: Bullet configuration, eager loading methods, scoped eager loading, counter caches, N+1 specs with query count assertions.

See references/n-plus-one.md for all code examples and patterns.

Query Optimization

Optimize queries by selecting only needed columns, using batch processing for large datasets, and choosing efficient existence checks.

Key Patterns

PatternBadGood
Column selection
User.all.map(&:name)
User.pluck(:name)
Large iterations
Event.all.each { ... }
Event.find_each { ... }
Existence checks
.any?
/
.present?
.exists?
Collection size
.length
(loads all)
.size
(smart)

Database Indexing

Add indexes for: foreign keys, columns in WHERE/ORDER BY/JOIN clauses, and unique constraints. Use composite indexes for multi-column queries. Use partial indexes for filtered subsets.

Query Analysis

Use

Event.where(...).explain(:analyze)
to inspect query plans. Set up slow query logging via
ActiveSupport::Notifications
to catch queries over a threshold.

See references/query-optimization.md for all code examples and patterns.

Memory Management and Profiling

Use

memory_profiler
to detect memory issues. Prefer
pluck
over loading full AR objects, use
find_each
for streaming, and use
update_all
/
in_batches
for bulk operations.

Rack Mini Profiler

Provides per-request profiling in development. Shows query count, timing, and flamegraphs (with

stackprof
gem). Access via the profiler badge or
?pp=flamegraph
.

See references/memory-and-profiling.md for all code examples and patterns.

Quick Fixes Reference

ProblemSolution
N+1 on belongs_to
includes(:association)
N+1 on has_many
includes(:association)
Slow COUNTAdd counter_cache
Loading all columnsUse
select
or
pluck
Large dataset iterationUse
find_each
Missing index on FKAdd index on
*_id
columns
Slow WHERE clauseAdd index on filtered column
Loading unused associationsRemove from
includes

Performance Checklist

  • Bullet enabled in development/test
  • No N+1 queries in critical paths
  • Foreign keys have indexes
  • Counter caches for frequent counts
  • Eager loading in controllers
  • Batch processing for large datasets
  • Query analysis for slow endpoints

Workflow

  1. Detect -- Enable Bullet, run specs, check Rack Mini Profiler
  2. Analyze -- Use
    explain(:analyze)
    , check slow query logs, profile memory
  3. Fix -- Apply the appropriate pattern from the reference files
  4. Verify -- Re-run specs, confirm query counts, check profiler

Reference Files