Amazon Web Services
Over the course of the past 6 months or so, I’ve had the opportunity to explore various cloud hosting services, starting with Amazon Web Services. I don’t want to go into detail about AWS here, but suffice to say that I like this suite of services a lot, and it was a great fit for an SMS app / messaging server I deployed on this infrastructure. The application consisted of a set of loosely coupled components running on EC2 (some daemon apps and some Merb based web frontends), communicating via the Simple Queue Service (SQS). I leveraged S3 for deployments and backups.
AWS is great, and the ability to bring up new EC2 instances any time is very powerful. Need to test something out real quick? Simply launch a fresh instance, then kill it when you no longer need it. One of your app servers running at capacity? Simply launch another one, or even automate this by monitoring your load. Need to bring up 1000 instances for an hour in order to load test your web app, then shut them right down again? No problem! No need to ever call up an IT person at your local hosting company and get a new server provisioned, or even buy your own server and drive to a colocation facility yourself to set it up.
But the services that AWS provides are still very low level. This can be a good thing because it gives you complete control and flexibility over how to architect your application, but it also means that you’ll spend a good amount of time configuring Linux images and writing deployment, monitoring, and backup scripts. For many complex applications, this makes perfect sense, and I would pretty much always pick AWS over VPS or dedicated hosting services these days. But for a large class of straightforward web apps, it would be great if I didn’t have to worry about these details (especially since I’m admittedly not that much of an IT guy). Ideally I would simply push my code out into the cloud and delegate all deployment concerns to the hosting service. When taken to the extreme, I would not even want to have to know any details about the deployment infrastructure. All I would care about is that the app runs reliably and scales up as needed (and affordably).
Google App Engine
Google App Engine has a similar philosophy, and if I was a Python fan, this would be a very interesting option. As soon as Google starts supporting Ruby, I will definitely check this out. My guess is that Rails might be difficult to support, because it is very tightly coupled with relational databases, but other Ruby based web frameworks (in particular Merb, perhaps even with a special DataMapper adapter) seem like they could be a great fit for App Engine. DataMapper already has adapters for other non-relational data stores (such as CouchDB), so it seems like it should be fairly straightforward to build an adapter for the Google App Engine Datastore.
But I’m getting off-track from what I was really planning to write about:
Lately, several Rails based services have emerged that take a big step in this direction. I’ve had the chance to work with Heroku and Morph AppSpace, so I figured I’d share my early impressions.
Still in private beta, Heroku is a Rails specific hosting service that prides itself on its ease of use and elastic scalability. You create a new Rails app using their web interface, and then either edit it straight in the browser via a nifty browser based IDE, or check it out via Git and edit it locally. Changes made via the browser take effect immediately, changes made via Git are automatically deployed upon pushing to the remote repository, including applying migration scripts. It can’t get much more streamlined than that!
Heroku sits on top of EC2, but this fact is completely hidden from the developer, who never interfaces directly with the underlying EC2 instance. This means that, among other limitations, you don’t have shell or FTP access to the server. You do however have access to the Rails console via Heroku’s web interface, allowing you to work with your model objects and take care of the odd ad-hoc task. You also have access to your Rake tasks and the Rails code generators. Overall, I didn’t find this limitation all that bad.
Heroku uses PostgreSQL (we would have preferred MySQL, but that is unfortunately not an option at this point), but you don’t have direct access to the database. The web interface has some rudimentary functionality for viewing your database schema and data, but there is no way to run SQL queries. I have found this a much bigger limitation than the lack of shell access, as it prevents a lot of ad-hoc analytics or quick and dirty data changes that occasionally come in handy (although I suppose it is easy enough to whip up a quick migration for the latter). There is a way to download a yaml based database dump, which you can then import into your local database (regardless of whether this runs PostgreSQL, MySQL, or Sqlite3). It’s a bit cumbersome, but at least the option is there, so your data is never held hostage.
Another major limitation is that Heroku does not support background tasks of any sort. This includes both cron jobs as well as tasks offloaded by the Rails app onto a job server such as BackgrounDRb or Workling. This may not be critical for all applications, but it is becoming increasingly common for Rails apps to offload a lot of the processing into asynchronous background tasks, allowing for a more responsive user experience as well as better scalability.
Heroku is free for now, but as far as I am aware they are aiming for a utility based pricing model, where you only pay for the actual bandwidth and CPU utilization you have consumed. If done right, this should be a great model that allows developers to launch their application without committing to any large upfront costs, and scale up the cost linearly with utilization.
Overall Heroku is very impressive, and if you’re starting out with a brand-new Rails app, it’s well worth considering, at least in the early phases. It does come with some significant limitations compared to traditional hosting options, which may or may not be a big deal for you. Of course these are offset with the elimination of IT related tasks that are no longer necessary in this environment.
But as much as I like Heroku’s premise, we were underwhelmed with the performance of our Rails app on Heroku, which was our main reason for exploring alternatives such as Morph. Of course, since Heroku is still in its early stages, I’m sure they will be able to improve this over time.
Morph is similar in principle to Heroku, but in my experience it is generally a bit more flexible.
One of the main differences is that scaling isn’t quite as transparent as in Heroku. Morph applications run on one or more “cubes”, which they describe as a “virtualized application compute environment”. A single cube is free and may very well be sufficient during development, so as with Heroku there is no up-front cost (although free plans don’t support custom domains). Additional cubes cost $31 per month (the price goes down after 4 cubes) and also come with increased bandwidth and storage limits. But unlike typical VPS accounts, cubes are charged on a daily basis, so you can ramp up (or down) your cubes any time as needed to adjust to your application’s utilization. This does mean that you need to manually allow your app to scale by adding additional cubes, but this is easily accomplished in the Morph Control Panel. Apparently automatic scaling based on application load is planned for a future release.
The next difference is in the range of applications that Morph supports: Rails, Java (including Grails), and PHP (experimental). I have only used Morph for Rails applications and can’t speak to any of the other options.
Morph supports both PostgreSQL and MySQL (although the latter costs an extra $0.33 per day, apparently due to licensing issues). One very useful feature is that Morph gives you direct access to the database via a web based admin tool (phpMyAdmin in case of MySQL).
Unlike Heroku, Morph does not offer a web based IDE. It also doesn’t create a blank Rails app for you, nor does it offer source code hosting. Instead, it integrates with your existing source control system via a customized Capistrano deployment script. You simply specify the type (supported are Git, Subversion, Mercurial, Bazaar, and Local Directory) and URL of your SCM (GitHub in our case) and their wizard spits out a customized Capistrano script. After that, deployments are a breeze, not unlike Heroku. One difference is that Morph’s deployment process involves multiple stages, the first of which consists of uploading your code to S3. As a result, you don’t actually see detailed deployment status in the console and need to refer to the deployment logs in the Control Panel instead.
Another critical feature for us is that Morph has at least rudimentary support for cron jobs. The Control Panel allows you to run Rake tasks directly (just like Heroku), but it also allows Rake tasks to be scheduled at arbitrary intervals (the minimum interval is 1 minute). This still doesn’t allow us to offload arbitrary processing jobs to a job server, but it does at least enable jobs to be queued up in the database and processed asynchronously by a Rake task. We are using this mechanism to offload email processing to ar_mailer, which works great and leads to a significantly improved user experience.
On the downside, Morph does not provide access to the Rails console. For me this is largely offset by the ability to access the database, but console access would have been nice.
Last not least, at least for our application, Morph resulted in a significant speed boost (at least multiple X, close to an order of magnitude).
So which service (if any) do I recommend? I wholeheartedly recommend both services. Which one is a better fit for you will likely depend on the specific features (and limitations) that matter to you. Personally, I’m mostly enamored with Morph at this point, the improved performance and ability to run background jobs being the biggest differentiators for me. It remains to be seen whether either Heroku or Morph remain good options for us as our application grows (the fact that neither support true background tasks or Memcached servers might become a limiting factor at some point), but if nothing else they’re an ideal way to get off the ground.
If you’re starting out with a new Rails application, you may want to simply try out both services (it really doesn’t take that long) to see which one you like better. The easiest way to do this is to start with Heroku, as this creates a new Rails app for you and provides Git hosting. You should be able to then use Morph’s Capistrano wizard to generate a custom Capistrano script for you and check this into your Git repository, at which point you’ll be able to deploy the same Rails app to both Heroku and Morph. Of course, if you later decide to stick with Morph, you should find a different source code host (I heartily recommend GitHub).
The bottom line is that this new breed of hosting services is extremely compelling. Sure, both Heroku and Morph still have some rough edges and won’t be a good match for all applications at this point, but the direction is very promising and I am excited to find out what the future holds.