Nginx vs apache as a reverse proxy

I’m doing some simple testing on a FreeBSD 7.0 server comparing Apache2
vs Nginx as a reverse proxy to an Apache backend server. The backend
serves mainly static images using mod_python.

I have yet to do thorough testing but it seems as though Apache2 has
slightly higher throughput (KB/s measured using Jmeter) when compared to
Nginx under moderate load.

Has anyone else found Apache to have a higher throughput as a reverse
proxy? Can I assume it’s because Nginx doesn’t use http keep-alives to
backend servers and thus creates a new connection upon each request?

Cheers

  •      Linden

I have found similar issue before.
Usually it is the number of sockets in TIME_WAIT (due to non keepalive).

Do you have KeepAlive in the backend Apache server?
Try to widen local_port_range and number of sockets in TIME_WAIT.

tcp_max_tw_buckets=800000 (YMMV)
tcp_tw_recycle=1
tcp_tw_resue=1
tcp_timestamps=1 (usually performance hit, but in this situation,
it will help)

On Mon, 2009-03-02 at 17:43 +1100, Linden Varley wrote:

I’m doing some simple testing on a FreeBSD 7.0 server comparing
Apache2 vs Nginx as a reverse proxy to an Apache backend server. The
backend serves mainly static images using mod_python.

I have yet to do thorough testing but it seems as though Apache2 has
slightly higher throughput (KB/s measured using Jmeter) when compared
to Nginx under moderate load.

Unfortunately (and counter-intuitively) KB/s isn’t completely useful
without also considering actual requests per second:

http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/

“The network I/O graph I find interesting mostly because I don’t know
how to take it. On one hand it seems Apache is simply using more
bandwidth to do the same number of requests as Nginx. Which would seem
bad. On the other it could just mean that Apache does a better job of
consuming and using the available pipe. Which would seem good. My hunch
is that it is the former.”

Regards,
Cliff

Sorry I should of mentioned that the requests per second are also
slightly higher with apache over nginx. Although it’s a marginal amount
it is consistent.

Yes the backend server has a large number of sockets in TIME_WAIT and
yes keep-alive is on on the backend too. Turning it off does actually
close the gap which is much better, but are there any plans for the
proxying in nginx to support keep-alives?

It plays havoc with the firewall too since it creates a new state entry
in the state table for each socket.

Apache mod_python has to be there since its an interface to a framework
which serves images. I can try to move to mod_wsgi on nginx but what I
was more trying to do was test the performance of Nginx vs Apache purely
as a reverse proxy server in a DMZ. (the backends are a multitude of
things such as tomcat, mod_python, CMS, IIS, apache etc.)

Nginx definitely has a smaller footprint and performs better at higher
loads but at the expense of an increase in sockets on the backend
servers. This will probably require some tuning at the backend to
decrease the TIME_WAIT connection states and disabling keep-alives for
all applications.

Not bashing nginx in any way at all, just wanted to see if what I was
seeing makes sense and if anyone else had experiences.

Cheers

  • Linden

On Tue, 2009-03-03 at 14:16 +1100, Linden Varley wrote:

Sorry I should of mentioned that the requests per second are also
slightly higher with apache over nginx. Although it’s a marginal
amount it is consistent.

Then you are probably right that it has to do with no keepalive for
backend connections.

One thing I wonder is if restructuring your stack a bit wouldn’t make a
lot of difference. You say you are serving your static images via
mod_python… what’s the logic there? Are the images dynamically
generated by Django or some other Python web framework?

Yes the backend server has a large number of sockets in TIME_WAIT and
yes keep-alive is on on the backend too. Turning it off does actually
close the gap which is much better, but are there any plans for the
proxying in nginx to support keep-alives?

I think it’s planned but I unaware of any time-frame.

It plays havoc with the firewall too since it creates a new state
entry in the state table for each socket.

Can you eliminate this firewall? If the Apache server isn’t
public-facing, I think I’d just give it a non-routable IP and get rid of
the firewall.

Cliff