RailsHealthChecks
A Rails engine providing structured, pluggable health check endpoints for monitoring application status. Goes beyond Rails' built-in /up endpoint with per-check diagnostics, latency tracking, and a configurable check registry.
Table of Contents
- Installation
- Endpoints
- Configuration
- Authentication
- Built-in Checks
- Per-Environment Toggling
- Check Groups
- Custom Checks
- Contributing
- License
Installation
Add to your Gemfile:
gem "rails_health_checks"
Then run:
bundle install
Mount the engine in config/routes.rb:
mount RailsHealthChecks::Engine => "/health"
Endpoints
| Endpoint | Format | Use case |
|---|---|---|
GET /health |
JSON | Monitoring dashboards, detailed diagnostics |
GET /health/live |
Plain text | Load balancer liveness probes |
HTTP status is 200 OK when all checks pass, 503 Service Unavailable otherwise.
JSON response shape
{
"status": "ok",
"timestamp": "2026-06-08T20:00:00Z",
"checks": {
"database": { "status": "ok", "latency_ms": 4 }
}
}
Status values: ok | degraded | critical. Overall status is critical if any check is critical, degraded if any is degraded.
Configuration
# config/initializers/rails_health_checks.rb
RailsHealthChecks.configure do |config|
config.checks = [:database, :cache] # checks to run (default: [:database])
config.timeout = 5 # global timeout per check in seconds (default: 5)
end
Authentication
By default health endpoints are public. Use one of the following strategies to restrict access. Unauthenticated requests receive 401 Unauthorized.
Bearer token
RailsHealthChecks.configure do |config|
config.token = ENV["HEALTH_TOKEN"]
end
Requests must include Authorization: Bearer <token>.
IP allowlist
RailsHealthChecks.configure do |config|
config.allowed_ips = ["127.0.0.1", "10.0.0.0/8"] # exact IPs or CIDR ranges
end
Custom block
RailsHealthChecks.configure do |config|
config.authenticate { |request| request.headers["X-Internal"] == "true" }
end
The block receives the ActionDispatch::Request object and must return a truthy value to allow access.
Built-in Checks
| Check | Description |
|---|---|
:database |
ActiveRecord SELECT 1 against the primary connection, includes latency |
:cache |
Rails.cache read/write probe; works with Redis, Memcached, or in-process store |
:sidekiq |
Sidekiq Redis connectivity; optional config.sidekiq_queue_size threshold for queue depth |
:solid_queue |
Solid Queue DB connectivity; optional config.solid_queue_job_count threshold for pending jobs |
:good_job |
GoodJob queue latency; optional config.good_job_latency (seconds) threshold for oldest pending job |
:resque |
Resque Redis connectivity; optional config.resque_queue_size threshold for total queue depth |
:disk |
Free disk bytes via df; optional config.disk_warn_threshold / config.disk_critical_threshold (bytes) and config.disk_path (default: /) |
:memory |
Process RSS via ps; optional config.memory_threshold (bytes) reports degraded when exceeded |
:http |
HTTP GET to config.http_url; reports critical if response code differs from config.http_expected_status (default: 200) or a network error occurs |
Per-Environment Toggling
Disable specific checks in specific environments:
RailsHealthChecks.configure do |config|
config.checks = [:database, :cache, :disk, :memory]
config.disable :disk, in: :test
config.disable :memory, in: [:test, :development]
end
The check is removed from the active list only when Rails.env matches. The in: option accepts a single symbol or an array.
Check Groups
Group related checks and expose them at a dedicated endpoint:
RailsHealthChecks.configure do |config|
config.group :system, [:disk, :memory]
config.group :workers, [:sidekiq, :good_job]
end
| Endpoint | Description |
|---|---|
GET /health/system |
Runs only :disk and :memory, same JSON shape as GET /health |
GET /health/workers |
Runs only :sidekiq and :good_job |
Unknown group names return 404 Not Found.
Custom Checks
Define a class inheriting from RailsHealthChecks::Check and register it in your initializer:
class MyApiCheck < RailsHealthChecks::Check
def call
res = Net::HTTP.get_response(URI("https://api.example.com/status"))
res.code == "200" ? pass : fail_with("API returned #{res.code}")
end
end
RailsHealthChecks.configure do |config|
config.register :my_api, MyApiCheck.new
end
config.register automatically adds the check to the active checks list. Use pass, warn_with, and fail_with (inherited from Check) to set status, and measure { } to record latency.
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
License
The gem is available as open source under the terms of the MIT License.