TL;DR: In I/O-bound PHP applications, reducing Docker CPU by 87% (from 4 to 0.5 vCPU) and memory by 96% (from 8 GB to 256 MB) has zero measurable impact on RPS. All configurations delivered 93–94 RPS under 50ms database latency. The bottleneck is external (database wait time), not internal (CPU or memory).
Running PHP in Docker is now standard practice, but one question persists: how much CPU and memory does your container actually need? We benchmarked PHP-FPM under various Docker resource limits — CPU quotas and memory caps — to find the breaking point. The results are surprising: in I/O-bound scenarios, resource limits barely affect throughput at all.
If your application spends most of its time waiting for databases or APIs, you may be drastically over-provisioning your containers. This benchmark shows you exactly how low you can go without impacting user experience — and when resource limits actually matter.
🧪 Test Environment
- Server: 4 vCPU, 8 GB RAM, Ubuntu 22.04
- PHP: 8.5.7 (OPcache + JIT tracing, buffer 128M)
- Database: MySQL 8.4 on same host, using
SLEEP(0.05)to simulate 50ms I/O latency - Web server: Nginx + PHP-FPM with 20 static workers (
pm.max_children = 20) - Load generator:
ab -c 50 -t 30(50 concurrent connections, 30 seconds), 3 runs per configuration - Docker resource limits: Varying combinations of
--cpus(0.5, 1, 2, unlimited) and--memory(256 MB, 512 MB, 1 GB, 8 GB), using host network mode (--network host) to eliminate network overhead
Business logic (identical across all tests):
- CPU: 1000 iterations of
sqrt($i)(light compute) - I/O:
SELECT SLEEP(0.05)(simulating a 50ms database query)
This setup mimics a typical API or microservice where the bottleneck is external latency, not local processing power.
📊 Benchmark Results: Docker CPU & Memory Limits

Key finding: All values are average requests per second (RPS) over 3 runs. Each request included a 50ms database delay. Every configuration delivered 93–94 RPS — a variation of less than 1%.
| Resource Limit | Run 1 | Run 2 | Run 3 | Avg RPS | vs Unlimited |
|---|---|---|---|---|---|
| Unlimited (4 vCPU / 8 GB) | 92.34 | 93.89 | 94.10 | 93.44 | 100% |
| 2 vCPU / 1 GB | 92.41 | 94.00 | 93.94 | 93.45 | 100% |
| 1 vCPU / 512 MB | 92.62 | 94.36 | 94.25 | 93.74 | 100.3% |
| 0.5 vCPU / 256 MB | 92.70 | 94.37 | 94.52 | 93.86 | 100.4% |
| 1 vCPU / 256 MB | 92.43 | 94.00 | 94.10 | 93.51 | 100.1% |
| 2 vCPU / 512 MB | 92.36 | 94.34 | 94.04 | 93.58 | 100.1% |
Core finding: Under I/O-bound workloads with 50ms database latency, Docker CPU and memory limits have virtually no impact on throughput. All 6 configurations delivered 93–94 RPS — a difference of less than 1% between the highest and lowest performing setups.
Quantified impact: Reducing CPU from 4 cores to 0.5 cores — an 87.5% reduction — resulted in 0% performance loss (93.86 RPS vs 93.44 RPS). Reducing memory from 8 GB to 256 MB — a 96% reduction — also resulted in 0% performance loss (93.86 RPS vs 93.44 RPS).
🔍 Analysis: Why I/O-Bound PHP Applications Are Resilient to Resource Limits

The Bottleneck Is External, Not Internal
Conclusion: In I/O-intensive applications, the bottleneck is external (database latency), not internal (CPU or memory). The PHP worker spends most of its time waiting — during a 50ms SLEEP, the worker is blocked and consumes almost no CPU or memory.
Mathematical limit: With 20 workers and 50ms per request, the theoretical maximum RPS is:
Theoretical max = (1000ms / 50ms) × 20 workers = 400 RPSWhy measured throughput is ~93 RPS: The gap between theoretical (400) and measured (93) RPS is due to FastCGI, Nginx, and connection overhead. The key insight: every configuration delivered the same RPS — proving the bottleneck is external, not internal.
When Do Docker Resource Limits Actually Matter?
Our previous CPU-intensive benchmark tells a different story. Under pure CPU load, resource limits directly capped RPS because CPU time was the bottleneck.
| Scenario | Bottleneck | Impact When Resources Halved | Recommendation |
|---|---|---|---|
| I/O-bound (database, API, network) | External latency | ✅ No impact — RPS unchanged (93.44 → 93.86) | Reduce resources aggressively to save costs |
| CPU-bound (computation, math, image processing) | Processing power | ⚠️ Significant impact — CPU quota directly caps RPS | Test workload; start with 2 vCPU |
| Memory-bound (large datasets, caching) | Memory capacity | ⚠️ Can cause OOM kills — catastrophic failure | Must accommodate dataset size |
Understanding your application’s primary bottleneck is essential for resource planning. I/O-bound apps are uniquely resilient to resource constraints.
🚀 Production Recommendations Based on This Benchmark
For I/O-Heavy Applications (APIs, Microservices, WordPress)
- You can safely reduce CPU and memory quotas without impacting user-facing performance — our data shows 0% RPS change with 87% CPU reduction.
- Recommended minimum: 1 vCPU / 512 MB per container for 20 workers (tested stable at 93 RPS).
- Aggressive cost-saving: 0.5 vCPU / 256 MB worked in our test (93.86 RPS), but leave headroom for traffic spikes.
- Monitor your database connection pool — that’s the real bottleneck in I/O-intensive apps.
For CPU-Heavy Applications (Image Processing, Data Crunching)
- CPU quotas directly limit throughput — CPU = performance ceiling.
- Start with 2 vCPU and monitor utilization; scale up if saturation occurs.
- Memory limits must accommodate your dataset size; OOM kills are catastrophic.
General Docker Resource Guidelines
- Use
--network hostfor production PHP containers to eliminate NAT overhead. - Use CPU pinning (
--cpuset-cpus) for CPU-bound workloads to prevent migration overhead. - Set
pm.max_childrenbased on memory:(RAM - 128MB) / 20MB per workeris a rough formula. - Monitor
docker statsin production to validate your limits.
📌 Key Takeaways
- I/O-bound PHP applications are remarkably resilient to resource limits. You can cut CPU by 87% and memory by 96% without losing throughput — a proven result from real benchmarks.
- The bottleneck defines the impact. Know your application’s primary bottleneck and allocate resources accordingly.
- Don’t overprovision for I/O-heavy workloads. Use our data to save cloud costs confidently — potentially up to 87% on CPU and 96% on memory costs.
- Always benchmark your own application. Your database latency and workload pattern may differ.
❓ Frequently Asked Questions
Q: Does reducing Docker CPU limits affect PHP performance?
A: It depends on your workload. In I/O-bound applications (database queries, API calls), reducing CPU from 4 to 0.5 cores had zero measurable impact on RPS (93.44 vs 93.86). For CPU-bound applications (image processing, computation), CPU quotas directly cap performance.
Q: How low can I go with memory limits?
A: Our testing found that 256 MB worked perfectly for 20 PHP-FPM workers under 50ms I/O latency, delivering 93.86 RPS — identical to 8 GB. Reducing memory from 8 GB to 256 MB is a 96% reduction with no performance loss.
Q: Should I use --network host in production?
A: Yes, for PHP containers. Host network mode eliminates NAT and iptables overhead, which can improve performance by 35–60% compared to the default bridge network, as shown in our previous Docker vs bare metal benchmark.
Q: Is this data reproducible?
A: Yes. All test scripts, Dockerfiles, and raw ab outputs are available on GitHub.
📁 Reproducibility
All test scripts, Dockerfiles, and raw ab output logs are available on GitHub.
To replicate:
git clone https://github.com/phpbenchlab/docker-resource-test.git
cd docker-resource-test
docker build -t php-fpm-bench .
./run_resource_test.sh 0 0 unlimited
# ... run other configurations
cat summary.txt🧵 Final Words
Core conclusion: In I/O-intensive PHP applications, you can dramatically reduce Docker CPU and memory limits without sacrificing performance. If your app spends most of its time waiting for databases or APIs, don’t waste money on overprovisioned containers.
Key distinction: CPU-bound tasks are a different story. Know your bottleneck, test your workload, and allocate resources accordingly.
Call to action: Have you optimized your Docker resource limits? What was your experience? Share in the comments!
Published on July 12, 2026 – Docker resource limits PHP benchmark.
🔗 Related Articles
- PHP-FPM vs RoadRunner vs Swoole: Docker vs Bare Metal Performance (2026)
- PHP 8.5 vs Node.js vs Go vs Python: CPU Performance Benchmark (2026)
- PHP 8.5 Application Server Selection Guide
- PHP 2026 Performance Trends: JIT, Swoole, Docker & Beyond
All data from PHPBenchLab’s 2026 benchmark series. Test scripts available on GitHub.