Heroku remains the easiest way to deploy and host a web app, and it doesn’t have to cost an arm and a leg. In fact, for some apps you can do it for (almost) free.
This guide covers everything you need to know about using Heroku on the cheap, including Eco dynos, the Mini Postgres database plan, and free add-ons.
How does Heroku work?
Heroku runs your app on “dynos”. This is just Heroku’s word for “container” or “server”. For your app to run and serve requests, you need at least one web dyno running. Adding more web dynos will increase your capacity to handle a higher volume of requests.
Heroku offers six dyno types, each increasing in price and performance characteristics. At the lowest tier are the Eco dynos.
Running an Eco (or Basic) dyno grants you the same performance characteristics as the Std-1x tier, but Eco dynos have unique guards around their allotted runtime.
Eco dyno limitations
Naturally, “Eco” comes with some… restrictions.
Eco web dynos will idle (sleep) after a period of inactivity. The next request will wake it up, but users will notice a delay while the app is waking.
You have a limited number of “Eco dyno hours” each month. When you’ve exhausted your quota, your app shuts down.
Eco dynos do not support Heroku SSL for custom domains.
Heroku metrics are not available for Eco dynos.
Those limitations might seem like deal-breakers, but fear not! We have workarounds for many of them.
How to prevent Eco dynos from sleeping/idling
Eco dynos will sleep (shut down) after 30 minutes of inactivity. This is actually a feature to avoid using up your Eco dyno hours. This makes Eco dynos great for staging/test environments that don’t have constant usage.
If you want your Eco web dynos to run 24/7, you’ll need to ensure they receive at least one request every 30 minutes. The easiest way to prevent your dynos from sleeping is using an uptime monitor that pings your app all day long.
There are lots of uptime monitor services, and there’s a good chance you’re already using one. If you need a free one (you’re reading about low-cost dynos, right?), we’re big fans of Uptime by Better Stack.
Note that dyno sleepingonly applies to web dynos. If you’re running a “worker” dyno (asynchronous/background job processing), it will not go to sleep. It’s very easy to consume your Eco dyno hours quota with worker dynos.
How are Eco dyno hours calculated?
Heroku prorates dyno usage to the second. If you run an Eco dyno for 30 minutes, that’ll use 0.5 hours from your Eco dyno hours quota. If you run an app with single Eco dyno 24/7 for 31 days, that’ll use 744 (24 x 31) of your Eco dyno hours.
Subscribing to the plan immediately gives you 1000 dyno hours for the current month
Pretty simple. Since a full month is at most 744 hours, this means you can run a single web dyno 24/7 for $5/mo (based on current Eco pricing).
Check your dyno usage
So how many Eco dyno hours do you have available? Check out your Heroku billing page.
This is a great way to check up on any forgotten apps that are consuming your free dynos quota!
Eco vs. Basic vs. Standard-1x dynos
Heroku’s six dyno types are generally more powerful as they get more expensive, but that’s not the case for cheapest three.
Eco, Basic, and Standard-1X dynos are exactly the same hardware with the same performance characteristics. Basic dynos only lift a few of the feature limitations of Eco dynos:
Basic dynos do not go to sleep.
Basic dynos support Heroku SSL for custom domains.
There’s no “hours quota” for Basic dynos.
One shared limitation between Eco and Basic dynos is that you cannot scale to more than one dyno per process. If you need to scale up to two web dynos, for example, you must use standard or performance dynos.
SSL for Eco dynos
SSL is no longer optional these days—you must serve your web app via HTTPS. On Eco dynos, you have two options:
Serve your app from the default Heroku URL. Every Heroku app is available by default at [app-name].herokuapp.com, and all of these URLs include SSL support out of the box.
If you need a custom domain, you’ll need to use a service like Cloudflare’s Flexible SSL (totally free). Your users will connect via HTTPS to Cloudflare, and Cloudflare will connect via HTTP to your Heroku app.
If neither of these options are acceptable to you, you’ll need to use one of the more expensive dyno types.
Running a production app on Eco dynos
Since you can run an Eco dyno (which is equivalent to a standard-1x dyno) for 1,000 hours per month, that means you can run your production app 24/7 on Heroku for $5 per month, right?
Well, that depends.
Most production apps need at least a web process and a background worker process for things like sending email and communicating with third-party services. This requires a “worker dyno” in addition to your “web dyno”, will exceed your 1,000 hour allotment if you run them both all month. And Eco worker dynos do not automatically sleep like Eco web dynos do, so they’ll be running 24/7 unless you manually scale them down.
This is where you need to decide just how “production-scale” your app needs to be right now. Some tools (like good_job and sucker_punch for Rails) let you run async jobs within your web process. You could also choose to do these tasks synchronously during web requests if the user impact is minimal.
Some background work could also be performed on a periodic basis with Heroku Scheduler, which creates a “one-off dyno” and only uses dyno hours for the time it’s running.
If you really do need a separate worker process (and most full-stack production apps do), then you’ve probably outgrown Eco dynos.
When to upgrade your Eco dynos
If you’re already running your app on Eco dynos, how will you know when you’ve outgrown them? If your app is a successful product with growing traffic, you will certainly hit a point where a single Eco dyno is insufficient.
You can’t scale Eco dynos horizontally—in other words, you can’t add more than one Eco web dyno to your app. If one dyno is not enough for you, you’ll need to upgrade to standard dynos.
The best way to know when you’re outgrowing Eco dynos is by watching your metrics. Since Heroku’s metrics tab is only available on Basic+ plans, check out Librato’s free add-on for similar metrics and alerting.
If you’re seeing high request times and/or HTTP errors, there’s a good chance you’re outgrowing free dynos.
It’s also possible your app is just slow. An APM tool like Scout will help you drill down into specific bottlenecks. A full tour of Scout is beyond the scope of this article, but generally speaking, high request queue time indicates a capacity issue (need more dynos).
If you’re seeing lots of time spent in other parts of your stack (Ruby, Postgres, etc.) then adding more dynos will not help. You’ll need to investigate your app code to resolve the performance issue.
Heroku’s (almost) Free Postgres database
Whew! All that and we haven’t even talked about your database yet. Much like dynos, Heroku offers multiple tiers of Postgres, but did away with the free tier in 2022.
But… ouch. Heroku’s ‘Mini’ Postgres is limited to 10,000 records.
Even the smallest production apps are likely going to exceed this limitation. Here are your options:
Upgrade to a larger Heroku database plan, starting at $9/month for 10,000,000 records.
Use a third-party hosted database provider with a more generous free plan, like ElephantSQL or Amazon RDS. Just note that once you’re out of the free plan, the pricing between these providers and Heroku is very small.
There’s really no way around it. Your database will eventually be the most expensive layer of your stack, so be prepared to pay for it early.
Free Heroku add-ons
One of the best parts of Heroku is the add-on ecosystem, and many add-ons have excellent free plans. Here are some of my favorites:
Librato — As mentioned earlier, Librato gives you visibility into your app metrics above and beyond what Heroku provides (and Heroku provides no metrics for free dynos).
Scout APM — Monitor and diagnose app performance issues. I install this on every app.
Sentry — Fantastic error monitoring service with generous free plan.
Redis Cloud – Heroku has their own Redis service, but you’ll get more for your money (or for free) with Redis Cloud.
Judoscale – Every Heroku app needs a safety net if traffic spikes or a dyno has a problem, and Judoscale gives you that for free.
AutoIdle — This one isn’t a free option, but it’s super useful if you’ve upgraded to larger dynos and you want to save money when your app isn’t being used. It essentially replicates the “sleeping” behavior of free dynos. Very nice for staging/QA apps.
Putting it all together
So with all this in mind, when do Heroku’s cheapest offerings make sense for you?
Launching a side project. There’s a good chance the side project won’t get much traction at first, so throw it on Eco dynos and a Mini Postgres DB and see what happens! You won’t have enough free hours to run worker dynos, but who cares… until you have real users and revenue, you can do everything in your web process.
Running a staging or QA app. These are perfect for Eco dynos because they don’t need to run all the time. Your staging data might even fit within a Mini Postgres DB.
Beyond those use cases, you’re probably going to have to pay more for Heroku. The Eco/Mini options exist to try out the service, play with an idea, and run experiments. Once you’re running a “real app”, you’re hopefully at a point where you can spend a few more dollars on hosting.
Questions or thoughts on this article? Let’s chat on Twitter.