Ruby
Version 0.1.0 Community February 2026
Note: This document is for agents and LLMs to follow when writing, reviewing, or refactoring ruby codebases. Humans may also find it useful, but guidance here is optimized for automation and consistency by AI-assisted workflows.
Abstract
Comprehensive performance optimization guide for Ruby applications, designed for AI agents and LLMs. Contains 42 rules across 8 categories, prioritized by impact from critical (object allocation, collection enumeration) to incremental (runtime configuration). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.
Table of Contents
- Object Allocation — CRITICAL
- 1.1 Avoid Repeated Computation in Hot Paths — MEDIUM-HIGH (eliminates redundant allocations from repeated to_s, to_a, Time.now)
- 1.2 Avoid Temporary Array Creation — HIGH (eliminates N intermediate allocations per iteration)
- 1.3 Avoid Unnecessary Object Duplication — CRITICAL (eliminates redundant allocations in hot paths)
- 1.4 Freeze Constant Collections — CRITICAL (prevents repeated allocation of identical objects)
- 1.5 Reuse Buffers in Loops — MEDIUM-HIGH (reduces allocations from O(n) to O(1))
- 1.6 Use Lazy Initialization for Expensive Objects — HIGH (defers allocation until needed, reduces startup overhead)
- Collection & Enumeration — CRITICAL
- 2.1 Avoid Recomputing Collection Size in Conditions — MEDIUM (O(n) to O(1) per check for non-Array enumerables)
- 2.2 Use each_slice for Batch Processing — MEDIUM (O(batch) memory vs O(n) for full dataset)
- 2.3 Use each_with_object Over inject for Building Collections — MEDIUM (eliminates common accumulator-return bugs and improves readability)
- 2.4 Use flat_map Instead of map.flatten — HIGH (eliminates intermediate nested array allocation)
- 2.5 Use Lazy Enumerators for Large Collections — CRITICAL (processes elements on demand, avoids loading entire collection)
- 2.6 Use Single-Pass Collection Transforms — CRITICAL (eliminates N intermediate arrays from chained methods)
- I/O & Database — HIGH
- 3.1 Avoid Database Queries Inside Loops — HIGH (reduces N queries to 1 bulk query)
- 3.2 Cache Expensive Database Results — MEDIUM (eliminates repeated identical queries across requests)
- 3.3 Eager Load ActiveRecord Associations — HIGH (eliminates N+1 queries, reduces from 2N+1 to 3 queries)
- 3.4 Select Only Needed Columns — HIGH (reduces memory allocation and query transfer time by 50-90%)
- 3.5 Size Connection Pools to Match Thread Count — MEDIUM (prevents connection checkout timeouts under load)
- 3.6 Stream Large Files Line by Line — MEDIUM-HIGH (O(1) memory vs O(n) — saves GBs on large files)
- 3.7 Use find_each for Large Record Sets — HIGH (O(1000) memory vs O(n) for entire table)
- String Handling — HIGH
- 4.1 Chain gsub Calls into a Single Replacement — MEDIUM (reduces N string allocations and regex scans to 1)
- 4.2 Enable Frozen String Literals — HIGH (reduces GC pressure by ~20%, saves ~100MB in production Rails apps)
- 4.3 Use Shovel Operator for String Building — HIGH (reduces N string allocations to 0 in loops)
- 4.4 Use String Interpolation Over Concatenation — MEDIUM-HIGH (single allocation vs N intermediate strings)
- 4.5 Use Symbols for Identifiers and Hash Keys — MEDIUM (1.3-2x faster hash lookups, single allocation per symbol)
- Method & Dispatch — MEDIUM-HIGH
- 5.1 Avoid Dynamic send in Performance-Critical Code — MEDIUM (send bypasses visibility checks and prevents YJIT optimization)
- 5.2 Avoid method_missing in Hot Paths — MEDIUM-HIGH (method_missing is 2-10x slower than direct dispatch)
- 5.3 Cache Method References for Repeated Calls — MEDIUM-HIGH (avoids repeated method lookup and Proc allocation overhead)
- 5.4 Pass Blocks Directly Instead of Converting to Proc — MEDIUM (avoids Proc allocation on each call)
- 5.5 Reduce Method Chain Depth in Hot Loops — MEDIUM (reduces N × depth dispatch calls to N × 1)
- Data Structures — MEDIUM
- 6.1 Preallocate Arrays When Size Is Known — LOW-MEDIUM (avoids repeated resizing and memory copies)
- 6.2 Use Hash Default Values Instead of Conditional Assignment — LOW-MEDIUM (eliminates conditional branches and simplifies accumulation)
- 6.3 Use Set for Membership Tests — MEDIUM (O(1) lookup vs O(n) with Array#include?)
- 6.4 Use sort_by Instead of sort with Block — MEDIUM (2-5x faster for large collections via Schwartzian transform)
- 6.5 Use Struct Over OpenStruct — MEDIUM (Struct is 10-50x faster to instantiate than OpenStruct)
- Concurrency — MEDIUM
- 7.1 Avoid Shared Mutable State Between Threads — MEDIUM (prevents race conditions and eliminates mutex contention overhead)
- 7.2 Size Thread Pools to Match Workload — MEDIUM (prevents GVL contention and resource exhaustion)
- 7.3 Use Fibers for I/O-Bound Concurrency — MEDIUM (reduces memory 250x per concurrent task (~4KB vs ~1MB))
- 7.4 Use Ractors for CPU-Bound Parallelism — MEDIUM (2-8x throughput improvement on multi-core for CPU-bound work)
- Runtime & Configuration — LOW-MEDIUM
- 8.1 Enable YJIT for Production — MEDIUM (15-25% latency reduction with zero code changes)
- 8.2 Optimize Require Load Order — LOW (reduces boot time by deferring heavy gem loading)
- 8.3 Set Frozen String Literal as Project Default — LOW-MEDIUM (reduces string allocations across entire codebase)
- 8.4 Tune GC Parameters for Your Workload — LOW-MEDIUM (reduces GC pause frequency by 30-50% for known allocation patterns)
References
- https://docs.ruby-lang.org
- https://github.com/rubocop/ruby-style-guide
- https://ruby-style-guide.shopify.dev
- https://shopify.engineering/ruby-yjit-is-production-ready
- https://railsatscale.com/2025-01-10-yjit-3-4-even-faster-and-more-memory-efficient/
- https://www.datadoghq.com/blog/ruby-performance-optimization/
- https://guides.rubyonrails.org/active_record_querying.html
- https://blog.appsignal.com/2021/11/17/practical-garbage-collection-tuning-in-ruby.html
- https://pragprog.com/titles/adrpo/ruby-performance-optimization/
- https://github.com/fastruby/fast-ruby
Source Files
This document was compiled from individual reference files. For detailed editing or extension:
| File | Description |
|---|---|
| references/_sections.md | Category definitions and impact ordering |
| SKILL.md | Quick reference entry point |
| metadata.json | Version and reference URLs |