How to monitor Ruby on Rails

Monitor a Rails app with an uptime check on the built-in /up route and key pages, error tracking through sentry-ruby, traces for slow actions and queries via OpenTelemetry, and the server agent for Puma, memory and logs. Watch the connection pool for ActiveRecord::ConnectionTimeoutError, and Sidekiq separately if you use it.

Updated · by PuzariCloud · commands checked against current releases

What can go wrong with Ruby on Rails

  • Pending migrations. Code deployed before db:migrate: in development Rails raises ActiveRecord::PendingMigrationError; in production, queries against missing columns raise and return 500.
  • Connection pool exhausted. More threads than pool in database.yml: requests wait and then fail with ActiveRecord::ConnectionTimeoutError ("could not obtain a connection from the pool").
  • Puma request queueing. All threads busy on slow requests; new requests wait in the backlog and latency grows for everyone.
  • Memory bloat. Ruby processes grow over time with fragmentation; workers get OOM-killed or swap.
  • /up stays green. Rails 7.1's /up returns 200 when the app boots; it does not check the database.

The signals that matter, with alert thresholds

SignalAlert whenWhy it matters
/up and key pagesnon-2xx twice, or p95 > 1 sWhat users see.
ConnectionTimeoutErroranyPool too small for the thread count.
Exceptionsnew issue, or a spike after a deployBugs.
Slow actions and queriesnew entries at the topN+1, missing indexes.
Memory per Puma workersteady growthBloat or leak.
Puma servicenot activeDown.

Thresholds are starting points. Tune them after a week of data: an alert nobody acts on should be raised or removed.

How to check Ruby on Rails by hand

Health route
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/up
Migrations not yet run
bin/rails db:migrate:status | grep -w down
Connection pool state
bin/rails runner 'p ActiveRecord::Base.connection_pool.stat'
Pool timeouts in the log
grep -c ConnectionTimeoutError log/production.log

How to watch Ruby on Rails with Vigil

  1. In New monitor add an Uptime monitor on /up and on a page that reads from the database (or an App health monitor on a JSON endpoint that checks the DB and Redis).
  2. Create a project under Errors and use its DSN with sentry-ruby and sentry-rails; set the release so regressions are tied to deploys.
  3. For traces, use the OpenTelemetry Ruby SDK with opentelemetry-instrumentation-all and the OTLP endpoint (quick start). Actions get latency histograms; queries are ranked by total time with N+1 detection.
  4. Install the server agent, add the Puma unit to the services to watch, ship log/production.log, and add a log_watch for ConnectionTimeoutError with a limit of 1.
  5. Using Sidekiq? Follow how to monitor Sidekiq for queues, retries and the dead set.

Every alert goes to the channels you pick: email, Slack, Telegram, Discord, Microsoft Teams, Pushover, webhooks or on-call paging. Failures are confirmed by a second check before anyone is woken up.

Ruby on Rails monitoring FAQ

Why isn't /up enough?

It proves the app boots, not that it can reach the database, Redis or anything else. Use it for uptime and add a check that exercises the database.

How big should the database pool be?

At least the number of Puma threads per process (RAILS_MAX_THREADS), plus any threads you start yourself. Sidekiq needs its own pool sized to its concurrency.

Can I see slow queries without APM?

Yes, from the database side: enable pg_stat_statements and the agent's database monitoring lists the top queries by total time. APM adds which action ran them.

Vigil by PuzariCloud

Watch Ruby on Rails without stitching five tools together

Uptime and API checks, heartbeats, server and database metrics, traces, errors and logs in one place, with one incident and one alert when something breaks. Every feature is on every plan, including Free.