When optimizing PHP applications, we obsess over RPS, P99 latency, and JIT performance — but one metric is equally important for production costs: memory efficiency. In the cloud, you pay for RAM. The question isn’t just “how fast” but “how much throughput per GB of memory.”
We benchmarked PHP-FPM, Swoole, and RoadRunner — all configured with 20 workers, under 50ms database I/O delay — to find the answer. The results reveal a clear trade-off between performance and memory efficiency.
TL;DR: PHP-FPM is the most memory-efficient (2,610 RPS/GB), Swoole delivers the highest RPS (936) but uses 445 MB peak, and RoadRunner consumes the most memory (~760 MB idle) with the lowest RPS (648). Choose based on your memory budget.
🧪 Why Memory Efficiency Matters in 2026
Cloud computing costs are dominated by two resources: CPU and memory. While CPU scaling is well-understood, memory is often overlooked. In 2026, with containerized PHP workloads running on Kubernetes and serverless platforms, understanding your application’s memory footprint is essential for cost optimization.
Consider this: a 1 GB memory difference across 10 containers can cost thousands of dollars annually. Choosing a memory-efficient runtime isn’t just a technical decision — it’s a financial one.
Key Questions We Answer
- How much memory does each PHP application server actually consume?
- Which server gives you the most RPS per GB of memory?
- How does memory usage change under load?
- What’s the real cost difference in the cloud?
🧪 Test Environment
All tests were conducted on identical hardware with consistent configuration to ensure fair comparison.
- Server: 4 vCPU, 8 GB RAM, Ubuntu 22.04
- PHP: 8.5.7 with OPcache + JIT tracing, buffer 128M
- MySQL: 8.4, same host,
SLEEP(0.05)for 50ms I/O latency - Worker count: 20 workers across all environments (unified for fair comparison)
- Load generator:
ab -c 50 -t 30, 3 runs per configuration - Business logic: 1000 sqrt iterations + one
SELECT SLEEP(0.05)query - Memory measurement:
psRSS (resident memory) before and after load
We used 50ms I/O latency to simulate a typical database query in a real-world application. This represents a realistic workload where the application spends time waiting for the database.
📊 Benchmark Results
All environments configured with 20 workers for fair comparison.
| Environment | Workers | Idle Memory | Peak Memory | Memory Growth | Avg RPS | Memory Efficiency (RPS/GB) |
|---|---|---|---|---|---|---|
| PHP-FPM | 20 | 322.7 MB | 322.7 MB | 0 MB | 842 | 2,610 |
| Swoole | 20 | 295.0 MB | 445.3 MB | +150.3 MB | 936 | 2,102 |
| RoadRunner | 20 | ~760 MB | ~800 MB | +40 MB | 648 | ~810 |

Key Observations
- PHP-FPM: Most memory-efficient. 322.7 MB idle, zero growth under load.
- Swoole: Highest RPS. Memory grows from 295 MB to 445 MB (+150 MB) under load.
- RoadRunner: Highest memory usage. ~760 MB idle, lowest efficiency.

🔍 Deep Analysis: Why the Memory Differences?
PHP-FPM: The Memory Champion
PHP-FPM’s pm = static model with 20 workers consumes only ~16 MB per worker. This is because:
- Each worker is a minimal PHP process with no extra framework overhead
- OPcache shares compiled bytecode across workers
- Memory stays flat under load because workers recycle after each request
Best for: Memory-constrained environments (512 MB containers). Delivers 842 RPS with just 323 MB peak.

Swoole: The Performance King
Swoole delivers the highest RPS (936), but memory grows by 150 MB under load (+51%). Why?
- Each worker holds the entire application in memory (no per-request reload)
- Coroutines maintain state during concurrent requests
- Memory is not freed until the worker restarts
- Single-worker memory is ~22 MB — higher than FPM
Best for: Teams that need maximum throughput and can allocate 512 MB+ memory.
RoadRunner: The Heavyweight
RoadRunner’s memory footprint is the highest by far. Each worker is a full PHP process with:
- Composer autoloading (~5-10 MB per worker)
- PSR-7 request/response serialization overhead
- Go binary runtime (rr binary itself is ~56 MB)
- 20 workers × 36 MB = 720 MB + Go binary
Best for: Teams that need RoadRunner’s specific features (gRPC, queue support, HTTP/2) and can allocate sufficient memory.
Single Worker Memory Comparison
Understanding per-worker memory helps with capacity planning:
| Environment | Single Worker Memory | 20 Workers Total | Why |
|---|---|---|---|
| PHP-FPM | ~16 MB | ~320 MB | Minimal process, no framework persistence |
| Swoole | ~22 MB | ~440 MB | Application code loaded once, shared across requests |
| RoadRunner | ~36 MB | ~720 MB | PSR-7 overhead + Composer autoloading |
💰 Cloud Cost Analysis
Let’s translate these memory numbers into real cloud costs. Assuming:
- AWS EC2 t3.medium: $0.0416/hour (8 GB RAM)
- Kubernetes pod with 1 GB memory: ~$0.005/hour
- 10 containers running 24/7: ~$438/month
| Environment | Memory Required | Monthly Cost (10 containers) | RPS per $ |
|---|---|---|---|
| PHP-FPM | 1 GB | $438 | 19.2 RPS/$ |
| Swoole | 1 GB | $438 | 21.4 RPS/$ |
| RoadRunner | 2 GB | $876 | 7.4 RPS/$ |

Key insight: Swoole gives you the best RPS per dollar (21.4), but requires careful memory tuning to stay within budget.
🎯 Practical Recommendations
| Memory Budget | Recommended | Expected RPS | Why |
|---|---|---|---|
| 512 MB or less | PHP-FPM ✅ | 842 | Stable, no memory growth under load |
| 1 GB | Swoole ✅ | 936 | Highest RPS, fits within 1 GB |
| 1 GB | PHP-FPM | 842 | Simpler, more predictable |
| 1 GB or more | RoadRunner ⚠️ | 648 | Use only if features justify cost |
Recommendation by Use Case
- Microservices in small containers (512 MB): PHP-FPM is your only safe choice.
- High-throughput APIs with 1 GB+ containers: Swoole gives the best performance.
- Applications requiring gRPC or advanced queueing: RoadRunner is justified despite higher memory.
- Cost-sensitive deployments: PHP-FPM gives the most predictable cost structure.
❓ Frequently Asked Questions
Q: Why does RoadRunner use so much memory?
A: RoadRunner uses a Go binary to manage PHP workers. Each PHP worker loads Composer dependencies and PSR-7 serialization, adding ~36 MB per worker. The Go binary itself adds another ~56 MB.
Q: Can I reduce Swoole’s memory usage?
A: Yes. Reduce `worker_num` to match your CPU cores, use `opcache.jit_buffer_size = 64M`, and consider `swoole.use_shortname = Off` to save memory.
Q: Is PHP-FPM always the best choice for memory?
A: For pure memory efficiency, yes. But if your application is CPU-heavy, JIT in Swoole or RoadRunner may still be worth the memory cost.
Q: How do I monitor memory in production?
A: Use `docker stats` for containers, `ps aux | grep php` for bare metal, and `opcache_get_status()` for OPcache metrics.
📌 Key Takeaways
- PHP-FPM is the most memory-efficient — 2,610 RPS/GB, memory stays flat under load. Ideal for small containers and predictable cost.
- Swoole delivers the highest throughput — 936 RPS, but needs 150 MB extra under load. Best RPS per dollar (21.4 RPS/$).
- RoadRunner consumes the most memory — ~760 MB idle, lowest efficiency. Only use when features justify the cost.
- Memory matters in the cloud — A 1 GB memory difference across 10 containers costs ~$438/month.
- Choose based on your budget — 512 MB → PHP-FPM, 1 GB → Swoole, 2 GB → consider RoadRunner.
📁 Reproducibility
All test scripts, Dockerfiles, configurations, and raw ab output logs are available on GitHub.
To replicate:
git clone https://github.com/phpbenchlab/memory-efficiency-benchmark.git
cd memory-efficiency-benchmark
./setup.sh
./run_memory_bench.shWe’ve included:
- PHP-FPM with 20 workers configuration
- PHP + Swoole with 20 workers and coroutine support
- RoadRunner with 20 workers (including Composer autoloading)
- Memory monitoring script
- Raw result files
🔗 Related Articles
- PHP 8.5 Production Performance Tuning: From Benchmark to Real-World
- PHP 8.5 JIT Deep Tuning: tracing vs function vs off
- PHP-FPM vs RoadRunner vs Swoole: Docker vs Bare Metal Performance
- PHP 8.5 Application Server Selection Guide
- How CPU & Memory Limits Impact PHP Performance in Docker
All data from PHPBenchLab’s 2026 benchmark series. Full scripts and configurations available on GitHub.
Have you measured memory efficiency in your production PHP applications? Share your findings in the comments!
Published on August 3, 2026 – PHP 8.5 memory efficiency benchmark.