Apache vs Nginx on a low-resource server
Recently, in the interest of leaning more about system and server administration, and the desire for a faster, non-shared server on which to run my various websites, I’ve invested in a small VPS (virtual private server) at Digital Ocean. For those of you who don’t know, a VPS is essentially a sub-section of a dedicated server in which you have root level access and can manage your operating system, installed programs, and pretty much anything. While the performance may not be as good an equivalently-spec’d dedicated server, they are generally much cheaper, and you can create and destroy multiple virtual services as needed to scale with demand.
While setting up a WordPress site, I ran into a huge issue that I had never ran into a shared hosting plan: I could rapidly refresh the page to crash the server. Basically, if the page was refreshed too quickly, the server would start to run out of memory and crash the MySQL process which would then be unable to restart itself. Unless the service was manually restarted, the server would still serve HTTP requests, but wouldn’t respond with anything besides a brief message saying that the MySQL Server was down. While it’s not unusual for a server to be able to be brought down by a large amount of requests, the fact that this server could be brought down by one person holding down the refresh key for a few seconds was outrageous.
I tried everything I could think of, configuring MySQL and Apache for a low-resource setup, creating a large swap space with the left over SSD space I wasn’t using, and limiting requests to prevent unintentional overloading. While some of these steps helped and would help the server stay up through a larger amount of concurrent requests, I could still single-handedly crash it. I started investigating the error logs of MySQL to find the source of what crashed the MySQL service, which turned out to be an out-of-memory error. Basically, what seemed to happen was that the memory of the server would run out which would cause the MySQL service to crash and become unrecoverable. Using the top command in SSH, I analyzed what was happening with the processes running, and found the following:
As you can see, there’s quite a bit of system resources being put to use on Apache alone. This is not to mention all the resources that are also going to go to PHP, MySQL, and all the other system level processes required to run Ubuntu. Clearly, this was a problem, as if Apache started hogging on the system resources during a large amount of requests, there was nothing else to be done to tune the other processes being run.
After looking into the problem, I found that there are many people who have found that running Nginx instead of Apache helps their servers run faster with less resource usage (including the creators of WordPress, ironically enough). This sounded especially good to me, as I am running on a low resource server (1 core CPU, 512 MB RAM, 20 GB SSD). As I had no experience using Nginx, I reset my VPS to a clean installation, then followed a tutorial series on installing Nginx with WordPress, which was surprisingly simple and only took about 20 minutes to do. After getting everything set-up, I attempted to crash my server again while watching a top view. Here’s what happened:
As you can see, the resource usage is much lower. Where Apache was using hundreds of megabytes of RAM on a large number of instances, Nginx ran only two processes, each using about 10 megabytes each. While the requests began to have longer response times, I didn’t have any timeouts occur. In addition, I could run a serving test using Blitz.io (1-100 users over 60 seconds) without dropping a single request, where Apache would being dropping requests about 5 seconds in.
Overall, this is phenomenal performance over Apache. While I’m sure with better hardware and configuration, you could get comparable performance with Apache, and that some advanced features may require it, I do think that Nginx should be used as the primary HTTP server on any setup.