Post

Save Money on Heroku: Share One Database Across Multiple Apps

Hey! This one’s going to be a short one, but hopefully useful to some of you out there.

It’s been a while since Heroku announced the end of free dynos and database plans, but it’s still one of the best price/value platforms for deploying proof of concepts, staging environments, and personal projects.

Wait… how?

They introduced a new Eco Dyno plan, a personal subscription for $7/month that gives you 1,000 hours to use across all your Heroku apps. Pretty neat!

But what about the database?

The cheapest plan for Heroku Postgres is $5/month, which doesn’t sound like much… until you have 10 staging apps running. That’s:

1
$5 * 10 apps + $7 (dyno) = $57/month

For apps you barely use and only access once every few weeks or months? Yeah, not ideal.

What if you could reuse a single DB across all your apps?

This simple trick lets you run as many Heroku apps as you want for just $12/month, and it’s been super helpful for me.

I run several proof of concepts, staging environments for projects I built for friends, my wife’s sports studio staging website, and even an old college final project that my friend and I still maintain to test small changes the company we built it for occasionally requests.

Let’s walk through how to do this. I’ll show the example using Ruby on Rails, but the same idea applies to other frameworks too.

Step-by-step: Share a single Heroku Postgres across apps

Use schema_search_path in your database.yml

In your Rails app, set the schema_search_path in config/database.yml like so:

1
2
3
4
production:
  <<: *default
  database: <%= ENV["DATABASE_URL"] %>
  schema_search_path: <%= ENV["DATABASE_SCHEMA"] || "public" %>

This tells Rails to use a specific schema for this app, falling back to “public” if nothing is set.

Update your Heroku app’s environment variables

After deploying your app to Heroku, it may automatically provision a new database. Let it finish, then delete it.

Now go to the app where your main Heroku Postgres addon lives, and copy its DATABASE_URL.

Paste that into the DATABASE_URL of your other apps.

Then, add a new environment variable:

1
DATABASE_SCHEMA=your_schema_name

I usually just set it to the app’s name.

almost there gif

Manually create the schema in the shared database

Your deploy will likely fail at first, that’s expected! The schema doesn’t exist yet.

Open the Heroku Postgres addon in the dashboard, grab the credentials, and connect using a tool like TablePlus or PgAdmin.

From there, just create a new schema with the same name you used in DATABASE_SCHEMA.

Release and deploy!

Once the schema is in place, trigger a new release, and you’re done 🎉

You just saved yourself $5/month, and the next time you do this, it’ll be $10/month, then $15/month, and so on 💸

⚠️ Gotchas

  • If Heroku rotates the DATABASE_URL for maintenance, you’ll need to update it in the other apps that don’t have the addon directly attached.
  • Aside from that, you’re good!

🪄 Alternatives: Kamal and self-hosting

If you’re a Rails developer, you’ve probably heard about Kamal, it’s been out for a few months now, and it’s awesome. It makes it really easy to deploy apps to virtual machines on AWS, Hetzner, DigitalOcean, etc.

If you’re not using AWS’s 1-year free tier, you’re probably looking at $8–12 per app/month, and that’s if you set up the DB as a Docker container yourself.

If you use managed services like RDS, that might cost an extra ~$16/month, even if you reuse the same DB across apps 😬

But here’s something cool I might write about soon: You can use Kamal to deploy multiple apps on the same server, reducing costs even further.


Thanks for reading! 😄

Let me know if you end up using this trick — or if you’ve got others to share.

thank you gif

This post is licensed under CC BY 4.0 by the author.