When a website's traffic grows, the web server's defaults stop being good enough: pages slow down, memory runs out and requests start to queue. Apache and Nginx can both handle heavy traffic, but each needs a few settings sized for your server and your application. This guide covers the changes that matter most in 2026, and how to measure whether they worked.
Everything here changes server-wide configuration, so it needs root access on a VPS or dedicated server. On Domain India shared hosting, the web server is managed for every account on the server and you can't change it. To speed up a site on shared hosting, see My website is slow.
Measure before and after every change. On Apache, use the event MPM with PHP-FPM, size MaxRequestWorkers to your RAM, keep KeepAlive on with a short timeout, and enable compression and browser caching. On Nginx, set worker_processes auto, raise worker_connections and the open-file limit, cache static files and, where it suits the application, use short-lived page caching. Nginx in front of Apache or several app servers gives you caching and load balancing in one place. Beyond that, a CDN and application caching do more than any server setting.
1. Measure first
Tuning without numbers is guessing. Before you change anything, record:
- Response time and throughput under load, with a tool such as
wrk,k6orabrun from another machine, never from the server itself. - Memory and CPU while the test runs:
top,free -mandvmstat 1. - Errors in the logs:
/var/log/apache2/or/var/log/httpd/, and/var/log/nginx/.
wrk -t4 -c200 -d60s https://www.example.com/Test a page that represents real traffic, change one thing at a time, and test again. Test on a staging copy where you can.
2. Apache or Nginx?
| Aspect | Apache | Nginx |
|---|---|---|
| Architecture | Processes and threads (MPM) | Event-driven, a few worker processes |
| Per-directory config | .htaccess supported | No .htaccess; all config is central |
| Static files | Good | Excellent, very low memory |
| PHP | Through PHP-FPM (or mod_php with prefork) | Through PHP-FPM only |
| Common role | Application server, .htaccess compatibility | Front-end proxy, static files, load balancer |
Many high-traffic setups use both: Nginx at the front for TLS, static files and caching, with Apache or application servers behind it.
3. Tuning Apache
Use the event MPM with PHP-FPM
Apache's Multi-Processing Module (MPM) decides how it handles connections. Event is the modern choice: it uses threads and handles idle keep-alive connections cheaply. Prefork runs one process per connection and exists mainly for the old mod_php, which is not thread-safe. Run PHP through PHP-FPM instead, and you can use event.
On Debian or Ubuntu:
sudo a2dismod php8.3 mpm_prefork # use the mod_php version you have, if any
sudo a2enmod mpm_event proxy_fcgi setenvif
sudo a2enconf php8.3-fpm # match your installed PHP-FPM version
sudo apachectl configtest && sudo systemctl restart apache2On AlmaLinux or Rocky Linux, the MPM is chosen in /etc/httpd/conf.modules.d/00-mpm.conf, and PHP-FPM is the default.
Size the workers to your memory
MaxRequestWorkers is the number of requests Apache serves at once. Too high and the server swaps; too low and visitors queue. With event, the threads are light; the real memory cost is in PHP-FPM, which you size separately (section 5).
<IfModule mpm_event_module>
StartServers 2
ServerLimit 16
ThreadsPerChild 25
MaxRequestWorkers 400
MinSpareThreads 50
MaxSpareThreads 150
MaxConnectionsPerChild 0
</IfModule>MaxRequestWorkers must not exceed ServerLimit × ThreadsPerChild. These numbers are a starting point for a server with a few GB of RAM; adjust them against your measurements.
Keep-alive and timeouts
KeepAlive On
MaxKeepAliveRequests 500
KeepAliveTimeout 3
Timeout 60A short KeepAliveTimeout frees connections quickly while still letting one browser fetch a page's assets over a single connection.
Compression, caching headers and HTTP/2
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json image/svg+xml
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 30 days"
ExpiresByType text/css "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
</IfModule>
Protocols h2 http/1.1Enable the modules with a2enmod deflate expires http2 on Debian and Ubuntu. HTTP/2 needs the event (or worker) MPM. mod_brotli compresses text better than deflate, if your build includes it. Disable modules you don't use, such as status on a public vhost, autoindex or cgi; but never disable ssl on an HTTPS site.
4. Tuning Nginx
Workers and connections
worker_processes auto; # one per CPU core
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
}Each connection uses a file descriptor, and a proxied request uses two, so raise the open-file limit with the connection count.
Keep-alive, compression and static files
http {
sendfile on;
tcp_nopush on;
keepalive_timeout 15s;
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
open_file_cache max=10000 inactive=60s;
}Serve static assets straight from disk with long cache headers:
location ~* \.(css|js|png|jpg|jpeg|gif|webp|avif|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
}For HTTP/2, Nginx 1.25.1 and later use a separate http2 on; directive in the server block; older versions put http2 on the listen 443 ssl line. Check yours with nginx -v.
Buffers and body size
Defaults suit most sites. Set client_max_body_size to the largest upload your application really needs (for example 64m), rather than the 1 MB default, and short client_header_timeout and client_body_timeout values (10–15s) to drop slow clients.
5. Size PHP-FPM, or everything else is wasted
With either web server, PHP-FPM usually limits throughput. In the pool file (for example /etc/php/8.3/fpm/pool.d/www.conf):
pm = dynamic
pm.max_children = 40
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 12
pm.max_requests = 500Work out pm.max_children as the RAM you can give PHP divided by the average memory of one PHP process (check it with ps -o rss -C php-fpm8.3, or php-fpm on RHEL-family systems). Enable OPcache as well; see the PHP OPcache guide.
6. Nginx as reverse proxy, cache and load balancer
upstream app_servers {
least_conn;
server 10.0.0.11:8080;
server 10.0.0.12:8080;
keepalive 32;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=pages:50m inactive=10m max_size=1g;
server {
location / {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache pages;
proxy_cache_valid 200 1m;
proxy_cache_use_stale error timeout updating;
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
}
}The balancing methods are round robin (the default), least_conn and ip_hash for sticky clients. Even a one-minute cache of public pages absorbs a traffic spike. Never cache pages for logged-in users: bypass the cache on the session cookie, as above, and check your application's cookie name. When Apache sits behind Nginx, enable mod_remoteip so Apache logs the visitor's real IP address.
Run sudo apachectl configtest or sudo nginx -t before reloading. A reload with a broken configuration can take every site on the server offline. Prefer systemctl reload to restart, so open connections finish.
7. Handling traffic spikes
- A CDN serves images, CSS and JavaScript from locations near your visitors and takes most of that load off your server.
- Application caching: a full-page cache for your CMS and an object cache (Redis or Memcached) for database results.
- Rate limiting with Nginx's
limit_reqprotects login pages and APIs from floods. - Scaling out: add application servers behind the load balancer when one server is no longer enough.
8. Monitoring
Enable Nginx's stub_status or Apache's mod_status on a location reachable only from localhost or your own IP, and feed the numbers to a monitoring tool such as Prometheus with Grafana, Zabbix or Netdata. Watch active connections, request rate, response time, 5xx errors and memory. Log the upstream response time in Nginx ($upstream_response_time) to see whether slowness comes from the web server or the application.
9. Where Domain India fits
On Domain India shared hosting, the servers run Apache; on cPanel, Nginx sits in front of Apache as a cache. That is managed for you. Speed up your site with a caching plugin (for WordPress, WP Super Cache or W3 Total Cache), image optimisation and a CDN.
When you need to tune the web server yourself, a VPS gives you full root access. VPS plans are self-managed: you install and configure Apache, Nginx and PHP-FPM, with or without a control panel. Prices on the cards are live and exclude 18% GST.
- 2 vCPU
- 4 GB DDR4 RAM
- 128 GB NVMe SSD Storage
- 3 TB Monthly Bandwidth
- 4 vCPU
- 8 GB DDR4 RAM
- 256 GB NVMe SSD Storage
- 5 TB Monthly Bandwidth
Which Apache MPM is best for high traffic?
The event MPM, with PHP running through PHP-FPM. It handles many connections with little memory and supports HTTP/2. Prefork is needed only for the old mod_php module, which does not work with threaded MPMs.
How do I choose MaxRequestWorkers?
Start from your server's memory and measure. With the event MPM the Apache threads are light, and the memory cost is mostly in PHP-FPM, so size pm.max_children from the RAM available to PHP and set MaxRequestWorkers no higher than ServerLimit times ThreadsPerChild.
Should I put Nginx in front of Apache?
It often helps on busy sites. Nginx handles TLS, static files and page caching efficiently, while Apache keeps .htaccess compatibility for the application. Remember to pass the visitor's IP to Apache with mod_remoteip.
How many worker_connections should Nginx have?
1024 is the usual default; 4096 or more suits busy servers, provided worker_rlimit_nofile and the system's open-file limit are raised to match. A proxied request uses two connections.
Can I change Apache or Nginx settings on Domain India shared hosting?
No. On shared hosting the web server is shared by every account, so its configuration is managed for you. Use a caching plugin, optimise images and use a CDN, or move to a VPS if you need to tune the server.
Does enabling HTTP/2 need any changes?
On Apache, enable mod_http2 with the event MPM and add Protocols h2 http/1.1. On Nginx 1.25.1 and later, add http2 on; to the HTTPS server block; older versions add http2 to the listen line. HTTP/2 works only over HTTPS in browsers.
Ready to take control of your web server? Compare VPS plans, compare Nginx and Caddy as app gateways, or open a support ticket if your site on shared hosting is slow.
Self-managed KVM VPS plans with full root access, so you control Apache, Nginx and PHP-FPM.
See VPS plans