See where every Rails request spends its time.

Rails Profiler adds a debug toolbar to every page of your app in development, keeps a profile of each request, and shows its SQL with N+1 detection and a flame graph of its timeline. Its MCP server lets your AI assistant read the same profiles.

Install itRuby 3.0 and Rails 7.0 or later, MIT license

  • GET /orders
  • app.myapp.test
  • 200
  • 240 ms
  • 12 SQL queries
  • Controller
  • View
  • Partial
  • SQL
  • Cache
  • HTTP
  • Custom
  • Repeated query (N+1)
An illustration with invented data of the flame graph in the Timeline tab. Each bar is an event of a 240 ms GET /orders request, nested under the event that triggered it and sized by its duration. The controller reads the database and the cache, waits 62 ms on an outbound HTTP call to rates.myapp.test and runs a custom pricing.apply_discounts block. The view then renders a collection of 10 orders that loads each customer with its own query: the same SELECT runs 10 times, the N+1 pattern the profiler flags.

What it shows you

A toolbar on every page

A bar fixed to the bottom of every HTML page gives the request at a glance: status, duration, SQL queries and their time, views and partials, cache hit rate, outbound HTTP calls, logs, jobs and mails. Hover an item for the details, click it to open the matching tab of the full profile at /_profiler.

SQL, with N+1 detection

The Database tab lists every query with its time and model, bind values replaced by ?. When the same query runs three times or more, it is grouped and flagged as N+1, with the call stack that ran it. Read-only queries can be explained in place, inside a transaction that is always rolled back.

A flame graph of the request

The Timeline tab nests every instrumented event (controller, views, SQL, cache, HTTP) by time, so the slow part stands out. Wrap your own code in Profiler.measure to add it to the graph. Below it, function profiling shows the Ruby methods the request spent its time in, sampled with the optional stackprof gem or traced in full.

Profiles your AI assistant can read

The bundled MCP server gives Claude or any other MCP client 21 tools and 7 resources, over stdio or HTTP. Ask why a page is slow: the assistant finds the request, reads its queries and spots the N+1 itself, instead of you pasting SQL and logs into the conversation. From the root of your app, with Claude Code:

claude mcp add rails-profiler -- bundle exec rake profiler:mcp

Also recorded

Every request, job, console expression and test gets its own profile, opened tab by tab in the dashboard. Beyond SQL and the timeline, the profiler records:

A Chrome DevTools extension adds a Rails Profiler panel that lists the profiled requests of the page you are browsing, and opens the profile of each one right in DevTools.

Install

  1. Add the gem to your Gemfile, then run bundle install. The library is named profiler: without the require, Bundler loads nothing of the gem.

    gem "rails-profiler", require: "profiler"
  2. Mount the dashboard in config/routes.rb:

    Rails.application.routes.draw do
      mount Profiler::Engine, at: '/_profiler' if Rails.env.development?
    end
  3. Open any page of your app in development: the toolbar is at the bottom, and /_profiler lists every profile. For function profiling in its default mode, also add gem "stackprof", require: false.

Out of the box it runs in development and test only, lets in requests from your own machine only, and masks your filter_parameters before anything is stored.

What it costs: measured with the repository's benchmark script on Ruby 3.4.6, on a synthetic page, the profiler adds 5.3 to 5.8 ms per request with function profiling off.