rack-mini-profiler: a speed badge on every HTML page from one Rack middleware
Profiler for your development and production Ruby rack apps.
At a glance
- What is it?
- The oldest still-maintained Ruby profiler in wide use puts per-request timings, SQL counts, flamegraphs and memory stats into a corner of your HTML, in development and in production.
- Who is it for?
- rack-mini-profiler is at its best as a first look at a slow page rather than as a profiler you settle into. The speed badge tells you which requests deserve attention in about a second of effort, the SQL panel names the ORM calls behind a slow action, and the flamegraph and memory views exist for when the badge has already told you where to look.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 52 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One line in the Gemfile buys you a speed badge
The installation section is one gem line, and the surrounding sentence sets the version floor the README wants:
gem 'rack-mini-profiler'For Rails, the README says that is the whole of it in development. For a plain Rack application you insert the middleware yourself, which the README shows with a lambda that returns a 200 and a body:
require 'rack-mini-profiler'
home = lambda { |env|
[200, {'Content-Type' => 'text/html'}, ["<html><body>hello!</body></html>"]]
}
builder = Rack::Builder.new do
use Rack::MiniProfiler
map('/') { run home }
end
run builderThe Sinatra version is the same idea in one line, `use Rack::MiniProfiler` inside the class body. So the shape is consistent across frameworks: it is Rack middleware, and anywhere you can insert Rack middleware you can insert this.
The badge renders into HTML pages only, which is the project's main constraint and also its main appeal. There is no separate dashboard and no agent to deploy. You look at results by loading the page you were already debugging, and the numbers arrive in the corner of the response. That makes it very cheap to leave switched on, and the README is explicit that it is designed to work in production as well as development, which is unusual for a profiler that patches your drivers.
Where the README and the 4.0.0 release notes disagree about Ruby
The README says to add the gem in Ruby 3.2 and later. The 4.0.0 release, published on 2025-06-10, opens with a breaking change line that says Ruby version 3.1.0 or later is required. Those are different floors, and neither one is wrong on its face: a README updated for the current state of the project can drift above the floor the gemspec actually enforces.
The concrete thing to check is the gemspec. If your application runs on Ruby 3.1 and the badge works, the README's 3.2+ is the stale number. If the bundle refuses to resolve on 3.1, the release notes are the stale number. Ruby versions move slowly enough that this kind of drift can sit unnoticed for a release cycle, which is why it is worth reading rather than assuming.
The rest of the 4.0.0 notes give a better sense of where the project is spending its effort, and the direction is instrumentation rather than user-facing redesign. It implements a prepend patch for Postgres, which connects directly to the patching problems discussed below. It shows Active Record query cache hits in the UI, and it shows record type and count in the SQL query panel. It fixes Rack 3 compatibility by lower-casing HTTP response headers, and it fixes a flamegraph_mode query parameter that had no effect. That last one is a good signal about the project's character: the kind of bug a profiler user hits and files precisely, because they were trying to read the flamegraph in a particular mode and nothing happened.
Ordering in the Gemfile decides whether SQL shows up at all
This is the sharpest edge in the README and the one most likely to waste an afternoon. The note under the install line says to require rack_mini_profiler below the pg and mysql gems in your Gemfile, because the profiler identifies those gems if they are loaded in order to insert instrumentation, and if it is included too early no SQL will show up.
The mechanism is Bundler require ordering, and it means the gem is not self-contained: it has to be positioned relative to your database driver. The README documents the fix as an environment variable rather than a reorder, which is useful when you cannot easily change the Gemfile:
export RACK_MINI_PROFILER_PATCH="pg,mongoid"
# or
export RACK_MINI_PROFILER_PATCH="false"Setting it to false turns ORM patching off entirely, and the README also shows an initializer line for patching a specific set by hand. The supported databases are Mysql2, Postgres, Oracle through oracle_enhanced 1.5.0, and Mongoid 3, with a fallback path to Active Record when a more specific adapter is not present.
The UI changes in 4.0.0 sit on top of exactly this layer. Showing query cache hits in the interface is only possible if you can see which Active Record calls were served from the cache rather than the database, and showing record type and count turns a wall of SQL into something you can actually rank. That is the difference between a profiler that logs queries and one that helps you decide which query to fix.
Monkey patch conflicts with peek and with Net::HTTP
The README has three separate sections on stack level too deep errors, and reading them together tells you more about this gem than any feature list. The Net::HTTP one is the most instructive. If installing Mini Profiler produces SystemStackError from Net::HTTP, the explanation given is that another patch for Net::HTTP#request conflicts with Mini Profiler's patch. The fix is to apply all patches the same way, and Mini Profiler by default aliases the method rather than prepending a module, so the require list has to be adjusted:
gem 'rack-mini-profiler', require: ['prepend_net_http_patch', 'rack-mini-profiler']The reasoning is stated plainly and links to the Ruby bug about a method being patched twice, once by module prepend and once by aliasing. The peek-mysql2 section is the same conflict with a different gem, and the pg section is the same idea for the Postgres driver. Each one has a two-line require fix.
There is also a leftover Rails concern worth knowing about. Prior to version 2.0.0 the profiler patched various Rails methods to get information such as template rendering time. From 2.0.0 it uses ActiveSupport::Notifications instead and patches no Rails methods by default, with the old behaviour available behind an explicit enable_rails_patches require. For manual initialization, the README asks you to declare the gem with require false so the Railtie does not load early, and then to run a generator:
bundle exec rails g rack_mini_profiler:installNone of that is a dealbreaker, but it is a fair amount of ceremony for a profiler, and the ceremony only shows up when something else in your stack also patches. Hanami gets its own note as well, using the Rack integration plus an explicit profile_method call on the partial renderer.
Flamegraphs and memory profiling need extra gems
The feature list at the top of the README covers three separate things: database profiling, call-stack profiling with flamegraphs showing time by gem, and memory profiling with per-request memory usage, GC stats and global allocation metrics. The first is free. The other two are not, and the README is upfront about the cost:
# For memory profiling
gem 'memory_profiler'
# For call-stack profiling flamegraphs
gem 'stackprof'So the flamegraph is really a stackprof rendering, and the memory panel is memory_profiler data. Neither is bundled. The 3.3.0 release added the ability to ignore garbage collection in flamegraphs through a pp query parameter or a flamegraph_ignore_gc config option, which is the sort of control that matters when GC time is drowning out the call stack you were trying to read.
The 3.3.1 release is a maintenance release with two features worth noting for anyone on an older line: support for a dynamic config.content_security_policy_nonce, and a flamegraph path added to the response headers. The nonce one matters for anyone serving the profiler UI from a page with a strict CSP, since an inline script without the right nonce is simply blocked and the UI appears broken for no visible reason.
The README section on flamegraphs begins at the very end of what is written here and points out to the full documentation, so the specifics of mode selection and rendering options live outside the README. The header placement from 3.3.1 gives you a way to get the flamegraph path without digging through the page markup.
Where this project fits against the alternatives
The honest comparison is with stackprof directly, with memory_profiler directly, and with server-side APM tools. rack-mini-profiler bundles the presentation layer that neither of the first two gives you, and that presentation layer is the whole point: a badge you read in a browser while you work, no separate process, no trace to correlate. For a Rails developer trying to answer why one action is slow, that is a much shorter path than learning stackprof's output format.
Against commercial APM the tradeoff is the usual one. Those tools give you history across requests, aggregation, and the ability to compare against last week, none of which a per-request badge gives you. What the badge gives you is immediacy and zero infrastructure. If you need to know whether a regression arrived three days ago, this is the wrong tool, because there is no stored history to look at.
The repository itself is modest and legible. The tree holds lib/, spec/, a gemspec, a Gemfile, a Rakefile, a Guardfile, .rubocop.yml, .rspec, a CHANGELOG.md and a website directory, with a test_old directory that suggests earlier test layout was retired. 3,904 stars and 424 forks indicate something still widely deployed, and the repository is not archived with the last push on 2026-08-21.
One piece of honest disclosure sits in the middle of the README: the maintainers state they have decided to restructure the repository into a central UI repository with separate language implementations, and they ask for help triaging issues. That is a plan for the future of the code, not a shutdown, but it does mean the architecture you read today may not be the architecture a new contributor finds later.
Editorial conclusion
rack-mini-profiler is at its best as a first look at a slow page rather than as a profiler you settle into. The speed badge tells you which requests deserve attention in about a second of effort, the SQL panel names the ORM calls behind a slow action, and the flamegraph and memory views exist for when the badge has already told you where to look. Where it is fussy is monkey patching: the gem wants to sit below your database driver in the Gemfile, it conflicts with peek and with other Net::HTTP patches, and every one of those conflicts is resolved by editing require lists by hand. It has been actively worked on, with the last push on 2026-08-21 and a 4.0.0 release that dropped Ruby below 3.1. Start with the plain gem line in development, turn on the flamegraph only when the badge has already pointed somewhere, and read the version requirement in the gemspec against what your Ruby actually is, since the README and the release notes disagree about it.
Frequently asked questions
What does rack-mini-profiler actually add to a Rails app?
It inserts one Rack middleware that renders a per-request speed badge into HTML responses and, when clicked, a breakdown of SQL calls, custom timing blocks, and optionally flamegraph and memory views. In development the gem line is the entire setup; the generator exists for manual initialization cases.
Why is no SQL showing up in my profiler output?
The README says rack_mini_profiler must be required below pg and mysql in your Gemfile, because it detects those gems as they load in order to insert its instrumentation. Require it too early and no SQL appears. You can also set the RACK_MINI_PROFILER_PATCH environment variable to a comma separated list such as pg,mongoid, or to false to disable ORM patching.
How do I fix SystemStackError stack level too deep after installing the gem?
The README attributes it to a Ruby method being patched twice, once by module prepend and once by method aliasing, and Mini Profiler aliases Net::HTTP#request by default. Requiring prepend_net_http_patch, prepend_pg_patch or prepend_mysql2_patch applies that patch by prepend instead, which is the documented fix for each of those three cases.
Which extra gems do flamegraphs and memory profiling need?
Flamegraphs are rendered from stackprof and the memory panel comes from memory_profiler, so both are optional gems you add yourself. Without them the badge, SQL timings and custom blocks still work. Garbage collection can be excluded from flamegraphs with the pp query parameter or the flamegraph_ignore_gc config option.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/miniprofiler-rack-mini-profiler)