When it comes time to horizontally scale up your application with multiple server instances on AWS you generally have three choices: DNS round-robin (simply assigning multiple A names to a domain), using Amazon Elastic Load Balancer, or using one or more HAProxy‘s on EC2. The Robin-robin approach, while easiest, is not good since DNS will always forward round-robin to an IP even to a dead or overloaded EC2 instance, hence, a real HTTP load balancer is needed.

Amazon ELB is pretty awesome as it’s inherently fault tolerant and highly available. You never have to worry about scaling it up like regular EC2 instances. It just works, and it’s relatively cheap. But it also has a few drawbacks including lacking complex routing algorithms, no logging outside of Cloudwatch, and can’t gracefully handle great spikes in traffic like a Slashdot or a consumer flash sale without “prewarming” the load balancer (an act that requires a premium support agreement and contact with Amazon ahead of time).

HAProxy, the premiere open-source load-balancer contains a swiss army knife of functionality, including tons of routing algorithms, that addresses many of the limitation of Amazon ELB at the cost of a lot more manual setup, complexity, and cost (since it’s hosted directly on EC2 instance(s). This article is a great discussion on the merits of both and worth a read if you’re like to know which to go with.

But wait there’s more! What if you could have the best of both worlds? The following article discusses pairing both ELC and HAproxy together.

Lastly, if you don’t want to get into the complexity that is HAProxy, you can always try load balancing through Nginx. There’s less fine-grained controls but it’s totally useable as an efficient load balancer.