The project is in a healthy, maintained state
A Rack middleware captures object allocations per request using GC.stat diffs and stores them in a thread-safe ring buffer. Results are served through a mountable engine with a sortable, filterable dashboard — filling the gap between the memory_profiler gem and having nowhere useful to view results in a Rails app.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

RailsMemoryProfiler

CI Gem Version Gem Downloads Ruby Rails codecov

Per-request memory allocation reports with a mountable dashboard UI. Fills the gap between the memory_profiler gem (terminal-only output, manual block wrapping) and having nowhere useful to browse results in a Rails app.

A Rack middleware captures object allocations for every request using GC.stat diffs. Results are stored in a thread-safe ring buffer and served through a mountable engine with a sortable, filterable dashboard.


Table of Contents

  • Installation
  • Dashboard
  • Configuration
  • Compatibility
  • Contributing
  • License

Installation

Add to your Gemfile:

gem "rails_memory_profiler", group: :development

Run the install generator:

bundle exec rails generate rails_memory_profiler:install

This creates config/initializers/rails_memory_profiler.rb with all options documented and prints mount instructions.

Mount the dashboard in config/routes.rb:

mount RailsMemoryProfiler::Engine, at: "/rails/memory"

Then visit /rails/memory/reports to see per-request allocation data.

↑ Back to top


Dashboard

The index view shows a sortable table of captured requests. Click any row to open the detail view for that request.

Columns: Path, Controller#Action, Allocated Objects (colour-coded), Retained Objects, Duration (ms), Recorded At.

Use the controller filter to narrow the table down to a specific controller without a page reload.

↑ Back to top


Configuration

All options and their defaults:

Option Default Description
enabled true in development Enable/disable request profiling
sample_rate 1 Profile every Nth request (1 = every request)
store_size 100 Max reports in the ring buffer; oldest are evicted when full
dashboard_enabled true in development Enable the dashboard endpoint
min_allocated_objects 0 Skip requests that allocate fewer objects than this
ignore_paths [] Additional paths to skip — strings (prefix) or regexes (the dashboard's own mount path is auto-ignored)
ignore_controllers [] Controller names to skip (e.g. "rails/health")
detailed_reports false Capture full MemoryProfiler.report breakdowns; requires gem "memory_profiler" in your Gemfile
detailed_sample_rate 10 When detailed_reports is enabled, capture a full report every Nth profiled request
notifiers [] Array of objects responding to #call(report); called after each report is stored
log_file nil Path to append JSON-serialized reports (one per line); shortcut for Notifiers::FileLogger
raise_on_allocation_spike nil Raise AllocationSpikeError when allocated_objects exceeds this threshold

Example:

RailsMemoryProfiler.configure do |config|
  config.sample_rate           = 5
  config.min_allocated_objects = 1_000
  config.ignore_paths          = ["/up"]   # dashboard mount path is auto-ignored
  config.ignore_controllers    = ["rails/health"]
  config.notifiers             = [RailsMemoryProfiler::Notifiers::Console.new]
  config.log_file              = Rails.root.join("log/memory_profiler.jsonl")
end

Test helpers

# Plain Ruby / shared utility
require "rails_memory_profiler/test_helper"

count = RailsMemoryProfiler::TestHelper.capture_allocations { MyClass.new }
RailsMemoryProfiler::TestHelper.assert_allocations_below(500) { MyClass.new }
# raises Minitest::Assertion when Minitest is loaded, RuntimeError otherwise

# Minitest — adds assert_allocates_fewer_than to all Minitest::Test subclasses
require "rails_memory_profiler/minitest_matchers"

assert_allocates_fewer_than(500) { MyClass.new }
assert_allocates_fewer_than(500, "MyClass allocates too much") { MyClass.new }

# RSpec
require "rails_memory_profiler/rspec_matchers"

expect { MyClass.new }.to allocate_fewer_than(500)

↑ Back to top


Compatibility

Ruby 3.3 Ruby 3.4 Ruby 4.0
Rails 7.1
Rails 8.x

↑ Back to top


Contributing

Bug reports and pull requests are welcome. See CONTRIBUTING.md for guidelines.

↑ Back to top


License

The gem is available as open source under the terms of the MIT License.

↑ Back to top