If your site gets a few thousand visits a day, both Nginx and Apache will serve it comfortably — neither is too slow for the job. The decision is therefore not about raw throughput. It is about which one costs you less in memory, configuration effort, and ongoing maintenance on the hardware you actually have.
This comparison focuses on a realistic low-traffic deployment: a single small server, a handful of sites, dynamic content from PHP or a similar runtime, and one administrator who wants things to keep working without babysitting.
The Architectural Difference That Matters
Apache historically forks or spawns a process or thread per connection. Nginx uses an event-driven model where a small, fixed number of worker processes handle thousands of concurrent connections. On a large server the difference is throughput; on a small server the difference is memory.
Measure it directly rather than taking anyone’s word for it. On a fresh install with no traffic, compare resident memory:
# Nginx: typical idle footprint
ps -o rss= -C nginx | awk '{s+=$1} END {print s/1024" MB"}'
# Apache with prefork and a modest MaxRequestWorkers
ps -o rss= -C apache2 | awk '{s+=$1} END {print s/1024" MB"}'
Nginx typically idles at 5–15 MB total. Apache with prefork and a few dozen workers can idle at 100–200 MB because each worker is a full process. On a 1 GB server, that difference is a large fraction of your available RAM — memory that could otherwise be a database buffer pool or a PHP OPcache.
When Apache Is the Better Choice on a Small Server
Memory is not the only currency. Apache has real advantages that matter more than a 100 MB difference for some setups:
.htaccesssupport — if you host applications that manage their own rewrite rules (many PHP CMSs and e-commerce platforms ship.htaccessfiles), Apache works out of the box. Nginx cannot read.htaccess; every rule must be converted into server config.- Modular legacy features —
mod_rewritewith per-directory context, basic auth, and directory listing behaviours are all available without translation. - Simpler mental model for one site — if you run exactly one application on one vhost, the configuration burden of Nginx is low and the event model is a pure win.
- Extensive documentation and community answers — for an unusual configuration, you will find more copy-paste-ready Apache examples than Nginx ones.
When Nginx Wins
- Serving static assets and many small files — Nginx’s
sendfileand event loop are extremely efficient here. - Acting as a reverse proxy or load balancer —
proxy_passand upstream blocks are first-class, and this is the most common reason people switch. - Hosting several sites on minimal RAM — one Nginx process handles all vhosts; each Apache vhost adds to the same worker pool but you are already paying the process overhead.
- Predictable memory under traffic spikes — Nginx’s worker count is fixed, so a connection flood does not balloon memory the way an Apache prefork pool can.
The Configuration Cost of Switching
The honest cost of Nginx on a low-traffic site is the one-time conversion of rewrite rules. A typical WordPress .htaccess becomes:
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_read_timeout 120;
}
Note the second block: Nginx does not execute PHP itself; it passes requests to PHP-FPM over a socket. That is an extra service to keep running, but it also means PHP workers are a separate, tunable pool — which is an advantage on a small server, because you can size PHP memory independently of the web server.
Apache’s equivalent is mod_php or php-fpm via mod_proxy_fcgi. Modern practice on small servers is PHP-FPM for both, so this is close to a wash if you are starting fresh.
Practical: Tuning Whichever You Choose
For Apache on a small server, use the event MPM rather than prefork if your modules allow it, and set worker counts against available RAM rather than leaving defaults:
# /etc/apache2/mods-available/mpm_event.conf
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 10
MaxSpareThreads 30
ThreadsPerChild 15
MaxRequestWorkers 45
MaxConnectionsPerChild 10000
</IfModule>
For Nginx, size workers to CPU cores and cap connections per worker so you fail predictably rather than running out of memory:
# /etc/nginx/nginx.conf
worker_processes auto;
events {
worker_connections 1024;
multi_accept on;
}
client_body_buffer_size 16k;
client_max_body_size 32m;
keepalive_timeout 30;
In both cases, put a FastCGI or proxy cache in front of dynamic content. On a low-traffic site this matters more than the web server choice, because caching a page means the request never reaches PHP at all.
A Decision Rule You Can Apply Today
| Your situation | Reasonable default |
|---|---|
One application, it ships .htaccess, you value low-effort setup | Apache with event MPM |
| Several sites on a 1–2 GB server | Nginx |
| You want to add a reverse proxy or load balancer later | Nginx |
| You are comfortable maintaining config and want the smallest footprint | Nginx |
| You rely on modules available only for Apache | Apache |
The two are not exclusive, either. A common small-server pattern is Nginx terminating TLS and proxying to Apache on a local port, which gives you Nginx’s static-file efficiency and Apache’s .htaccess compatibility in one machine — at the cost of one more service to maintain.
What Actually Limits a Low-Traffic Site
At a few thousand visits a day, your web server is almost never the bottleneck. The usual culprits are an uncached database query on every page load, PHP workers set too low, or a server so small that the web tier and database compete for the same RAM. Fix those before you spend a weekend migrating web servers — you will get far more out of a page cache, a tuned OPcache, and enough memory to keep the database in RAM.
If you are at the point where the machine itself is the constraint, our VPS comparison table lists measured memory and IOPS per plan so you can pick a host whose resources line up with what your stack needs. For the tuning side, our deeper write-ups on Nginx caching and PHP worker sizing go into the settings that matter, and the FAQ covers how to tell whether you are memory-bound or CPU-bound before you buy anything.




Leave a Reply
You must be logged in to post a comment.