Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Measure 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

  1. 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.
  2. 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.
  3. 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.
  4. Check CPU and downstream limits. If the application server, database, API or disk becomes saturated first, raising MaxRequestWorkers only creates more waiting and can amplify failures.
  5. 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:

  • ServerLimit caps the number of child processes that can be created.
  • ThreadLimit caps the maximum threads allowed in one child process.
  • ThreadsPerChild sets 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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 On when 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 MaxRequestWorkers or 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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

  1. Save and label the known-good configuration. Include the MPM files, virtual hosts, proxy settings and service-manager overrides.
  2. Confirm the active MPM and module inventory. Record the Apache version and package build so later comparisons use the same binary.
  3. Baseline at realistic concurrency. Capture throughput, p95/p99 latency, errors, CPU, RSS, open connections and queueing.
  4. Select the MPM. Start with event when threaded compatibility is established; otherwise evaluate worker or prefork based on compatibility and measured memory.
  5. Set a conservative worker ceiling. Use the memory calculation, then align ServerLimit, ThreadLimit and ThreadsPerChild for worker or event.
  6. 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.
  7. Validate syntax. Run apachectl configtest (or the equivalent command supplied by your distribution) before a restart.
  8. 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.
  9. Repeat the same load test. Compare tail latency, errors, memory and queueing with the baseline; do not declare success from throughput alone.
  10. 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.