Nginx vs Apache: Performance, Config, and When to Use Each

- Nginx vs Apache: What's the Real Difference?
- A Quick History (and Why It Explains Everything)
- How Each Server Handles Requests
- Nginx vs Apache Performance
- Configuration: Two Different Philosophies
- Apache or Nginx for WordPress?
- When to Use Apache
- When to Use Nginx
- Can You Use Both Together?
- The Bottom Line
Nginx vs Apache: What's the Real Difference?
Nginx and Apache are the two web servers you're most likely to meet on a Linux box, and the honest answer is that both are excellent. The real difference is architectural: Nginx uses an event-driven model that handles many connections per worker process, while Apache traditionally dedicates a process or thread to each connection. That makes Nginx leaner under heavy concurrency and a natural fit as a reverse proxy, while Apache offers per-directory .htaccess overrides and a deep module ecosystem that shared hosts and legacy apps depend on.
Neither choice will sink your project. But the differences in performance behavior, configuration style, and operational habits are real, and they matter more as your traffic grows. This guide walks through each one so you can pick deliberately rather than by default.
A Quick History (and Why It Explains Everything)
Apache HTTP Server dates back to 1995 and powered a huge share of the early web. It was built in an era when a server handling a few hundred simultaneous connections was doing well, so its design — spawn a process or thread per connection — was perfectly reasonable.
Nginx (pronounced "engine-x") was released in 2004 by Igor Sysoev, written specifically to address the C10K problem: how do you serve ten thousand concurrent connections on one machine? Its answer was an asynchronous, event-driven core where a small, fixed number of worker processes each juggle thousands of connections using non-blocking I/O.
That origin story explains almost every practical difference between the two. Apache optimizes for flexibility and per-site customization; Nginx optimizes for predictable resource use at scale.
How Each Server Handles Requests
Apache: processes, threads, and MPMs
Apache's connection handling is pluggable through Multi-Processing Modules (MPMs):
- prefork — one process per connection. No threads, so it's safe with non-thread-safe modules like classic
mod_php, but memory use climbs steeply with traffic. - worker — multiple threads per process. Lighter than prefork, still one thread per connection.
- event — the default on modern distributions when
mod_phpisn't installed. It keeps threads free during keep-alive waits, which closes much of the gap with Nginx.
The catch: if you install mod_php, Apache typically falls back to prefork, the heaviest option. Running PHP-FPM behind Apache via mod_proxy_fcgi avoids this and lets you keep the event MPM.
Nginx: the event loop
Nginx starts a master process plus a small number of worker processes — commonly one per CPU core. Each worker runs an event loop that services thousands of connections without allocating a thread to each one. Memory use stays low and roughly flat as connection counts rise, which is why Nginx became the go-to choice for busy sites, reverse proxies, and load balancers.
The trade-off is that Nginx workers must never block. That's why Nginx doesn't embed language runtimes the way mod_php embeds PHP: dynamic requests are handed to a separate backend, usually PHP-FPM over FastCGI in a LEMP stack.
Nginx vs Apache Performance
Static content
For static files — images, CSS, JavaScript, downloads — Nginx generally serves more requests per second with less memory, and the advantage widens as concurrency climbs. Apache with the event MPM performs respectably, but Apache with prefork under high concurrency can exhaust RAM and start swapping, which is the failure mode behind many "server died under load" stories.
We won't quote specific benchmark numbers here because they vary enormously with hardware, kernel tuning, file sizes, and connection patterns. The honest general finding, consistent across years of independent testing, is: Nginx holds a clear edge on static content at high concurrency; at low traffic the difference is negligible.
Dynamic content (PHP)
For PHP applications the picture flattens, because the web server isn't doing the heavy work — PHP is. Whether the request path is Nginx → PHP-FPM or Apache → PHP-FPM, the time is dominated by PHP execution and database queries. A well-configured Apache event + PHP-FPM setup and a Nginx + PHP-FPM setup will feel very similar for typical dynamic workloads.
Where Nginx still pulls ahead is everything around the PHP request: serving the page's static assets, holding thousands of keep-alive connections cheaply, and acting as a caching or proxy layer.
Configuration: Two Different Philosophies
Central config vs .htaccess
This is the difference you'll feel daily.
Apache allows per-directory configuration through .htaccess files. Any directory can carry its own rewrite rules, access controls, and overrides, applied without touching the main config or reloading the server. It's why shared hosting standardized on Apache: customers can self-serve rules without root access. The cost is performance and debuggability — Apache must check for .htaccess files along the filesystem path on requests, and rules scattered across directories are harder to audit.
Nginx has no .htaccess equivalent, deliberately. All configuration lives centrally (on Debian/Ubuntu, under /etc/nginx/, with per-site files in sites-available/), and changes take effect only when you test with nginx -t and reload. That's more disciplined and faster at runtime, but it means every change requires shell access.
What the configs look like
A minimal Apache virtual host:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example.com
</VirtualHost>
The equivalent Nginx server block, with a PHP handoff included:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
(The socket path above matches PHP 8.3 on Ubuntu 24.04 — adjust it to your installed PHP version.) If the Nginx style appeals to you, our guide to Nginx server blocks walks through hosting multiple sites this way, line by line.
At a glance
| Nginx | Apache | |
|---|---|---|
| Architecture | Event-driven, async workers | Process/thread per connection (MPM-dependent) |
| Static file performance | Excellent, low memory at high concurrency | Good with event MPM; weak with prefork |
| PHP handling | External PHP-FPM via FastCGI | Embedded mod_php or external PHP-FPM |
| Per-directory config | No — central config only | Yes — .htaccess |
| Config style | Declarative blocks, must reload | Directives + runtime overrides |
| Typical extra roles | Reverse proxy, load balancer, cache | Broad module ecosystem |
| Best known for | Concurrency and efficiency | Flexibility and compatibility |
Apache or Nginx for WordPress?
WordPress runs well on both, and the WordPress ecosystem supports both officially. The practical considerations:
- On shared hosting, you rarely get a choice — it's usually Apache, and WordPress's pretty permalinks work out of the box via the
.htaccessfile WordPress writes itself. - On your own VPS, Nginx + PHP-FPM is a very common and well-documented pairing. Permalinks need one line — the
try_files $uri $uri/ /index.php?$args;shown above — instead of.htaccessrewrites. - Plugins that write
.htaccessrules (some caching and security plugins) need manual translation to Nginx directives. Most major plugins document their Nginx equivalents.
If you're building a fresh WordPress server today and are comfortable editing config files over SSH, Nginx is the mainstream recommendation for its efficiency and simpler request path. If you depend on .htaccess-driven workflows or tooling, Apache remains a fully legitimate choice.
When to Use Apache
Choose Apache when:
- You're on shared hosting or building for it —
.htaccesssupport is non-negotiable there. - Users need per-directory self-service without root access.
- A legacy app documents only Apache, with rewrite rules and module dependencies you'd otherwise have to port.
- You need a specific Apache module with no mature Nginx equivalent.
When to Use Nginx
Choose Nginx when:
- You're building a LEMP stack — it's the "E" in the acronym, and the ecosystem of tutorials and configs is deep. Our walkthrough shows how to install a full LEMP stack on Ubuntu 24.04 from a bare server.
- You expect high concurrency — many simultaneous visitors, long-lived connections, or lots of static assets.
- You want one tool for serving, proxying, and load balancing — Nginx does all three natively.
- You're on a small VPS where predictable, low memory use is the difference between stable and swapping.
Can You Use Both Together?
Yes, and it's a classic pattern: Nginx in front, Apache behind. Nginx faces the internet, serves static files directly, terminates TLS, and proxies dynamic requests to Apache listening on a local port. You get Nginx's concurrency at the edge and keep .htaccess compatibility for the application.
It's a genuinely useful migration path for legacy Apache apps. For a new build, though, it's usually unnecessary complexity — Nginx + PHP-FPM covers the same ground with one less moving part.
The Bottom Line
Is Nginx better than Apache? For high-concurrency serving, static content, and reverse proxying — yes, measurably. For per-directory flexibility, shared-hosting compatibility, and legacy module support — Apache still wins. For a typical PHP site with both servers configured well, the performance difference is smaller than most comparisons imply, because PHP-FPM does the heavy lifting either way.
Our default recommendation for a new self-managed server is Nginx: central config that's easy to audit, excellent efficiency, and a huge tutorial ecosystem — including the rest of our stack guides. Whichever you choose, configure it deliberately, test changes before reloading, and you'll be ahead of most of the internet.