The internet, as we know it today, started its global “conquest” in the ’90s. The whole “Web” protocol can be summed up as a visitor requesting a document from a given web address, with DNS and IP system forwarding that request to the right computer. This computer, which is hosting the requested web page, will “serve” the web page back to the visitor.
Web pages are essentially HTML documents. To be able to serve different web pages to the visitors, the “serving” machine needs a server program. Software like Nginx vs Apache handle requests, analyze them, and then hand back the corresponding documents to be viewed in a visitor’s browser.
Nginx vs Apache
Nginx and Apache are popular web servers used to deliver web pages to a user’s browser. In our case, from a hosted WordPress site. Quick stats:
- Apache was released first in 1995, then came Nginx in 2004.
- Both are used by large Fortune 500 companies around the globe.
- Nginx market share has been steadily growing for years.
- In some instances, Nginx has a competitive edge in terms of performance.
We’ll dive into Apache first since it was released first.
After Tim Berners-Lee’s CERN httpd and NCSA HTTPd in the first couple of years of the internet, Apache – first released in 1995 – quickly conquered the market and became the world’s most popular web server. Nowadays, it still is in that market position but mostly for legacy reasons. Apache is being developed and maintained by the Apache Foundation, under the Apache license.
There are two different stories on how Apache got its name. One version says that the name originates from the famous Native American heritage, while the other says that the name is a pun on “a patchy server”, which followed a series of software patches.
Apache’s huge market share is partly due to the fact that it comes pre-installed with all major Linux distributions, like Red Hat/Centos and Ubuntu.
One example of the important role of Apache within the Linux world is that its server process name is HTTPd, making Apache a synonym with web server software.
Besides being the first serious player in the web server market, part of Apache’s proliferation is due to its configuration system and its .htaccess file.
Apache uses .htaccess for its configuration. There are plenty of tutorials about how to configure, edit, and work with this file as it provides a lot of flexibility in configuring how Apache handles incoming requests. Some examples are: different redirection rules, maximum upload file sizes, URL rewrites, memory limits, directory protection (htpasswd), expires headers, cache-control headers, encoding headers, cookies, query string manipulations.
On the other hand, Kinsta utilizes Nginx which doesn’t support .htaccess files. However, settings and rules from your .htaccess files can be easily “translated” to Nginx’ own rewrite rule syntax.
One of the main “Pros” of Apache is that in the server root — the main website directory — every level or directory in the directory tree can have its own .htaccess file with its own configuration.
For shared hosting providers, this is a dream because they can provide hundreds of users on the same machine a way to configure how their websites are served, without it affecting the others. Customers can configure a lot of details in a restricted shared hosting environment, while never touching the global server configuration.
As the official documentation says:
“In general, you should only use .htaccess files when you don’t have access to the main server configuration file.”
This flexibility, however, comes at the expense of performance “permitting .htaccess files causes a performance hit, whether or not you actually even use them!”
Every time .htaccess files are enabled, Apache has to traverse the entire directory tree from the requested URL or file through all the higher levels up until the server’s root directory and then load them, for each and every request. It then needs to process these files and reconfigure itself for each of the directories configured in this way.
With WordPress websites, things can get really complex. A typical WordPress website can have hundreds of requests from different directories.
Then there will also be /wp-content/plugins with static files loaded from often dozens of plugin subdirectories. For each of these resources, Apache has to traverse its entire tree to look for the configuration.
One analysis has shown that a typical WordPress setup, rather common for websites on shared hosts, will include 42 separate .htaccess executions and 249 separate looks for the .htaccess file.
This is just at a web server level. The visitor still needs to wait for the PHP process to execute the entire WordPress call stack to create the database query and give it to MySQL to assemble the web page and send it to the visitor.
Another thing that made Apache popular is its dynamic module system.
Modules — as a feature that allows users to extend web server functionality — exist both in Nginx and Apache. Apache allows users to install modules once the web server has already been installed and deployed and then enabled/disabled them as needed. Debian-based distributions have commands that allow enabling and disabling these modules without having to edit any configuration files: a2enmod and a2dismod.
The official list of modules that come as part of Apache standard distribution is here and these include things from compression, encryption, logging, redirections to more advanced things like editing requests and responses with advanced syntax.
“Nginx was written specifically to address the performance limitations of Apache web servers.”
The server was first created as a scaling tool for the website rambler.ru in 2002. It comes in two versions: open source, with BSD-type license, and Nginx Plus, with support and additional enterprise features.
After it was released, Nginx was used mostly to serve static files and as a load-balancer or reverse proxy in front of Apache installations. As the web evolved, and the need to squeeze every last drop of speed and hardware usage efficiency with it, more websites started to replace Apache with Nginx entirely, thanks also to a more mature software.
According to data from w3techs, Nginx market share has been steadily growing, pushing Apache out and dethroning it from the first place:
This data pertains to overall web servers globally, but if we take sample of the top one million websites, Nginx has been there for some time now:
Google Search Trends seems to reflect this fact as well:
Netcraft survey suggests that Apache has been overtaken by Nginx in April 2019.
Nginx does not have a configuration system like Apache so, despite it being a lot more efficient and fast, it is not widely employed with retail hosting providers. It does not shine in shared environments as Apache does.
On the other hand, as we said, by not allowing directory-level configurations, Nginx gains a significant edge over Apache. There is an article on Nginx wiki that compares performance impact:
Nginx modules system is one more thing that positions it as a more premium choice. Nginx modules typically need to be enabled at build time, which means a more technical prowess is involved, and the post-installation adding of modules is a bit more complicated.
In 2016, with version 1.9.11, things have changed and the official/verified dynamic modules repository is reserved to the paying users. As of May 2019, they announced starting the development of support for QUIC and HTTP/3.
The Matter of Caching: Nginx vs Apache
Caching — if we want to oversimplify it — can be pictured as preparing the content for website visitors before they visit so that when they “knock on the door”, you don’t need to go look for the content that they’re looking for. You already have it prepared and you hand it to them without any waiting.
Like Apache, Nginx’ typical setup used to be to sit between servers and the end user to relieve the performance hit on the rest of the infrastructure. In these cases, it can cache static content without the need to fetch it from the protected, origin server every time.
If we use Nginx as a standalone web server — as is the case with Kinsta LXC containers – there is no such need. Nginx is very efficient in serving static content on its own.
Then there is the matter of dynamic cache or page cache. In a WordPress website’s scenario, this means storing all WordPress pages generated for every URL in memory or on disk.
FastCGI caching is natively available in a standard Nginx installation. It is simple, very powerful, and one of the less commonly used Nginx features.
To compare this to Apache equivalents, you should know that Apache has mod_cache module which reportedly tends to be glitchy, conflicting with other modules. So the standard caching solution deployed with Apache is Varnish HTTP accelerator. Although Varnish is the dedicated industry solution, some recent tests give Nginx caching clear edge over Varnish.
Handling Requests: Nginx vs Apache
The biggest difference between Apache and Nginx is in the underlying architecture of the way they handle requests.
Apache processes requests with MPM-s or Multi-Processing-Modules, which is “responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests.”
The oldest MPM, which dates back all the way to Apache’s beginnings, is prefork module. This module alone can be credited for Apache’ performance bad reputation. Under this mode, Apache spawns new process with one thread on every request.
This module, used with mod_php, meant that Apache server embedded a PHP interpreter in every single process, even if it had to serve CSS files or images.
This was inefficient. Prefork module comes with Apache as the default module. It also restricts connections to HTTP/1.
In later years, Apache has developed multi-threaded worker mpm and after that, the event mpm. Both ot them alleviate many of Apache’s performance issues. Switching to php-fpm makes it possible for Apache to still be a competing solution today, along with eliminating the use of .htaccess, but that kind of defeats its purpose.
Nginx uses asynchronous, non-blocking event-driven architecture.
To explain the difference: in the Linux/Unix world, processes are running programs.
Threads are a subset of processes and there can be multiple threads within one process execution. Think of this as multiple tabs in a browser window. This way a program can leverage multiple CPU-s and multi-core, multi-thread CPU-s to execute faster. You can read Linus Torvalds elaborating the differences.
In short, Apache uses processes for every connection (and with worker mpm it uses threads). As traffic rises, it quickly becomes too expensive.
We can picture new process or thread creation like booting up of a computer or starting up programs. Even on the fastest of computers, it still takes some time. With websites today making hundreds of requests on a single page load, this quickly adds up.
Event mpm goes a bit further in terms of optimization, but some tests show that it can’t outrun Nginx. Especially when we talk about static files, where Nginx serves as much as double the requests that Apache does.
Nginx ideally has one worker process per CPU/core. The difference of Nginx worker processes is that each one can handle hundreds of thousands of incoming network connections per worker. There is no need to create new threads or processes for each connection.
The list of companies that take advantage of Nginx is too long to list them all, so we will end with Automattic, the private company behind WordPress.com.
Checking It in Real Life
If we want to inspect what the website in production uses, we usually can find this in the HTTP response headers. This means we will need to right-click on a website > Inspect, in the developer tools, we will choose the network panel, and then reload the website. We’ll see all the resources that the website is loading. If we choose any particular resource and its Headers tab, we will usually see the server information. If the website uses CDN, we may see something like Cloudflare in the server line or something like Varnish if the website uses HTTP accelerator.
This is an example of a WordPress website that uses a typical shared hosting setup with cPanel, Apache, and PHP:
This is a website on Nginx:
On the left side, if we expand it, we will also be able to analyze the time of every resource and see its impact on the overall page load time.
In this article, I focused on Nginx vs Apache and explained the main architectural differences that helped Nginx gaining more traction and attention within the web server arena. These are the key traits that give it the performance edge in our resource-hungry industry.
At Kinsta, we use Nginx as part of our performance-optimized hosting solutions for WordPress and WooCommerce. Every WordPress site is housed in its own isolated container, which has all of the software resources required to run it (Nginx, Linux, PHP, MySQL). The resources are 100% private and are not shared between any other sites.