Performance monitoring that lives inside your Rails app. Slow requests, N+1 queries, background jobs and exceptions, stored in your own database. No agent, no account, no data leaving your servers.
Rails Pulse is a Rails engine. It hooks into the instrumentation Rails already emits, writes what it sees to a handful of tables, and mounts a dashboard that shows you where the time went. Install the gem, run one migration, schedule two jobs, and you have monitoring that works the same on SQLite, PostgreSQL and MySQL.
- The state of the app in one screen. A health bar counts healthy, slow and critical routes, queries, jobs and exception groups. A ranked "needs attention" list tells you what to fix first.
- Every request, broken down. Each request stores its route, status, duration and a timeline of the SQL, view, cache, HTTP, mailer and Active Storage operations inside it.
- Queries you can act on. SQL is normalised and fingerprinted, so you see execution counts and P95 per statement shape, N+1 patterns, an EXPLAIN plan and index suggestions.
- Jobs and exceptions in the same place. Duration, queue wait and failure rate for every Active Job class on any adapter. Unhandled exceptions from requests and jobs grouped by class and location, with filtered params and backtraces.
- Numbers over time. Hourly, daily, weekly and monthly summaries with P50, P95 and P99, your service level objectives drawn as lines on the charts, and a marker for every deploy so a regression lines up with the release that caused it.
- Built for production. Tracking is queued off the request thread and dropped rather than blocked under load. If the gem is deployed before its migrations, tracking pauses and tells you what to run. Retention is enforced by age and by row count so the tables never grow without bound.
- Your coding agent can read it. A read-only JSON API, a
rails-pulseCLI and an MCP server give Claude Code, Codex, Cursor or a CI script the same data: the slowest endpoints since the last deploy, the queries behind them, the jobs that failed. Ask the agent why checkout got slow and it can go and look.
A request and where its time went |
Diagnostics and an index suggestion for one query |
One route over two weeks, with objective lines and deploy markers |
|
# Gemfile
gem "rails_pulse"bundle install
rails generate rails_pulse:install
rails db:migrate# config/routes.rb
mount RailsPulse::Engine => "/rails_pulse"Schedule the summary job hourly and the cleanup job daily with whatever your queue adapter provides. With Solid Queue:
# config/recurring.yml
production:
rails_pulse_summary:
class: RailsPulse::SummaryJob
schedule: "5 * * * *"
rails_pulse_cleanup:
class: RailsPulse::CleanupJob
schedule: "0 1 * * *"Open http://localhost:3000/rails_pulse. That's the whole setup.
Requirements: Ruby 3.2+, Rails 7.2+ (tested on 7.2, 8.0 and 8.1), SQLite, PostgreSQL or MySQL.
Full install guide, including a separate database and plain cron: railspulse.com/documentation/installation
Lock it down. The dashboard is authenticated by default outside development and test. Point it at your own auth with a predicate; anything but true is a 403.
RailsPulse.configure do |config|
config.authorize = ->(controller) { controller.current_user&.admin? }
endWith nothing configured it falls back to HTTP Basic against RAILS_PULSE_USERNAME and RAILS_PULSE_PASSWORD. Authentication guide
Tune it. Thresholds for slow, very slow and critical, service level objectives per percentile, what to ignore, what to tag, how long to keep. All in config/initializers/rails_pulse.rb. Configuration reference
Run the dashboard on its own. bundle exec rails_pulse_server serves the UI from a separate process with its own health endpoint, so a slow report never competes with your app for a thread. Deployment modes
Mark your deploys. rails rails_pulse:record_deployment[sha] from a release script, or POST /rails_pulse/deployments with the API token from CI, and every chart draws a line at that moment.
Brief your agent. Set config.api_token, then on your machine:
rails-pulse configure # URL and token, saved to ~/.rails-pulse
rails-pulse routes list --since 2026-06-01T00:00:00Z
rails-pulse install claude # Claude Code skill: when and how to use the toolsAdd gem "mcp" to your Gemfile (a development group is enough), register rails-pulse mcp as an MCP server, and the agent gets eleven read-only tools: routes, slow requests, errors, exception groups and their backtraces, one endpoint in depth, expensive and N+1 queries, job health, deployments and whether each one made things worse, what needs attention and whether your thresholds fit, and what has actually been recorded. Nothing the agent can call changes production. Agent tooling
Keep it in its own database. rails generate rails_pulse:install --database=separate puts the tables somewhere your primary never has to vacuum. Database setup
bundle update rails_pulse
rails generate rails_pulse:upgrade
rails db:migrate # separate Pulse database: rails db:migrate:rails_pulse
rails rails_pulse:status # exits 1 while anything still needs actionUpgrading from 0.3.x to 0.4? Back up first, run rails rails_pulse:migrate_routes after migrating, and restart every process together. The details are in the changelog.
Bug reports and pull requests are welcome on GitHub. docs/ explains how the pieces fit and why they are built the way they are. Building on top of Rails Pulse (a plugin, scripting the CLI)? docs/api.md states what's public and stable across minor releases.
git config core.hooksPath .githooks # once, after cloning
DB=sqlite3 rake test # or DB=postgresql / DB=mysql2
bundle exec rubocopAvailable as open source under the MIT License.
