Database Setup
Rails Pulse offers two database setup options - single database (default and recommended) or separate database for complete isolation.
Rails Pulse offers two database setup options: single database (default and recommended) or separate database for complete isolation.
Option 1: Single Database (Default)
Stores Rails Pulse data in your main application database alongside your existing tables. This is the simplest setup and works great for most applications.
Advantages
- Zero additional configuration required
- Simpler backup and deployment strategies
- Works with any database (SQLite, PostgreSQL, MySQL)
- Easy to get started - just run migrations
Installation
rails generate rails_pulse:install
rails db:migrate
That’s it! Rails Pulse tables are created in your main database and ready to use.
Option 2: Separate Database
Stores Rails Pulse data in a dedicated database, completely isolated from your main application.
Use a separate database when you want:
- Isolating monitoring data from your main application database
- Using different database engines optimized for time-series data
- Scaling monitoring independently from your application
- Simplified backup strategies with separate retention policies
Installation
Install with the --database=separate flag:
rails generate rails_pulse:install --database=separate
Then uncomment the connects_to option in your Rails Pulse initializer. Without it, all Rails Pulse models keep writing to your primary connection even though the separate database exists:
# config/initializers/rails_pulse.rb
RailsPulse.configure do |config|
# Single separate database
config.connects_to = {
database: { writing: :rails_pulse, reading: :rails_pulse }
}
end
Add the database configuration to config/database.yml and run:
rails db:prepare
Important: The
connects_tosetting applies in every environment, so add therails_pulseentry to each environment indatabase.yml(development, test, and production).rails db:test:prepareloads the Rails Pulse schema into the test database automatically.
Database Configuration Examples
SQLite Configuration
# config/database.yml
production:
# ... your main database ...
rails_pulse:
adapter: sqlite3
database: storage/rails_pulse_production.sqlite3
migrations_paths: db/rails_pulse_migrate
schema_dump: false
pool: 5
timeout: 5000
PostgreSQL Configuration
# config/database.yml
production:
# ... your main database ...
rails_pulse:
adapter: postgresql
database: myapp_rails_pulse_production
username: rails_pulse_user
password: <%= Rails.application.credentials.dig(:rails_pulse, :database_password) %>
host: localhost
migrations_paths: db/rails_pulse_migrate
schema_dump: false
pool: 5
MySQL Configuration
# config/database.yml
production:
# ... your main database ...
rails_pulse:
adapter: mysql2
database: myapp_rails_pulse_production
username: rails_pulse_user
password: <%= Rails.application.credentials.dig(:rails_pulse, :database_password) %>
host: localhost
migrations_paths: db/rails_pulse_migrate
schema_dump: false
pool: 5
Note:
schema_dump: falseis required. Without it Rails dumps or loadsdb/rails_pulse_structure.sqlanddb:migratecan fail withrelation already exists. Keep database tasks enabled sorails db:migrate:rails_pulsestill runs upgrades. If a structure file already exists, delete it.
Running Tests in CI
In a multi-database setup, the DATABASE_URL environment variable only overrides the primary database configuration. The rails_pulse entry keeps whatever is in database.yml, so if it has no host, the connection falls back to a local socket and fails in CI.
Set the connection details explicitly instead of relying on DATABASE_URL:
# config/database.yml
default: &default
adapter: postgresql
host: <%= ENV.fetch("DB_HOST", "localhost") %>
username: <%= ENV.fetch("DB_USERNAME", "postgres") %>
password: <%= ENV.fetch("DB_PASSWORD", nil) %>
test:
primary:
<<: *default
database: myapp_test
rails_pulse:
<<: *default
database: myapp_test_rails_pulse
migrations_paths: db/rails_pulse_migrate
schema_dump: false
# .github/workflows/ci.yml
env:
RAILS_ENV: test
DB_HOST: localhost
DB_USERNAME: postgres
DB_PASSWORD: postgres
With this in place, rails db:test:prepare creates and loads both databases.
Primary/Replica Configuration
For high-availability setups, configure Rails Pulse with primary and replica databases:
# config/initializers/rails_pulse.rb
RailsPulse.configure do |config|
config.connects_to = {
database: {
writing: :rails_pulse_primary,
reading: :rails_pulse_replica
}
}
end
Schema Management
The schema file db/rails_pulse_schema.rb defines all Rails Pulse tables in one place. It is loaded by the installation migration (single database) or by db:prepare (separate database), and should not be deleted or edited by hand.
Upgrades ship as migrations. The upgrade generator copies them into db/migrate (single database) or db/rails_pulse_migrate (separate database).
| Single database | Separate database | |
|---|---|---|
| First install | rails db:migrate | rails db:prepare |
| Upgrades | rails generate rails_pulse:upgrade then rails db:migrate | rails generate rails_pulse:upgrade --database=separate then rails db:migrate:rails_pulse |
After a schema load, Rails Pulse records any copied migrations as already applied so they do not show as pending.
Do not use
db:prepareordb:setupas a substitute fordb:migrate:rails_pulseon an existing separate database. They will not run pending migrations. See Upgrading, which also covers the one-time route migration required for 0.4.0.
Next Steps
Advanced Configuration
Customize performance thresholds, tagging, and data cleanup.
Common Questions
Find answers to frequently asked questions.