Go and PHP: capacity per core
Go, FrankenPHP and PHP-FPM on the same OAuth2 service: requests per core, CPU per request, PostgreSQL load and instance count.
OAuth2 service · medium confidence
Requests per second per core
- 14,330GoGo 1.27.1
- 6,415FrankenPHP1.12.7, worker mode
- 5,152PHP-FPMPHP 8.5.10
On four cores
Go does 2.78 times the work of PHP-FPM.
2.23 times that of FrankenPHP. The measurement was published with medium confidence; the number is a saturation ceiling, not an SLO.
Ceiling
Requests per second on four cores
req/s
- Go57,321
- FrankenPHP25,659
- PHP-FPM20,606
Ceiling
Req/s by core count
| Cores | Go | FrankenPHP | PHP-FPM |
|---|---|---|---|
| 1 | 16,883 | 6,544 | 6,218 |
| 2 | 29,449 | 14,306 | 11,211 |
| 4 | 57,321 | 25,659 | 20,606 |
Efficiency
CPU per request on four cores
µs
- Go66.77
- FrankenPHP110.74
- PHP-FPM187.74
Efficiency
FrankenPHP does not fill the core
- 0.54Used on 1 coreGo and PHP-FPM 0.98
- 1.44Used on 2 coresGo 1.87, PHP-FPM 1.95
- 2.84Used on 4 coresGo 3.83, PHP-FPM 3.87
At the ceiling
Latency and memory
| Candidate | p50 read / write | p99 read / write | RSS |
|---|---|---|---|
| Go | 1.81 / 2.42 ms | 4.69 / 5.41 ms | 30.4 MiB |
| FrankenPHP | 4.77 / 4.96 ms | 8.80 / 9.06 ms | 60.3 MiB |
| PHP-FPM | 6.03 / 6.24 ms | 8.27 / 8.45 ms | 60.0 MiB |
Database
PostgreSQL's share
| Saturating candidate | Writes + reads | PostgreSQL cores | CPU per request |
|---|---|---|---|
| Go | 24,930 + 32,392 | 2.34 | 40.75 µs |
| FrankenPHP | 12,575 + 13,084 | 1.11 | 43.2 µs |
| PHP-FPM | 10,128 + 10,478 | 1.46 | 71.07 µs |
Capacity
Cores needed for 30,000 req/s
- 2.0Go
- 3.3FrankenPHP
- 5.6PHP-FPM
Capacity
Instance count by target rate
| Target req/s | Go | FrankenPHP | PHP-FPM |
|---|---|---|---|
| 10,000 | 1 | 1 | 1 |
| 20,000 | 1 | 1 | 1 |
| 30,000 | 1 | 2 | 2 |
| 50,000 | 1 | 2 | 3 |
| 100,000 | 2 | 4 | 5 |
Tuning
Pool size and the cost of a wrong choice
| Candidate | Best pool (1/2/4 cores) | Cost of the worst choice |
|---|---|---|
| Go | 16 / 64 / 64 | 70.6% |
| PHP-FPM | 8 / 16 / 32 | 30.7% |
| FrankenPHP | 8 / 8 / 8 | 29.6% |
As you read
The limits of these numbers
- CeilingThe published number is a saturation ceiling, not an SLO. 45 of 45 repetitions passed the load-generator probe.
- EnvironmentIn one run, a headless Chromium on the host machine dropped Go to 17,490 req/s instead of 57,321; that run was discarded.
- DiskThe VM disk's fsync guarantee was not verified; absolute write numbers may be optimistic, the comparison is not affected.