Recommended Free Tools
PHP-FPM workers and PHP’s memory_limit control different bottlenecks. A worker is a PHP-FPM child process that handles a request; pm.max_children limits how many requests can run concurrently. memory_limit limits how much memory one PHP script may allocate. More workers increase potential concurrency, while a higher memory limit allows a single request to handle a larger workload. Neither setting replaces the other.
The short answer: concurrency versus per-request memory
PHP-FPM workers are the processes that execute PHP requests. The process manager creates and removes those children according to its mode and pool settings. The most important ceiling is pm.max_children: it limits the number of child processes and therefore the number of requests that can be served at the same time.
As an Amazon Associate I earn from qualifying purchases.
memory_limit is a PHP core setting. It caps the memory a single script is allowed to allocate through PHP’s memory manager. A request can hit that ceiling and fail even when several FPM workers are idle. Conversely, adding workers can let more requests run at once without helping a request that needs more memory than its current limit.
Free tools Windows power users keep installed
One-click scans. No signup required.
What “PHP workers” means in PHP-FPM
PHP-FPM (FastCGI Process Manager) keeps a pool of child processes ready to accept PHP work. Each child normally handles one request at a time. When every child is busy, additional requests wait in the web server or FastCGI queue, or are rejected by an upstream timeout or capacity limit.
#1 Best Overall
The three process-management modes
| Mode | How children are managed | Relevant settings |
|---|---|---|
static |
A fixed number of children is created. | pm.max_children |
dynamic |
The pool maintains a starting population and spare-process range, adding or removing children as demand changes. | pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers |
ondemand |
Children are spawned when requests arrive rather than being kept running in a fixed idle pool. | pm.max_children plus the mode’s idle-process behavior |
The mode changes when processes exist; it does not change the meaning of pm.max_children. In static mode, that value is the number of children. In dynamic and ondemand modes, it is the maximum number that may be created. PHP’s manual describes this as the limit on simultaneous requests served.
What happens when the worker ceiling is reached?
Suppose a pool permits 10 children and all 10 are processing requests. An eleventh request cannot create an eleventh PHP worker. It must wait in the web-server/FastCGI queue, or it may encounter an upstream limit, timeout, or “max children reached” warning. Raising memory_limit does not add a worker and does not remove this queue.
What PHP memory_limit controls
memory_limit is the maximum amount of memory, in bytes, that one PHP script is allowed to allocate. The current PHP manual documents a default of 128M and classifies the directive as INI_ALL. That is a documentation default, not a universal production recommendation; distributions, hosting panels, pool files, and application policies can set a different effective value.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →The limit applies to the individual script/request context. A large import, image transformation, report, or game-backend operation can terminate with an “Allowed memory size exhausted” error when it reaches the limit. Idle workers elsewhere in the pool do not make that particular request’s limit larger.
Setting memory_limit = -1 removes PHP’s limit. That does not make the process safe: the operating system, container, cgroup, or host still has a finite memory budget, and an unbounded script can consume it.
PHP-managed memory is not total process memory
PHP’s memory_get_usage() measurement and memory_limit concern memory reserved by PHP’s memory manager. The PHP documentation explicitly notes that this is not the total memory the operating system has given the PHP process, which is typically larger. Extensions, native libraries, allocator behavior, shared mappings, and process overhead can sit outside the amount counted by PHP.
For capacity work, inspect both levels: application measurements such as PHP memory usage and operating-system, container, or process metrics such as resident memory. Relying on only one can produce a misleading worker count.
Rank #2
Workers and memory limit compared
| Question | PHP-FPM workers | memory_limit |
|---|---|---|
| Scope | All child processes in an FPM pool and their concurrent requests | One PHP script/request context |
| What it limits | Simultaneous service capacity through pm.max_children |
PHP-managed allocation available to one script |
| Typical symptom | Queued requests, rising wait time, or “max children reached” | “Allowed memory size exhausted” |
| Main benefit of increasing it | More concurrent requests, if RAM and CPU can support them | Larger individual workloads can complete |
| Main risk of increasing it | More processes can consume aggregate RAM and CPU | A single request can consume more memory and worsen host pressure |
| Primary configuration area | FPM pool pm.* directives |
PHP core configuration; an FPM pool can also enforce it with php_admin_value |
How the two settings interact
They are separate controls, but their resource effects multiply. If pm.max_children permits 20 concurrent children and active requests commonly use 100 MB of PHP-managed memory each, a full burst could approach 2 GB of PHP-managed usage (20 × 100 MB). This is a planning estimate, not a guaranteed allocation: requests differ, workers have baseline overhead, extensions may allocate outside PHP’s tracked manager, and the operating system and other services also need memory.
Increasing the worker count therefore raises the possible aggregate demand even when memory_limit is unchanged. Increasing memory_limit raises the possible demand of each request even when the worker count is unchanged. Raising both at once can turn a queueing problem into a host-level out-of-memory event.
Why free RAM does not disprove a memory-limit error
A request can be denied by its PHP ceiling before the machine runs out of physical memory. The error means that the script reached its configured PHP allocation limit, not that every byte of host RAM was already consumed. The reverse is also possible: no request reaches memory_limit, yet many workers together, plus non-PHP allocations and other services, exhaust the host or container and trigger an OOM kill.
How requests consume both kinds of capacity
Think of a pool as a set of service slots. A request occupies one slot for its entire execution, regardless of whether it uses little or much memory. A lightweight health check and a memory-heavy report each consume one worker while running, but their process footprints can be very different. The pool therefore has two simultaneous constraints: the number of slots and the memory available to all occupied slots.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsLong-running requests make the worker constraint visible first because they hold children for longer and cause more arrivals to wait. Memory-intensive requests make the per-script constraint visible first when one operation repeatedly reaches the same allocation ceiling. A mixed workload can trigger both symptoms at once: a few large requests consume substantial RAM while ordinary requests queue behind them.
Do not assume that an idle worker represents unused memory capacity. An idle child still has baseline process overhead, and a child that is currently idle can become a large consumer as soon as it accepts a request. Conversely, a high worker count does not prove that all children are active; it only defines the maximum concurrency the pool may attempt.
An illustrative planning calculation
Use measured values rather than the nominal memory_limit when estimating aggregate demand. If 20 children are allowed and a representative active request reserves about 100 MB through PHP’s memory manager, the arithmetic is 20 × 100 MB, or roughly 2 GB for that PHP-managed portion. Add each worker’s baseline footprint, allocations by extensions and native libraries, the web server, database, caches, monitoring, and headroom for bursts. The result is a planning range, not a promise: one request may use far less or far more than the representative measurement.
Because memory_limit is a ceiling rather than a reservation, twenty workers do not automatically reserve twenty times that amount. They create the possibility that twenty requests can approach their individual ceilings simultaneously. Capacity planning should evaluate realistic concurrency and worst-case mixes, not multiply the limit blindly and assume that every request reaches it.
How to choose a worker limit
There is no safe universal number. The right value depends on available memory, CPU, other services, the PHP version and extensions, and the application’s request mix. Treat pm.max_children as a capacity decision based on measurements rather than a value copied from another server.
- Reserve memory for the whole system. Start with total RAM available to the host or container. Subtract the operating system, web server, database, caches, queues, monitoring agents, and a safety margin.
- Measure representative PHP processes. Observe process or container memory during ordinary traffic and during the heaviest realistic requests. PHP-managed usage alone is insufficient because total process memory is usually higher.
- Estimate a ceiling. Divide memory available for PHP-FPM by the measured per-worker footprint. Use a conservative figure and leave headroom for bursts, allocator variation, and extensions.
- Check CPU and latency. More children can increase throughput only while CPU, database connections, disk, and upstream services can keep up. A larger pool can otherwise create contention and longer response times.
- Validate under gradual load. Change one control at a time and watch queueing, latency, error rates, PHP memory usage, process/container memory, and OOM events.
The arithmetic is a planning aid, not a promise that every worker consumes exactly the measured amount. A pool sized to the average request can still fail when a burst contains several memory-heavy requests at once.
How to verify the effective values
The value in a file you edited is not necessarily the value used by the failing request. FPM pools can have their own directives, and different pools may serve different applications or URL paths. Check the active pool configuration and verify the request’s effective PHP settings through the diagnostics appropriate to your deployment. Compare the reported memory_limit with the pool file, the global PHP configuration, and any application-level setting.
Also confirm that a configuration reload or restart actually reached the FPM instance serving traffic. A changed file on disk does nothing for already running children until the deployment’s normal reload or restart process applies it. In multi-host or containerized systems, verify every instance; one unchanged pool can make an intermittent error appear configuration-dependent.
For worker capacity, inspect the pool’s process-management mode, current child count, queue or wait indicators, and “max children reached” events. Pair those observations with request latency and host metrics. A busy queue with low memory pressure points toward concurrency; high memory pressure with few queued requests points toward per-process or non-PHP allocations.
When should you raise memory_limit?
Raise it only when a specific request genuinely needs more PHP-managed memory and the application cannot be made more efficient. First identify the operation and its allocation pattern. Large data sets, unbounded result sets, repeated copies of arrays or strings, and image or document processing can all increase peak usage.
Rank #4
- Confirm the effective limit for the failing request rather than assuming the global
php.inivalue applies. - Look for leaks or accidental retention before granting a larger ceiling.
- Consider streaming, pagination, chunked processing, or smaller batches to reduce the peak.
- Raise the value with enough aggregate RAM for the number of requests that could run concurrently.
A higher limit fixes only the per-request ceiling. It does not increase the number of workers or shorten a queue.
Configuration precedence and hard limits
An FPM pool can set a limit with php_admin_value[memory_limit]. The FPM documentation states that a value supplied this way cannot be overridden by ini_set(). This is useful when an administrator needs a policy that application code cannot raise at runtime.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →A normal php_value[memory_limit] entry and an application-level ini_set() can have different precedence depending on the deployment. When the observed value differs from the file you edited, inspect the effective PHP/FPM configuration for the actual request context rather than changing several files at random.
Common configuration and sizing pitfalls
- Copying a worker count from another server: two hosts with the same RAM can have different databases, extensions, traffic patterns, and safety margins.
- Using
memory_limitas a worker formula: the limit is a per-script ceiling, not a guaranteed per-process footprint. Measure real process memory as well. - Counting only PHP-managed bytes: native extensions, shared libraries, allocator behavior, and process overhead can push resident memory above
memory_get_usage(). - Removing the limit casually:
-1eliminates PHP’s guardrail but not the host or container’s finite budget. - Changing both controls together: you lose the ability to tell which change helped and can increase aggregate demand before you notice the problem.
- Ignoring upstream limits: a web server, proxy, database, or container can become the bottleneck even when FPM has spare children.
- Assuming dynamic or ondemand means unlimited: both modes still obey
pm.max_children; they only change when children are created and retained.
What changing each setting can and cannot fix
Raising pm.max_children can reduce waiting when requests are healthy but arrive concurrently. It cannot repair a script that exhausts its allocation limit, and it cannot create CPU, database connections, disk throughput, or memory that the system does not have.
Raising memory_limit can let a legitimate large operation finish. It cannot make more requests run concurrently, reduce time spent waiting for a worker, or prevent an OOM kill caused by aggregate process memory. In some cases, optimizing the operation, streaming its input, or batching work is safer than increasing the ceiling.
When both queueing and allocation errors are present, map each symptom to its own control. Measure the request that fails, the queue that grows, and the total memory used during the same interval. This avoids treating a pool-capacity symptom as an application-memory problem, or treating a host-memory problem as proof that every individual request needs a larger limit.
Troubleshooting by symptom
| Symptom | Likely control to inspect first | What to check next |
|---|---|---|
| “Max children reached” warnings, queued requests, or rising wait time | Worker capacity: pm.max_children, process-management mode, and upstream limits |
Per-worker memory, CPU saturation, database capacity, queue length, and timeouts |
| “Allowed memory size exhausted” from one request | That request’s effective memory_limit and allocation pattern |
Leaks, oversized data structures, extension allocations, and whether the task can be streamed or batched |
| Host or container OOM kill without a PHP memory-limit error | Aggregate process and system memory | Total worker count, native or extension allocations, other services, cgroup limits, and available headroom |
Changing memory_limit has no effect |
Configuration precedence | Whether an FPM pool’s php_admin_value is enforcing a lower value and whether the edited configuration is the one serving the request |
Do not treat all memory errors as worker errors
If one script reports an exhausted allocation, adding workers usually increases risk rather than solving the cause. More workers can help only when the actual problem is concurrent demand waiting for available children. Separate the request-level error from pool-level queueing before changing either setting.
A safe change procedure
- Record the current effective
pm.max_children, process mode, andmemory_limitfor the affected pool and request path. - Capture a baseline for latency, queueing, error counts, PHP memory usage, process/container memory, and OOM events.
- Change one setting, not both. A worker increase tests concurrency; a memory-limit increase tests per-request capacity.
- Apply the configuration using your deployment’s normal FPM reload or restart procedure, then verify that new requests use the intended values.
- Observe normal traffic and a representative peak. Stop or roll back if host memory loses its safety margin, latency worsens, or OOM events appear.
- Document the reason, measured effect, and remaining headroom so the next change is based on evidence rather than guesswork.
Practical decision guide
- Requests wait while existing requests are healthy: investigate pool concurrency and upstream queues.
- One operation fails at a repeatable allocation size: investigate that request’s effective
memory_limitand optimize its peak usage. - The whole service is killed under bursts: measure aggregate process memory and reduce worker concurrency or other consumers before raising limits.
- Both queueing and memory errors occur: map each symptom to its own control, then change and observe them separately.
The reliable mental model is simple: workers decide how many requests may run together; memory_limit decides how much PHP-managed memory each request may claim. Capacity planning must account for both, plus memory and CPU used outside PHP’s accounting.
Frequently Asked Questions
Are PHP workers the same as the PHP memory limit?
No. A PHP-FPM worker is a child process that serves a request. The pool’s pm.max_children value limits simultaneous workers and therefore concurrent requests. memory_limit is a per-script ceiling on memory allocated through PHP’s memory manager. They address concurrency and individual request size, respectively.
How many PHP-FPM workers should I use?
There is no universal number. Reserve memory for the operating system and other services, measure total memory used by representative PHP processes during ordinary and heavy requests, and divide the memory available to FPM by a conservative per-worker footprint. Check CPU, database capacity, latency, bursts, and leave safety headroom.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, 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 minuteWhy do I get “Allowed memory size exhausted” when the server has free RAM?
The error means that one script reached its configured PHP allocation ceiling. PHP can refuse another allocation before the host runs out of physical memory. Check the request’s effective memory_limit and peak allocation pattern, then consider optimization, streaming, batching, or a carefully justified increase.
Does increasing pm.max_children increase PHP memory?
It increases possible aggregate demand, not the limit for one script. More children allow more requests to run at once, so total process memory can rise if those children become active. The exact increase depends on the request mix, worker overhead, extensions, and allocations outside PHP’s memory manager.
What is the difference between pm.max_children and memory_limit?
pm.max_children is an FPM pool concurrency ceiling: it limits the number of child processes and simultaneous requests. memory_limit is a PHP core setting that limits memory one script may allocate. Queueing and “max children reached” indicate the former; “Allowed memory size exhausted” indicates the latter.
Can I set memory_limit to -1 safely?
That removes PHP’s own per-script limit but does not remove limits imposed by the operating system, container, cgroup, or host. An unbounded script can consume enough aggregate memory to trigger an OOM kill, especially when several workers run concurrently. Use it only with deliberate capacity planning and monitoring.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Why does changing ini_set() not raise the limit?
An FPM pool may enforce php_admin_value[memory_limit]. The FPM manual states that an administrator value cannot be overridden by ini_set(). Inspect the effective configuration for the request and confirm which pool and instance serve it before editing other files.
The Bottom Line
Bottom line: PHP-FPM workers control how many requests can run concurrently, while memory_limit controls how much PHP-managed memory one request may allocate. Size and troubleshoot them separately, then validate their combined effect against total host or container memory, CPU, and upstream capacity.
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.




