Apache usually creates child processes because its active Multi-Processing Module (MPM) is maintaining enough capacity for current and expected connections. A rising count is normal when traffic increases or idle-spare settings are not met. It becomes a problem when the configured ceiling exceeds available memory, when graceful restarts leave old generations alive, or when worker and thread limits do not match.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
The safe fix is diagnostic: identify the active MPM, read the error log, inspect the mod_status scoreboard, measure memory per process, and then change one capacity setting at a time. Do not reduce the count blindly or raise MaxRequestWorkers just because requests are queuing.
As an Amazon Associate I earn from qualifying purchases.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC 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 & 11What an Apache child process does
Apache has a parent process that reads configuration, opens listening sockets, and manages a pool of children. The children handle client connections and requests. The exact meaning of “child” depends on the active MPM:
- prefork: each child is a separate process and normally handles one request at a time.
- worker: each child process contains multiple worker threads; threads handle concurrent requests.
- event: a threaded design that uses an event-driven listener for keep-alive connections, allowing worker threads to spend more time on active requests.
Therefore, a process list alone cannot tell you how much concurrency Apache is serving. Ten prefork children and ten event children represent very different numbers of possible simultaneous requests.
#1 Best Overall
Apache deliberately maintains spare capacity. When the number of idle workers falls below the configured minimum, the parent starts more children or threads. When there are more idle workers than the configured maximum, it retires some. Creation and retirement are capacity management, not automatically a leak.
How Apache decides to create children
Prefork spare-process control
In prefork, the principal controls are StartServers, MinSpareServers, MaxSpareServers, and MaxRequestWorkers. StartServers determines the initial number of children. MinSpareServers is the minimum number of idle children Apache tries to keep available, while MaxSpareServers is the upper target for idle children. MaxRequestWorkers is the maximum number of simultaneous requests and, in prefork, is also the maximum number of child processes.
When demand consumes idle children below MinSpareServers, the parent accelerates creation. The Apache Software Foundation’s prefork documentation describes the ramp this way: “It will spawn one, wait a second, then spawn two, wait a second, then spawn four.” A sudden burst in the process list can therefore be the expected response to sustained shortage of idle children.
The current Apache 2.4 common-MPM documentation lists 256 as the documented default MaxRequestWorkers value for the prefork case. That is a ceiling, not a target and not a recommendation for every host. Raising it beyond the prefork limit also requires a suitable ServerLimit.
Rank #2
- Used Book in Good Condition
Worker and event process arithmetic
With worker and event, MaxRequestWorkers counts request-handling threads, not child processes. ThreadsPerChild sets the number of threads in each child. ServerLimit sets the maximum number of active child processes.
A useful planning approximation is:
required child processes ≈ ceil(MaxRequestWorkers ÷ ThreadsPerChild)
Free tools Windows power users keep installed
One-click scans. No signup required.
The actual count is bounded by ServerLimit, startup behavior, spare-thread settings, and the state of existing children. For example, a threaded configuration can serve a given concurrency with fewer processes than prefork, but each process still has its own memory footprint and module compatibility considerations.
The Apache documentation states that connection attempts above MaxRequestWorkers are normally queued. Queueing can be preferable to exhausting RAM, so a queue is not by itself proof that the limit should be raised.
What each capacity directive means
| Directive | Applies primarily to | What it controls | How to interpret a high value |
|---|---|---|---|
StartServers |
prefork, worker, event | Initial child-process count after startup | More processes appear immediately after a restart; it does not set the long-term ceiling. |
MinSpareServers |
prefork | Minimum idle prefork children Apache tries to keep | A high value intentionally keeps more idle processes. |
MaxSpareServers |
prefork | Upper target for idle prefork children | Too high a value lets idle processes remain resident longer. |
MinSpareThreads |
worker, event | Minimum idle request threads | Apache may start additional child processes to restore spare threads. |
MaxSpareThreads |
worker, event | Upper target for idle request threads | A high target can preserve more process and thread capacity than traffic needs. |
ThreadsPerChild |
worker, event | Threads in each child process | Higher values can reduce process count for the same thread total, but alter memory and module behavior. |
MaxRequestWorkers |
all MPMs | Maximum simultaneous requests; threads for worker/event, processes for prefork | A high ceiling can consume all available memory under concurrency. |
ServerLimit |
all MPMs | Hard upper bound on child processes | It limits how far Apache can scale the process pool; oversized values reserve a potentially unsafe configuration range. |
MaxConnectionsPerChild |
all MPMs | Connections a child serves before exiting | A low value causes regular recycling; a high value keeps children longer. It is not a substitute for fixing a leak. |
The current Apache 2.4 documentation records hard ServerLimit ceilings of 20,000 for worker/event and 200,000 for prefork. Those are implementation limits, not safe operating points. Apache warns that setting ServerLimit and MaxRequestWorkers beyond what the system can handle can prevent startup or destabilize the host.
Why the process count can look excessive
Real concurrency and bursty traffic
Every active request consumes capacity. A traffic burst, a slow upstream application, large downloads, or clients that hold connections open can reduce the idle pool. Apache then creates more children or threads to maintain its spare target. If demand repeatedly rises and falls, the process list will fluctuate as children are added and retired.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsSpare settings are deliberately generous
A server configured with high MinSpareServers, MinSpareThreads, or related startup values is choosing faster burst response in exchange for resident memory. Seeing many idle workers may therefore indicate policy, not runaway behavior. Compare the configured spare target with measured traffic before changing it.
Configured ceilings exceed the host’s memory budget
Prefork processes can carry an application runtime and loaded modules in each process. Worker and event share more code within a process but still require memory for every process and thread. A large MaxRequestWorkers value can look harmless while idle, then trigger swapping when many requests become active. Swapping increases latency and can make Apache appear to create and kill workers continuously as the system struggles.
Rank #4
Graceful restarts leave old children alive
A graceful restart starts a new generation while old children finish existing connections. The event MPM exposes old or stopping processes in its scoreboard. Slow clients, long keep-alive periods, streaming responses, and blocked application calls can keep those children in a Graceful state for a long time. During that interval, the process list contains both the new generation and the old one.
Frequent reloads can create several overlapping generations. This is not solved by raising ServerLimit; investigate why restarts occur and why old connections do not finish.
Thread and process arithmetic is inconsistent
For worker and event, the process count needed for a requested concurrency depends on ThreadsPerChild. If MaxRequestWorkers is not an appropriate multiple of ThreadsPerChild, Apache may round the usable capacity and start a process count that surprises you. If ServerLimit is too low for the required number of children, Apache cannot create the configured thread total. If it is set much higher than needed, an incident or configuration change can permit more processes than the host can safely support.
Connection recycling is intentional
MaxConnectionsPerChild causes a child to exit after serving a specified number of connections. Administrators sometimes use it to contain gradual memory growth or refresh long-lived processes. Exits followed by replacements can look like a loop. Check the directive and correlate exits with the error log before treating recycling as a fault.
Best Value
- Used Book in Good Condition
A safe troubleshooting sequence
- Identify the active MPM and Apache version. Use the module-list command supplied by your distribution, commonly
apachectl -M,apache2ctl -M, orhttpd -M, and look for the loadedmpm_prefork_module,mpm_worker_module, ormpm_event_module. Record the version shown by your distribution’s version command. Do not tune directives for a different MPM than the one actually loaded. - Read the error log during the event. Search for
MaxRequestWorkers, scoreboard-limit messages, child exits, graceful-restart notices, and startup warnings. A message that requests are being queued points to saturation; repeated graceful or stopping messages point to lifecycle pressure; a startup refusal points to an invalid limit relationship. - Inspect
server-statusormod_status. Compare busy and idle workers, process IDs, generation numbers, and states such as Gracefully finishing or open connections. The scoreboard distinguishes active work from idle capacity and reveals whether old generations are accumulating. Restrict this endpoint to administrators; it exposes operational details. - Record every related directive. Capture
StartServers,MinSpareServers,MaxSpareServers,MinSpareThreads,MaxSpareThreads,ThreadsPerChild,MaxRequestWorkers,ServerLimit, andMaxConnectionsPerChild. Include values inherited from included configuration files, not only the file you normally edit. - Measure resident memory. Sample representative Apache children while the server is idle and under normal peak load. Account for the operating system, TLS, Apache modules, the application runtime, file-cache needs, and database clients. Use the measured per-process and per-thread costs to establish a memory budget; do not multiply a vendor’s theoretical value or copy a large limit from another host.
- Check connection behavior. Look for long keep-alive sessions, slow uploads, streaming responses, blocked backends, and clients that remain connected while doing little work. These can occupy workers or keep graceful children from exiting even when request rates seem modest.
- Check restart frequency. Correlate deployment hooks, certificate renewal, log rotation, configuration management, and watchdog actions with the appearance of old generations. A frequent graceful restart can explain a persistently elevated process count.
- Change one control at a time. Validate the configuration, reload gracefully, and watch memory, swap, queueing, busy/idle workers, and old-generation counts. Keep a record of the before-and-after values so a rollback is unambiguous.
Choose the fix that matches the evidence
Prefork falls below its spare target during genuine demand
If the scoreboard shows that traffic is consuming idle children and the host has memory headroom, keep spare settings proportional to the observed burst rather than setting them arbitrarily high. A modest increase can reduce repeated spawn cycles. Keep MaxRequestWorkers within the measured memory budget; prefork’s process-per-request model makes an oversized ceiling especially expensive.
MaxRequestWorkers is reached but memory is available
Confirm that requests are actually queued at the Apache limit, that the application backend can use the additional concurrency, and that file descriptors and downstream services have capacity. Increase MaxRequestWorkers cautiously. For prefork, raise ServerLimit when the Apache documentation requires it for the new ceiling. For worker/event, make sure the resulting thread total can be represented by the available ServerLimit and ThreadsPerChild relationship.
Recommended Free Tools
Memory pressure or swapping appears
Lower MaxRequestWorkers and spare limits to keep concurrency inside the host’s memory budget. Reduce per-process application cost where possible, and consider moving application execution to a separate process manager so web-server capacity and application-worker capacity can be controlled independently. Do not respond to swapping by increasing Apache limits.
Event shows many Graceful or old-generation processes
Investigate restart frequency, keep-alive duration, slow clients, streaming endpoints, and requests waiting on upstream services. Use the scoreboard and error log to identify which generation is stopping and how long it remains. Raising ServerLimit only permits more overlap; it does not make old children finish sooner.
Worker/event values do not divide cleanly
Choose a MaxRequestWorkers value that is an appropriate multiple of ThreadsPerChild for the intended capacity, then verify that ServerLimit can provide the necessary number of child processes. Recheck the result in server-status; the configured arithmetic is a planning boundary, not a guarantee that every process will be equally busy.
Comparing prefork, worker, and event
| Axis | Prefork | Worker | Event |
|---|---|---|---|
| Concurrency unit | One request per child process | Request-handling threads inside child processes | Request-handling threads plus event-driven keep-alive handling |
| How process count relates to load | Approximately the number of simultaneous requests, up to MaxRequestWorkers |
Approximately required threads divided by ThreadsPerChild, bounded by ServerLimit |
Similar thread/process arithmetic, with keep-alive connections handled more efficiently when conditions permit |
| Memory behavior | Each child carries its own process overhead and commonly a copy of loaded application state | Fewer processes can provide the same thread count, but each process contains multiple threads | Shares the threaded model and can avoid tying a worker thread to an idle keep-alive connection |
| Module compatibility | Most forgiving for modules that are not thread-safe | Requires modules and application libraries to be thread-safe | Has the same threaded-compatibility requirement as worker |
| Graceful-restart visibility | Old children remain until their connections finish | Old threaded children remain until their work and connections finish | Scoreboard states make old-generation and Graceful processes particularly important to inspect |
| Useful operational view | Process count and busy/idle children | Process count plus busy/idle threads | Process generations, thread states, keep-alive behavior, and graceful states |
The appropriate MPM is the one compatible with your modules and application while meeting measured concurrency within memory and file-descriptor limits. A lower process count is not automatically better if it forces excessive threads, increases queueing, or breaks a required module.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →How to tell normal churn from a fault
- Usually normal: the count rises with traffic, idle workers return toward the configured spare range, memory remains stable, and the log contains no repeated limit or child-failure warnings.
- Needs tuning: the count remains far above the spare target, the host swaps, or requests queue while substantial memory is still free.
- Needs lifecycle investigation: many processes are marked Graceful or belong to old generations after repeated reloads.
- Needs configuration correction: Apache refuses to start, reports an impossible scoreboard or worker limit, or cannot reach the configured thread total because
ServerLimitis too low. - Needs application investigation: workers stay busy on slow upstream calls, uploads, downloads, or streaming responses while incoming traffic is not high enough to explain the occupancy.
Common mistakes to avoid
- Counting processes without first identifying the MPM.
- Treating the documented default of 256 prefork workers as a performance goal.
- Raising
ServerLimitandMaxRequestWorkerstogether without measuring resident memory and swap behavior. - Using
MaxConnectionsPerChildto hide a leak without checking why memory grows. - Increasing limits when the real cause is frequent graceful restarts or slow clients.
- Changing several directives in one deployment, making it impossible to tell which change helped or harmed.
- Assuming fewer processes always means better performance; threaded MPMs trade process count against thread safety, per-process cost, and compatibility.
A practical decision rule
Set capacity from observations, not from the largest number Apache accepts. First determine which MPM is active and how many busy, idle, stopping, and old-generation workers exist. Then establish the memory available after the operating system and dependent services are accounted for. Select spare settings that cover normal bursts, set MaxRequestWorkers below the point where memory pressure begins, and ensure ServerLimit and ThreadsPerChild describe the same intended concurrency. Recheck after a graceful reload and under representative peak traffic.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




