Update: I've recently been getting some comments about changes that have occurred in both AWS and HAProxy since originally posting this. Please review the comments and use this as a companion to additional research. If/when I have the time and need I will review and update this post. Thanks!
Recently I've done a bit of research on the differences between Nginx, HAProxy and AWS ELB when being used as a Load Balancer. I put together a line by line comparison for a friend of mine and thought I would share my results.
Below I'm going to go over load balancing talking points, discuss the pros and cons of each. I welcome comments -- especially disagreements -- in the comments section at the bottom of this post.
In a side by side comparison of performance response times between Nginx and HAProxy done in 2008, HAProxy clearly out performs Nginx for application with lower load (3 concurrent connections or less), while Nginx quickly becomes the clear leader under higher load (10 to 30+ concurrent connections) as HAProxy begins to perform very poorly. I read somewhere (but can't seem to dig up the post) that this is due to HAProxy not being multi-threaded nor having the capability to spawn child processes. Additionally, HAProxy must be run on port 80, which solidifies this limitation.
In the end, if you're using AWS, use ELB, otherwise from purely a performance perspective, for smaller trafficked application, HAProxy would be better choice. For high load, Nginx is the only real option unless you want to use a tiered approach in your load balancing.
HAProxy has the most options in this arena, support Round-Robin, Least Connection, Weighted and more.
Nginx supports Round-Robin and Weighted only.
AWS ELB only supports Round-Robin.
Nginx has two plug-ins -- HttpGeoModule and HttpGeoipModule -- which when used in conjunction can be used to direct traffic by geo-location. I haven't personally used this option, so I can't speak to performance or accuracy, but the folks a Nginx tend to do things right.
HAProxy does not support geo-location out of the box. I found a few forum posts that mention patches or combining it with BIND and GeoDNS patching, but I didn't read too deeply in to it, as it breaks the focus of this post.
Over all, I would recommend using ELB if you're on AWS -- not that I would recommend that in most cases. If you're not, I would recommend Nginx for most cases; it's performs better under load, it support HTTPS and if needed geo-location is always handy. As for HAProxy, this is best suited for lower traffic thin API application, where HTTPS isn't a requirement and especially when Least Connections is preferred.