iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
There is no safe, universal Apache setting for “high traffic.” A reliable configuration starts by choosing a suitable multi-processing module (MPM), measuring the memory and latency of your actual workload, then sizing MaxRequestWorkers so Apache can serve that concurrency without exhausting RAM. Keep-alive must be short enough to prevent idle clients from monopolising capacity, and mod_status should expose enough information to prove when workers, CPU, memory or a downstream service is saturated.
For a new deployment, use the event MPM when every loaded module is thread-safe. It handles many idle keep-alive connections asynchronously, leaving request workers available for active work. Use worker when its threaded model fits your modules and workload, and retain prefork when compatibility with process-oriented or non-thread-safe modules is more important than memory efficiency. The values below are a measurement and rollout method, not a copied recipe.
What “high traffic” means in Apache
Traffic is not one number. A site can have many open connections but few requests per second, or a smaller number of expensive requests that consume every worker. Before changing Apache, define the condition you are trying to improve:
- Concurrency: active requests and open client connections at the same time.
- Throughput: requests or bytes served per second.
- Latency: especially p95 and p99 response time at the expected peak.
- Errors: 4xx/5xx responses, timeouts and upstream failures.
- Resource pressure: CPU, Apache resident memory (RSS), file descriptors, network sockets and application or database capacity.
MaxRequestWorkers is a concurrency ceiling, not a requests-per-second guarantee. Once all request workers are busy, additional work normally waits in a queue governed in part by ListenBacklog. A larger ceiling can therefore improve throughput, do nothing, or make the host slower by causing swapping and contention.
#1 Best Overall
Establish a baseline before editing configuration
Record the current MPM and modules
Use the commands supplied by your distribution to identify the active MPM and loaded modules. On installations that provide apachectl, these are useful first checks:
apachectl -V | grep SERVER_MPM
apachectl -M
apachectl -S
The first command reports the compiled MPM, the second lists loaded modules, and the third shows virtual-host and configuration-file resolution. Keep a copy of the working configuration and note the Apache version, operating system, PHP or other application integration, TLS termination, proxying and any third-party modules. A threaded MPM is appropriate only when those modules are safe in a threaded process.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchMeasure representative load
Generate traffic that resembles production: the same mix of cached and dynamic pages, request sizes, authentication, TLS, uploads, slow clients and upstream calls. Capture a baseline that includes:
- requests per second and transferred bytes;
- p50, p95 and p99 latency;
- 4xx, 5xx, timeout and reset counts;
- CPU utilisation and run-queue pressure;
- Apache RSS and total system memory, including the application, database and caches;
- open connections, active requests and queueing;
- file-descriptor use and graceful-restart duration.
Run the same scenario after each material change. Alter one variable at a time and retain the previous configuration so a regression can be reversed immediately.
Choose the right Apache MPM
Apache’s performance guidance describes worker as generally suitable for high-traffic servers because it has a smaller memory footprint than prefork. The event MPM uses a threaded design like worker, but listener threads handle much of the state for idle keep-alive connections. That allows request threads to serve new work instead of sitting on quiet sockets.
| MPM | Threaded? | Idle keep-alive behaviour | Memory and compatibility considerations | Good fit |
|---|---|---|---|---|
event |
Yes | Many idle keep-alive states can be handled asynchronously by listener threads. | Usually the best connection efficiency, but every loaded module must be thread-safe. Long-running or blocking work can still occupy request workers. | Modern static, proxy and dynamic stacks that have been verified with threaded modules. |
worker |
Yes | Threaded workers handle requests; idle connections do not receive the same event-specific treatment. | Smaller memory footprint than prefork, with the same threaded-module requirement. | High-traffic services where worker compatibility is proven and event-specific behaviour is not required. |
prefork |
No; one request process at a time | Each process model can hold a connection while it waits, so idle clients consume more process capacity. | Largest memory cost at high concurrency, but strong isolation and compatibility with modules that are not thread-safe. | Legacy process-oriented modules or applications that cannot run safely in a threaded MPM. |
Neither documentation nor a reliable benchmark establishes a guaranteed requests-per-second advantage for one MPM in every workload. Select the threaded model only after checking module compatibility and testing the request mix that matters to your users.
Switching MPMs safely
Package commands differ by distribution. On Debian or Ubuntu, a typical switch from prefork to event is:
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo apachectl configtest
sudo systemctl restart apache2
Do not run both MPM modules. On systems that manage LoadModule lines directly, enable exactly one MPM in the module configuration, run the platform’s syntax check, and restart during a controlled window. If a module or application fails under a threaded MPM, restore the previous MPM rather than masking the error with larger worker limits.
Size MaxRequestWorkers from memory and workload
MaxRequestWorkers sets the maximum number of requests Apache can serve simultaneously. Connections above that number normally wait; they are not automatically rejected, although queue limits, timeouts and upstream behaviour can turn waiting into errors.
A measurement-based sizing method
- Reserve host capacity. Set aside memory and CPU for the operating system, TLS libraries, logs, monitoring, the application runtime, caches and databases. Do not give Apache every free megabyte.
- Measure Apache under representative concurrency. Record RSS with the chosen MPM and modules while traffic is active. For prefork, observe the typical child-process footprint. For worker or event, distinguish shared process memory from the incremental cost of additional threads and request state.
- Calculate a memory ceiling. Divide the memory budget available to Apache by the measured incremental cost of one additional concurrent request. Use a conservative percentile, not the smallest process you observed. The result is a starting ceiling, not a promise of capacity.
- Check CPU and downstream limits. If the application server, database, API or disk becomes saturated first, raising
MaxRequestWorkersonly creates more waiting and can amplify failures. - Round for the selected MPM. Ensure the value can be represented by the available child processes and threads, then load-test it. Apache warns that process and worker limits above what the machine can handle can prevent startup or destabilise the host.
How the related limits fit together
Threaded MPMs use three related controls:
ServerLimitcaps the number of child processes that can be created.ThreadLimitcaps the maximum threads allowed in one child process.ThreadsPerChildsets how many worker threads each child creates.
MaxRequestWorkers must fit inside those limits. Increasing it without increasing the structural limits can leave the effective ceiling unchanged; increasing all of them blindly can consume excessive memory or make Apache refuse to start. Keep the values close to the measured requirement and restart only after a successful syntax check.
Free tools Windows power users keep installed
One-click scans. No signup required.
Documented defaults (Apache documentation accessed in 2026)
| Directive | MPM | Documented default | What it controls |
|---|---|---|---|
MaxRequestWorkers |
prefork | 256 | Maximum simultaneously served requests. |
MinSpareThreads |
worker and event | 75 | Minimum idle threads Apache tries to keep ready. |
MaxSpareThreads |
worker and event | 250 | Upper bound on idle threads before excess capacity is retired. |
ThreadsPerChild |
worker and event | 25 | Threads created in each child process. |
These defaults are starting points from the current Apache mpm_common documentation, not recommended production targets. A server with a small memory budget, expensive dynamic requests or a large TLS footprint may need fewer workers; a static-content server with measured headroom may support more.
Rank #2
Illustrative calculation
Suppose a host has 16 GB of RAM, and monitoring shows that 6 GB must remain available for the operating system, application runtime, database and cache. If testing shows that each additional concurrent Apache request consumes about 18 MB at the chosen workload, a conservative first ceiling is approximately 10 GB divided by 18 MB, or about 568 concurrent requests. You would normally round down, verify the result against CPU and upstream limits, and leave additional safety margin for spikes. This is an example of the method; substitute your measured values rather than copying 568.
Tune keep-alive without exhausting concurrency
Keep-alive avoids a new TCP and TLS setup for every object, which usually lowers latency and connection overhead. The trade-off is that an idle client can retain a connection while no request is being processed. Apache’s performance guide uses a KeepAliveTimeout default of 5 seconds as an attempt to limit that cost and cautions against raising it above about 60 seconds.
A practical policy
- Leave
KeepAlive Onwhen clients fetch multiple resources or TLS handshakes are expensive. - Start near the documented 5-second timeout and measure. Lower it when many slow or mobile clients occupy scarce capacity; raise it only when repeated connection setup is demonstrably a larger cost and concurrency remains healthy.
- Do not treat a long timeout as a cure for latency. It can increase open connections and queueing while delivering no additional completed requests.
- With
event, idle keep-alive sockets are handled more cheaply because listener threads can manage them asynchronously. Active requests, uploads and blocking application calls still consume request workers.
Review connection counts and worker states in mod_status while changing the timeout. A value that looks harmless in a synthetic test can be costly when real clients have high latency or download large responses slowly.
Understand event-specific capacity
The event MPM includes AsyncRequestWorkerFactor, documented with a default of 2 in Apache’s 2.5 development documentation accessed in 2026. It helps determine how many connections a child can accept relative to its request-worker capacity while asynchronous connection handling is in use. Because its interaction with other event limits is version-specific, change it only after reading the documentation for the exact Apache build and observing connection and worker metrics. It is not a substitute for sizing MaxRequestWorkers or fixing a blocking backend.
Expose mod_status to find the bottleneck
mod_status reports worker states, request counts and bytes served. Restrict it to a trusted administration network; an internet-facing status page can disclose operational details and become an unnecessary attack surface.
<Location /server-status>
SetHandler server-status
Require local
</Location>
Use the access-control directive appropriate for your network rather than copying Require local when administrators connect from a separate management subnet. During a test, correlate the status page with latency, errors, CPU, RSS, open connections and operating-system socket counts:
- Many workers in active processing with rising latency suggests CPU, application or downstream saturation.
- Many idle keep-alive states with few active requests points toward connection policy or client behaviour.
- A full worker set and growing wait time indicates that
MaxRequestWorkersor a downstream service is the immediate constraint. - A large number of graceful or finishing workers can indicate long requests that delay restarts and reduce effective capacity.
Disable or restrict the endpoint again after a diagnostic session if your operational policy does not require continuous access.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Account for workload shape and module compatibility
Dynamic and blocking requests
The event MPM frees workers from many idle sockets, not from CPU-heavy or blocking application work. A request waiting on a slow database, external API, file lock or application runtime can still occupy a worker. Measure those requests separately and enforce sensible upstream and application timeouts.
TLS, proxying and large uploads
TLS handshakes, reverse-proxy buffers, streaming responses and large uploads alter per-connection memory and worker duration. Include them in the load scenario used to calculate the limit. A value measured only with small static files can be unsafe for authenticated pages or uploads.
Thread safety
Inventory every loaded module before moving from prefork. A module that assumes one request per process can behave incorrectly or crash in a threaded model. If compatibility cannot be established, use prefork temporarily, reduce its concurrency expectation, and plan a migration path rather than enabling event solely because it is newer.
A controlled tuning procedure
- Save and label the known-good configuration. Include the MPM files, virtual hosts, proxy settings and service-manager overrides.
- Confirm the active MPM and module inventory. Record the Apache version and package build so later comparisons use the same binary.
- Baseline at realistic concurrency. Capture throughput, p95/p99 latency, errors, CPU, RSS, open connections and queueing.
- Select the MPM. Start with event when threaded compatibility is established; otherwise evaluate worker or prefork based on compatibility and measured memory.
- Set a conservative worker ceiling. Use the memory calculation, then align
ServerLimit,ThreadLimitandThreadsPerChildfor worker or event. - Configure keep-alive. Keep it enabled when reuse helps, begin around the 5-second documented timeout, and change it only in response to measured connection behaviour.
- Validate syntax. Run
apachectl configtest(or the equivalent command supplied by your distribution) before a restart. - Apply with a planned restart or graceful reload. Confirm that the service is healthy and that long-running requests are not leaving a large finishing-worker backlog.
- Repeat the same load test. Compare tail latency, errors, memory and queueing with the baseline; do not declare success from throughput alone.
- Keep one change per experiment. If a result worsens memory pressure, queueing or errors, restore the saved configuration and investigate before trying another variable.
Troubleshoot common saturation symptoms
| Symptom | Likely cause | Action |
|---|---|---|
| All workers are busy and response time rises | Concurrency ceiling reached, or requests are blocked on an upstream service. | Use mod_status and host metrics to distinguish Apache saturation from backend wait. Raise the ceiling only if memory, CPU and downstream capacity have measured headroom. |
| Memory climbs, swap appears or the kernel kills Apache | Worker limits exceed the safe memory budget, or request types use more memory than the baseline. | Roll back, lower MaxRequestWorkers, inspect per-request memory and include TLS, uploads and dynamic pages in the test. |
| Apache refuses to start after a limit change | ServerLimit, ThreadLimit or related values are invalid for the build or exceed what the host can support. |
Run the syntax check, restore the last known-good values, and increase limits in smaller, measured steps. |
| Many open connections but few active requests | Keep-alive timeout is too long for the client population, or slow clients are holding sockets. | Inspect status and connection metrics; shorten the timeout and retest. Event can reduce the worker cost of idle sockets but does not remove network and file-descriptor costs. |
| Crashes or application errors after enabling event or worker | A loaded module or integration is not safe in a threaded MPM. | Return to the compatible MPM, identify the offending module, and migrate only after it is replaced or verified. |
| Graceful restarts take too long | Long-running requests, uploads or slow clients keep child processes alive. | Find finishing workers in mod_status, review request and proxy timeouts, and avoid using a restart as a substitute for fixing the long-running workload. |
Operational guardrails
- Keep the status endpoint limited to trusted administration networks.
- Monitor file-descriptor and socket limits alongside Apache workers; a high worker ceiling is useless if the operating system cannot accept or retain the required connections.
- Alert on p95/p99 latency, 5xx rate, RSS, swap, open connections and queueing, not only CPU.
- Document the measured memory budget, workload mix, Apache version, MPM and every chosen directive so another administrator can reproduce the decision.
- Use graceful reloads for routine configuration changes, but schedule a full restart when a module or MPM change requires it.
Bottom line
Configure Apache for high traffic by proving capacity rather than copying a “high-performance” file. Choose event when your modules are thread-safe and idle keep-alive connections are a major part of the load; choose worker for a compatible threaded deployment; use prefork when compatibility requires process isolation. Derive MaxRequestWorkers from measured memory and downstream limits, keep KeepAliveTimeout close to the documented 5-second starting point unless testing justifies a change, and use mod_status plus host metrics to verify every adjustment. Apache publishes no universal requests-per-second figure, universal worker value or guaranteed MPM gain, so the defensible configuration is the one backed by your workload measurements and a tested rollback.
Recommended Free Tools

