I have been using Heroku as a cloud hosting provider for the last couple of years for my personal projects, which are usually Ruby web apps, and have really grown to love the platform. Heroku is a Platform as a Service (PaaS) that sits on top of Amazon AWS. I have grown to appreciate the simplicity of using the platform via the Command Line Interface (CLI) tools provided by Heroku and it's tight integration with the Ruby toolchain and Git, which I use almost exclusively these days for Software Configuration Management (SCM). The support for Ruby and the ease of setting up my deployment and installation tasks has been very simple because Heroku uses the standard tooling that I was already using to do Ruby development. Deployment to Heroku was as easy as performing a push with Git.

Recently, I had to write a simple REST API for an internal project and decided to experiment with Node.js and Express. Node.js is a JavaScript runtime built as an alternative to running JavaScript in a browser runtime, and Express is a lightweight web application framework for Node.js. Initially, I built my API and deployed it to Heroku in a very similar fashion to how I was deploying my other Ruby apps to Heroku. Using the standard Node Package Manager (npm) and a package.json file was very similar to how I had been using Bundler for managing dependencies in Ruby. Additionally, the Express framework is very similar to Sinatra in Ruby, so the actual development and deployment to Heroku ended up being quite easy. I should note that most of my client work has been JavaScript heavy, so the burden of entry to Node.js was relatively low for me. Below are my simple deployment steps for deploying a Node.js and Express application to Heroku. To follow along you can setup git, node.js and the Heroku CLI. A "hello world" app can be downloaded from my GitHub here.

Heroku Node.js Deployment Steps:

$ git init
$ git add .
$ git commit -m "initial commit"
$ heroku create my-first-node-api
$ git push heroku master

While doing my research and development of this API, I ended up reading quite a bit on Amazon Elastic Beanstalk. It appeared that quite a few people have written similar Node.js REST APIs and deployed them directly on to Amazon EC2 instances using Amazon's new Elastic Beanstalk tooling. This piqued my curiosity, and I decided that I should compare the configuration, deployment, and cost differences between Elastic Beanstalk and Heroku.

Comparison Criteria

  1. Ease of Create a Deployment Target
  2. Ease of Deployment
  3. Git Integration
  4. External Service Integration (DB Tier, Other Web APIs, Cache Providers etc.)
  5. Cost

Amazon's Elastic Beanstalk tooling integrates directly with their EC2 instances in order to provide a competing experience to Heroku and other PaaS providers. The basics of the Elastic Beanstalk tooling are a CLI tool and Git integration so that pushing out live code and configuration can all be handled with out having to login to the EC2 Web Console or SSHing into your EC2 instance. The creation of new server instances to deploy to and all other configuration can be handled using the CLI tool. This addresses my first 3 criteria, and the experience is actually very similar to the Heroku workflow I described above, so there isn't a clear winner yet. To follow along you can deploy the "hello world" app from above after you have installed the Elastic Beanstalk CLI tools following the below steps. As you can see pushing out live code is just as easy as the Heroku steps from above.

Elastic Beanstalk Node.js Deployment Steps:

$ git init
$ git add .
$ git commit -m "initial commit"
$ eb init my-first-node-api

My fourth criterion is about integration with external services. Obviously, if your application doesn't require any new external services or is only interacting with other existing services that you own then this question might not matter to you at all. Heroku has a lot of baked in add-ons that allow you to setup and integrate with a new database tier, caching provider, or reporting service that is hosted by one of these add-on providers. This feature is accessible from Heroku's CLI and makes it very easy to setup the other pieces that may be needed by your application. For a full list of available add-ons checkout the add-on repository here. Elastic Beanstalk some is weak here, but if you are using Amazon's Databases or other services you can access and configure those via the Elastic Beanstalk CLI. This is a clear advantage for Heroku if you need one of the service add-ons that are offered.

Finally, let's talk about cost. If you look at Heroku's Pricing and Amazon's Elastic Beanstalk Pricing, you can do a quick comparison of each service's cheapest instance. Free instances at Amazon are limited to 1 year after account creation vs. unlimited at Heroku so we will not be comparing those. At the time of writing the monthly costs for the next cheapest options are $34.50 at Heroku and $35.115 at Amazon. Comparing features Heroku's instance has more dedicated RAM than the similarly priced Elastic Beanstalk instance as well as having 2 CPUs vs 1 at Amazon. This would appear to be a big win on the Heroku side but, it is important to note that the CPU instances at Heroku are shared and the CPU at Amazon is dedicated entirely to your instance. Both Heroku and Elastic Beanstalk are layers on top of Amazon EC2 instances so at the core you will get a similar level of service in relation to the hardware and network layer that is underneath your application.

If you go the Amazon Elastic Beanstalk route you will be setting up your application on an actual EC2 instance that you have complete control over, so you will be able to remote into that instance if you like and install other software that you may need. Heroku's application containers do not afford you this privilege, so if there was any custom software that you needed that is not supported by Heroku then you would be out of luck. Heroku does support most of the major software you would need for making web applications on any of the frameworks that it supports, but this is still something worth considering when talking about cost. Additionally, Amazon provides an out of the box way to configure auto-scaling of it's EC2 instances, meaning if there is some level of traffic spike it will automatically allocate new instances to run and serve requests. This functionality is not supported by the default Heroku service, but there appear to be a few custom solutions that have been proposed by Heroku users online. Finally, it should be noted that the Amazon price is a total of the estimated variable bandwidth and data that your application would use so the price may be slightly lower or higher per month.

Criterion Heroku Elastic BeanStalk
Ease of Creating a Deployment Target TIE TIE
Ease of Deployment TIE TIE
Git Integration TIE TIE
External Service Integration WIN* LOSS
*May not impact every application

Looking over all of this data, it seems that for the purposes of the prototype web application that I was building Heroku was still the best option. It provided free hosting and access to all of the libraries that I needed, and if this system did end up needing to be elevated to production I could easily upgrade to the cheapest Heroku instance. However, in the future when choosing which PaaS to host a system that I know will be going into a full production environment, I think that Elastic Beanstalk is the clear winner providing all of the functionality that is great about Heroku, with the exception of Heroku's add-on platform, and with the additional ability to fully control my instance at a price that is easily comparable to that of Heroku.