First off, let’s just say: Heroku is awesome. There are all kinds of great reasons to use it, and I would never, never claim that Heroku is wrong for all deployments.
But it’s also not right for all deployments. Let’s talk about when it’s wrong and when it’s right.
Heroku’s big advantages are:
- really easy to deploy
- really easy to scale
- mostly everything just works
Those are big advantages. Sometimes they’re the most important thing for your project. When they are, you should absolutely use Heroku.
But why might you not?
First, the elephant in the room: the cost. Heroku gives you limited free hours per month, and after that it’s expensive. Background threads or processes also cost extra.
A single minimum-power dyno runs you $36 per month, assuming you need barely any space in Postgres. Heroku is basically going to cost you at least twice what a VPS would cost (e.g. Linode or Digital Ocean) and give you much less power. If you process many simultaneous requests or run many background threads, it will be at least three or four times as expensive for the same power.
Third-party services like MySQL (vs Postgres), Cassandra, Redis or MemCacheD will also cost more if you use them.
Speaking of third-party services, they’re not always available. Somebody has to have written a specific Heroku plugin for them, and you’d better hope the version available matches your needs.
For off-the-shelf services, that’s no problem. Redis or MemCacheD, for instance, are pretty easy to use.
But if you want Ventrilo or Akka or a specific version or a specific background process of your own that you’d have to compile… Nope. Heroku’s not the right service in that case, even if you’re willing to pay a lot.
In general, Heroku limits your ability to customize. You can have the Ruby versions and third-party libraries (e.g. libxml, node.js, libuv) that they specifically provide. Need something weird or a specific version? Sorry, not on Heroku.
Compatibility with app servers is also spotty. They provide Thin for EventMachine, but there are slightly odd limits as a result of the Heroku architecture, and it generally won’t work quite right. Which isn’t a problem if you use Unicorn, of course. Heroku is great if you want pre-chosen off-the-shelf components. Which often you do, and occasionally you don’t.
Similarly, the Ruby evented support (e.g. EventMachine) isn’t amazing. That’s not a problem for you… Unless it is.
The Heroku architecture is great if you’re building a hosting service, and a little weird if you’re being hosted on it.
Your app needs to be prepared to be killed and put onto a new server at any time, instantly. That means you can’t write to local disk (no log files, no file-based Rails cache), nor assume that things like global variables will last from request to request.
You can do some Heroku-specific logging, but you have to do it all in a very specific style.
It also means that a lot of your existing operations knowledge doesn’t work. You can’t log into the machine and poke around, and you certainly can’t modify machine settings or have your application save local state or logs.
Is that a problem? Well, sometimes.
Heroku is also hard to use for non-web services that don’t use HTTP. It’s not really set up for them.
It gets your data, which may or may not be a problem. It’s like other cloud vendors, but may not be okay for you.
And Heroku’s scaling of dynos — regular, 2x everything or huge CPU and RAM for 16x the cost — may not be for you. Or it may be fine, depending.
Do I Use Heroku? The Short Version
You’ve read (or skimmed or scrolled) through the long version.
What’s the short version?
The short version is that when you have an installation where you don’t need to customize much, and you don’t need a lot of servers, Heroku is great.
Or when you want utter simplicity and being expensive is fine, Heroku is awesome. Especially if somebody else pays the server bill!