ActiveRecord::Db::Metrics
A lightweight gem to monitor and measure database queries in Rails applications. Track CRUD operations per table with support for bulk operations like insert_all.
Features
- ð Track database queries per request
- ð Breakdown by table and operation type (INSERT, SELECT, UPDATE, DELETE)
- ðŠ Support for bulk operations (
insert_all,upsert_all) - ðŠķ Lightweight with minimal performance overhead
- ðŊ Easy integration with Rails controllers
Installation
Add this line to your application's Gemfile:
gem 'activerecord-db-metrics'
And then execute:
bundle install
Usage
Basic Setup
Include the helper module in your controller and add the around_action:
class ApplicationController < ActionController::Base
include ActiveRecord::Db::Metrics::ControllerHelper
around_action :measure_db_operations
end
Now, every request will log database metrics like this:
--- DB Metrics for Request ---
Total DB Queries: 15
[USERS] I:1, S:10, U:2, D:0 (Total: 13)
[POSTS] I:0, S:2, U:0, D:0 (Total: 2)
------------------------------
Selective Monitoring
You can apply metrics to specific controllers or actions:
class UsersController < ApplicationController
include ActiveRecord::Db::Metrics::ControllerHelper
around_action :measure_db_operations, only: [:index, :show]
end
Custom Logging
Override the log_db_metrics method to customize logging behavior:
class ApplicationController < ActionController::Base
include ActiveRecord::Db::Metrics::ControllerHelper
around_action :measure_db_operations
private
def log_db_metrics(results)
# Send to your monitoring service
StatsD.gauge('db.queries.total', results[:total_queries])
results[:crud_operations_by_table].each do |table, counts|
counts.each do |operation, count|
StatsD.gauge("db.queries.#{table}.#{operation.downcase}", count)
end
end
end
end
Manual Usage
You can also use the collector directly without the controller helper:
collector = ActiveRecord::Db::Metrics::Collector.new
collector.start_monitoring
# Your database operations here
User.all
User.create(name: "Alice")
collector.stop_monitoring
results = collector.results
# => {
# total_queries: 2,
# crud_operations_by_table: {
# users: { SELECT: 1, INSERT: 1 }
# }
# }
How It Works
The gem subscribes to ActiveSupport::Notifications for SQL events and tracks:
- Total query count: How many SQL queries were executed
- Operations by table: Breakdown of INSERT, SELECT, UPDATE, DELETE per table
- Accurate row counts: Uses Rails 7.2+
payload[:row_count]for SELECT queries andpayload[:affected_rows]for INSERT/UPDATE/DELETE operations
Bulk Operations
This gem correctly counts the actual rows affected in bulk operations:
User.insert_all([{name: "A"}, {name: "B"}, {name: "C"}])
# => Counted as INSERT: 3 â
Requirements
- Ruby >= 3.4.0
- Rails >= 7.2
- ActiveRecord >= 7.2
This gem requires Rails 7.2+ to utilize the row_count and affected_rows fields in sql.active_record notifications (PR #50887).
Development
After checking out the repo, run:
bundle install
To run tests:
rake spec
To build the gem:
gem build activerecord-db-metrics.gemspec
Contributing
Bug reports and pull requests are welcome on GitHub.
License
The gem is available as open source under the terms of the MIT License.