Integration · Ruby

End-to-end Ruby monitoring for faster root cause analysis

Add two OpenTelemetry gems and Obseria traces every Rails request and Sidekiq job, links slow queries, Redis calls and GC pressure, and shows the root cause of a slowdown.
Obseria apps and capabilities: observability, APM, infrastructure and integrations
Obseria home dashboard with service health, open problems, SLO compliance and ingestion
Obseria trace explorer with span list and span attributes
Overview

Why monitor Ruby with Obseria

One initializer, full coverage

opentelemetry-instrumentation-all instruments Rails, ActiveRecord, Sidekiq, Redis, Net::HTTP and many more gems through a single use_all call.

Web requests and jobs in one trace

Trace context travels from the Rails controller through Redis into the Sidekiq worker, so background jobs are no longer a blind spot.

From symptom to cause

Obseria Intelligence correlates a latency spike with the deploy, the slow SQL statement or the saturated Puma pool that caused it.

Coverage

Ruby frameworks and libraries Obseria monitors

  • Ruby on Rails. Controllers, Action View rendering, Active Job and Action Cable appear as spans with route and status code.
  • ActiveRecord, pg and mysql2. Every SQL statement becomes a client span, so N+1 queries are visible in the trace waterfall.
  • Sidekiq and Active Job. Enqueue and perform spans connect web requests with the workers that process them, including queue latency.
  • Puma, Rack and Sinatra. Rack middleware creates server spans for any Rack-based app, and Puma thread usage is tracked as metrics.
  • Redis, Faraday and Net::HTTP. Cache calls and outbound HTTP requests carry W3C trace context to downstream services.
  • CRuby runtime. Heap slots, GC runs and process memory show how the interpreter behaves under real traffic.
At a glance

The Ruby signals that matter

Obseria collects these values automatically and shows them in ready-made dashboards and alerts.

Response speed and errors

Shows how quickly your Ruby application answers visitors and how often a page ends in an error instead of a result.

  • ruby_http_request_duration_seconds
  • ruby_http_requests_total

Capacity and database access

Tells you whether the application has enough free workers and database connections to serve everyone without waiting.

  • ruby_puma_busy_threads
  • ruby_active_record_connection_pool_waiting

Background jobs

Reveals whether tasks like sending emails or invoices run on time or pile up and fail in the background.

  • ruby_sidekiq_queue_latency_seconds
  • ruby_sidekiq_failed_jobs_total

Memory usage

Shows how much memory the application holds and how often it cleans up, so growing usage is caught before a crash.

  • ruby_heap_live_slots
  • ruby_major_gc_ops_total
  • ruby_rss
Show all 9 metrics in detail
MetricUnitWhat it tells you
ruby_http_request_duration_secondssTime Rails spends per request, the core latency signal per controller and action.
ruby_http_requests_total{request}Request count by status code, the basis for throughput and error rate.
ruby_puma_busy_threads{thread}Puma threads currently serving requests; near the maximum means requests start to queue.
ruby_active_record_connection_pool_waiting{thread}Threads waiting for a database connection, a direct sign of an undersized pool.
ruby_sidekiq_queue_latency_secondssAge of the oldest job per queue; rising values mean workers cannot keep up.
ruby_sidekiq_failed_jobs_total{job}Failed Sidekiq jobs per worker class, to catch broken jobs after a deploy.
ruby_heap_live_slots{slot}Live object slots on the Ruby heap; steady growth points to retained objects.
ruby_major_gc_ops_total{run}Major garbage collections; frequent full GCs cost CPU and add latency.
ruby_rssByResident memory of the Ruby process, to spot bloat before the container is killed.
Setup

Set up Ruby monitoring in minutes

  1. Step 1

    Add the gems

    Add opentelemetry-sdk, opentelemetry-exporter-otlp and opentelemetry-instrumentation-all to your Gemfile and run bundle install.

  2. Step 2

    Create the initializer

    Call OpenTelemetry::SDK.configure with use_all in config/initializers/opentelemetry.rb; endpoint and token come from OTEL_* variables.

  3. Step 3

    Add runtime metrics

    Expose Puma, Sidekiq and GC metrics with the prometheus_exporter gem and let the Obseria Agent or OpenTelemetry Collector scrape them.

Example configuration · RUBY
# Gemfile
gem "opentelemetry-sdk"
gem "opentelemetry-exporter-otlp"
gem "opentelemetry-instrumentation-all"

# config/initializers/opentelemetry.rb
require "opentelemetry/sdk"
require "opentelemetry/exporter/otlp"
require "opentelemetry/instrumentation/all"

# Environment (set in your deployment):
#   OTEL_SERVICE_NAME=storefront
#   OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production
#   OTEL_EXPORTER_OTLP_ENDPOINT=${OBSERIA_OTLP_ENDPOINT}
#   OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20${OBSERIA_TOKEN}
OpenTelemetry::SDK.configure do |c|
  c.use_all # Rails, ActiveRecord, Sidekiq, Redis, Net::HTTP, Faraday ...
end

Out of the box

Dashboards, alerts and SLOs that are ready the moment data arrives.

  • Rails service health with RED metrics per action
  • Sidekiq queues: latency, backlog, failures
  • Alert on Puma thread saturation
  • Alert on Sidekiq queue latency above threshold
  • Slowest ActiveRecord queries by endpoint
Guide

Ruby monitoring: what matters

Why Ruby monitoring matters

Ruby on Rails powers online shops, SaaS products and internal tools that teams want to ship quickly. That speed comes with a runtime that needs attention in production: Puma serves requests with a fixed number of threads, ActiveRecord hides SQL behind convenient methods, and much of the real work runs asynchronously in Sidekiq. When a page gets slow, the cause can sit in any of these layers. Ruby monitoring connects them, so you see whether time is lost in your code, in the database, in Redis or in a job queue.

OpenTelemetry Ruby provides tracing that is marked stable and a large set of instrumentation gems. The meta gem opentelemetry-instrumentation-all pulls them in, and a single use_all call activates instrumentation for every supported library found in your bundle. That makes Ruby APM possible without a proprietary agent and without changing application code.

Signals that matter for Ruby performance monitoring

A useful Ruby performance monitoring setup combines traces with a short list of runtime and queue metrics:

  • Request latency and errors: server spans per controller action and ruby_http_request_duration_seconds give the RED view. Error spans carry the exception class and stack trace.
  • Puma capacity: ruby_puma_busy_threads compared with the configured maximum shows when requests start to wait for a free thread.
  • Database pool: ruby_active_record_connection_pool_waiting reveals threads that block before the query even starts.
  • Sidekiq: ruby_sidekiq_queue_latency_seconds and ruby_sidekiq_failed_jobs_total tell you whether background work is on time and healthy.
  • Memory and GC: ruby_heap_live_slots, ruby_major_gc_ops_total and ruby_rss show allocation pressure and memory bloat.

OpenTelemetry metrics for Ruby are still in development, so runtime, Puma and Sidekiq metrics are best collected with the widely used prometheus_exporter gem and scraped into Obseria next to the traces.

Common Rails and Sidekiq problems and how to detect them

N+1 queries

A list view that loads associations one by one issues dozens of nearly identical SQL statements. In the trace waterfall this appears as a long ladder of short ActiveRecord spans under one request. Grouping spans by statement makes the pattern obvious.

Thread and pool saturation

If the ActiveRecord pool is smaller than the number of Puma threads plus Sidekiq concurrency, threads queue for connections. You see waiting threads, flat CPU and rising latency at the same time.

Growing Sidekiq backlogs

A slow external API or a new, expensive job can let queues grow for hours. Alerting on queue latency rather than queue size catches delays that customers notice, such as late emails or invoices.

Memory bloat

Ruby processes that allocate many objects grow their heap and rarely give memory back. Rising ruby_rss and frequent major GCs after a release point to the code path to profile.

Regressions after a release

A new gem version or a changed scope can make one endpoint slower without any error. Comparing latency and query counts per service.version right after a deploy separates real regressions from noise and tells you which release to roll back.

Best practices for Ruby on Rails monitoring

  1. Set service.name, service.version and deployment.environment.name for web and worker processes separately, so Puma and Sidekiq appear as distinct services.
  2. Start with use_all, then disable instrumentations you do not need to keep span volume focused.
  3. Size the database pool from Puma threads and Sidekiq concurrency, and alert on waiting threads.
  4. Write trace IDs into Rails logs so every error log line leads to its trace.
  5. Use tail-based sampling to keep every slow or failed request and job.

How Obseria helps with Ruby APM

Obseria receives OpenTelemetry Ruby traces over OTLP and scrapes Prometheus metrics from your Ruby processes through the Obseria Agent or the OpenTelemetry Collector. TopoGraph maps Rails apps, Sidekiq workers, PostgreSQL and Redis automatically. When latency rises, Obseria Intelligence checks deploys, slow statements, pool saturation and queue delays and presents the root cause with its chain of evidence. Dashboards, alerts and SLOs are included, and all data stays exportable via OTLP.

Ruby monitoring FAQ

No. You add three gems and an initializer that calls use_all. Rails, ActiveRecord, Sidekiq, Redis and HTTP clients are instrumented automatically. Custom spans for business logic are optional.

The OpenTelemetry Ruby SDK supports CRuby 3.1 and newer, as well as recent JRuby and TruffleRuby releases. Check the instrumentation gem documentation for framework-specific version ranges.

The Sidekiq instrumentation creates enqueue and perform spans linked to the originating request. For queue latency, backlog and failure counts, add the Sidekiq collectors of the prometheus_exporter gem.

Tracing in OpenTelemetry Ruby is stable, while metrics and logs are still in development. That is why we recommend Prometheus-based runtime metrics for Ruby today; Obseria stores both side by side.

Yes. Deploy the Obseria Agent as a DaemonSet via Helm and set the OTEL_* variables in your pod spec. Traces are enriched with pod, namespace and node metadata.

Start monitoring Ruby today

Connect Ruby in minutes with OpenTelemetry or the Obseria Agent. Free for 14 days.