Heroku debuted a commercial version of their Rails hosting solution last week, after a free beta stage that lasted over a year. They describe their service as "provisionless deployment" because it operates and scales automatically, without any system administration. While it is more expensive than alternatives and (for now) is based on Amazon's EC2 cloud with its accompanying SLA limitations, we think that they have a solid offering that is worth further examination.
Last week a couple of my engineers and I spoke to James Lindebaum, co-founder of Heroku, to pick his brain about the service. He jovially calls his company a bunch of "Ruby guys". A little over a year and a half ago, with support from YCombinator, James and his two partners, Adam Wiggins and Orion Henry started working on a service to allow dead-simple deployment of Rails applications. We think that what they have accomplished is nothing short of revolutionary.
Using Heroku, deployment of a new Ruby web application from scratch is accomplished with little more than a handful of commands from your terminal. No emails, phone calls or support tickets needed. We've been using their service at Hashrocket to host our internal staging environments and I can attest, it is unlike any other deployment experience you've ever had. Capistrano setup and deployment is a thing of the past with Heroku. After registering with the service and creating a new application instance in Heroku's cloud via their command-line tool, deployment is as easy as typing "git push heroku master".
The push triggers a processing hook which compiles your application into a self-contained, read-only instance Heroku calls a “slug”. It is automatically tested to assure that it can actually start. Gem dependencies are automatically installed and maintained via a .gems manifest file in your application's root directory, one of the only differences from a plain-vanilla Rails application. It's worth mentioning that Merb and Sinatra (actually, any Rack) applications are supported too.
Once the push succeeds, the slug is instantiated in one or more slots in a specially-designed grid computing environment, where it is given access to its database and cache information, and brought to life. The only major database supported is Postgres. According to James, Heroku does not currently support MySQL because it does not have transactional DDL execution.
Once a slug is activated, it becomes a fully-functioning web application called a “dyno”. Each dyno is a process running on a server in the grid, and contains a unique copy of the application code, framework, middleware, Rack, application server, Ruby virtual machine, and POSIX environment. The app server used in a dyno is their slightly-modified version of Thin, with a 250 MB memory allocation.
In response to changing demand, Heroku’s intelligent infrastructure can launch additional, fully-independent dynos at new locations in the grid, or shut down existing idle ones. Startup time for a new dyno is less than 2 seconds, a fact that gives Heroku’s platform an unprecedented level of dynamism. The custom routing system can actually put a request "on hold" while it spins up a new dyno instance in order to meet high demand. Four dynos give the equivalent compute performance as one server instance in conventional environments.
Heroku's grid itself is built on a robust cloud computing infrastructure which allows it to expand and contract as required to accommodate as many dynos from as many different applications as necessary. Above the grid is a sophisticated and highly concurrent routing mesh that allocates requests among the dynos. Additional elements, such as an HTTP cache and a memory cache, reduce the requests to the dynos and database, respectively.
According to James, the routing mesh is proprietary and an important part of Heroku's innovation. The initial version of the system was implemented as Nginx C-modules and worked well until they reached about 10,000 applications deployed and performance started suffering. The second version of the routing system is written in Erlang and is working very well.
Heroku itself is hosted on a pool of extra-large EC2 instances. I asked James how much of a premium he charges over direct usage of EC2, a question he found hard to answer. Since Heroku includes a full system architecture that would need 6 or 7 EC2 instances to replicate for a single app, it's hard to draw a valid price comparison between the two services. On the other hand, the ease with which new Heroku dynos can be activated and deactivated means that cost savings from carefully managing consumption is easier to accomplish than with normal EC2 deployments.
Heroku's pricing model is designed to charge users for only the resources they consume, and to meet the needs of users of all levels. There are a variety of tiers to accommodate everyone, from enterprises with large applications and millions of unique hits per month, down to entry-level users. Prices range from thousands of dollars a month down to less than a hundred, and the platform includes a free offering great for testing the service and rapid prototyping. As mentioned earlier, we've been using the free offering for internal staging deployments and it works very well.
Heroku’s service has been battle tested during an extended beta period in which over 25,000 Ruby apps have been deployed to the platform by more than 23,000 different developers. By conservative estimates, this makes Heroku’s platform 10 times larger than the next most popular Ruby deployment provider. Even though the commercial offering is new, James told us that he's had paying customers right from the beginning and that with support from his investors, they are ready to offer a strong and lasting commitment to new clients. (Heroku raised a $3MM Series A from Redpoint Ventures in May 2008.)