Rails 8 introduced support for multiple databases, and by default, it wants to create separate database instances for your primary data, cache, queue, and ActionCable connections. If you’re deploying to Heroku and you just follow the defaults, you’ll end up with four separate Postgres databases, which means four separate billable databases instances.
I’m using a single database instead. Here’s why, and when you might actually want separate databases.
The Default Rails 8 Configuration
When you set up Rails 8 with SolidQueue, SolidCache, and ActionCable, the default database.yml looks something like this:
production:
primary:
url: <%= ENV["DATABASE_URL"] %>
cache:
url: <%= ENV["CACHE_DATABASE_URL"] %> # Different database!
queue:
url: <%= ENV["QUEUE_DATABASE_URL"] %> # Different database!
cable:
url: <%= ENV["CABLE_DATABASE_URL"] %> # Different database!
If you deploy this to Heroku without setting those environment variables, Rails will try to create separate databases. On Heroku, that means four separate Postgres add-ons, which gets expensive fast.
Our Configuration: One Database, Multiple Connections
Instead, we can point everything at the same database:
production:
primary: &primary_production
<<: *default
database: seeress_production
url: <%= ENV["DATABASE_URL"] %>
cache:
<<: *primary_production
url: <%= ENV["DATABASE_URL"] %> # Same database
migrations_paths: db/cache_migrate
queue:
<<: *primary_production
url: <%= ENV["DATABASE_URL"] %> # Same database
migrations_paths: db/queue_migrate
pool: <%= ENV.fetch("SOLID_QUEUE_POOL", 5).to_i %>
cable:
<<: *primary_production
url: <%= ENV["DATABASE_URL"] %> # Same database
migrations_paths: db/cable_migrate
All four logical connections point to the same physical database. You still get the benefits of logical separation (different migration paths, different connection pools), but you’re only paying for one database instance.
Why Rails 8 Does This By Default
Before I decided to use one database, I had to understand why Rails 8 wants separate databases in the first place. Rails 8 defaults to separate databases for a few good reasons:
- Isolation – If your cache database gets hammered, it doesn’t affect your primary queries
- Scaling – You can scale cache/queue databases independently from your primary data
- Backup strategies – You might want different backup schedules for different data types
- Multi-tenant setups – Some apps need separate databases per tenant
These are all valid reasons, but they don’t apply to my smaller app scale use-case.
When Separate Databases Make Sense
You will want separate databases if…
- You’re running at scale – If you’re processing millions of jobs per day, a separate queue database might make sense
- You have different performance requirements. -Cache databases can use different instance types optimized for read-heavy workloads
- You need geographic distribution – You might want your cache database in a different region than your primary
- You’re doing multi-tenant – Each tenant gets their own database
- You have compliance requirements – Some data might need to be in a separate, more secure database
For most apps, especially ones running on Heroku’s managed Postgres, these concerns don’t apply. I am a big fan of Heroku for this and many other reasons.
Why One Rails 8 Database Works on Heroku
Heroku’s Postgres handles I/O pretty well. The connection pooling works fine, and I’m not at a scale where we need to separate cache from primary data. My queue tables are small, cache tables are small, and they all live happily together in the same database.
The key is that we still get logical separation:
- Different migration paths (
db/migrate,db/cache_migrate,db/queue_migrate,db/cable_migrate) - Different connection pools (we can tune the queue pool separately)
- Different ActiveRecord models (SolidQueue::Job, SolidCache::Entry, etc.)
There hasn’t be an issue with throughput at the database for me in this, or in many of my Rails apps on Heroku. If scaling becomes a need, it’s a quick config and database migration task away from being ready.
The Cost Difference
On Heroku, a Hobby Dev Postgres database is $5/month. If you follow Rails 8 defaults and create four databases, that’s $20/month just for databases. For a small app, that’s unnecessary.
Even on Standard plans, you’re looking at $50/month per database. Four databases = $200/month. One database = $50/month.
Unless you actually need the isolation, you’re just burning money.
How We Deploy
When we deploy to Heroku, we only provision one database:
heroku addons:create heroku-postgresql:standard-0
This gives us DATABASE_URL, and we point everything at it. Migrations still work correctly:
rails db:migrate # Primary tables
rails db:migrate:cache # SolidCache tables
rails db:migrate:queue # SolidQueue tables
rails db:migrate:cable # ActionCable tables
Each migration path creates its own tables in the same database. SolidQueue tables don’t conflict with SolidCache tables because they’re in different namespaces.
When to Reconsider Multiple Rails 8 Databases on Heroku
There are 3 key triggers for me to move to separate databases:
- We hit performance issues: If cache queries start affecting primary queries, we’d split them
- We need to scale independently: If the queue database needs more resources than the primary
- We outgrow Heroku’s single-database approach: If we need geographic distribution or specialized instances
But right now, the need is not there. One database works fine, and it saves money while prototyping and even in many of my production apps.
The Bottom Line
Rails 8 multiple database support is great, but the default configuration assumes you need physical separation. For most apps on Heroku, you don’t.
If you need separate databases later, you can always split them. If you are just prototyping or running a smaller app you can start with one, and only add more when you have a real reason.