A later linked-runtime check found that this campaign used one Flyology event loop while its metadata reported 16, and it did not verify every server thread's CPU affinity. Keep the files as a historical record, but do not use these tables as current performance evidence. See the corrected comparison.
A longer Linux follow-up now records seven 30-second trials on ARM64 and AMD64, and explains why its common comparison stops at concurrency one.
The physical host was a MacBook Pro (Mac15,9) with an Apple M3 Max, 16 CPU cores (12 performance and 4 efficiency), and 48 GB of memory. The container exposed all 16 cores; server and client processes used separate CPU sets.
All measured requests completed with HTTP 200 and no transport errors. The runner checked the status, content type, and exact response bytes before each measurement.
Two tiers keep the comparison narrow.
The plain tier compares direct HTTP request handlers: Flyology's raw connection handler, AWS's callback API, and EWS's dynamic handler API. Every server returns either the exact 13-byte Hello, World! body or an exact 1 KiB body.
The application tier includes framework dispatch. Flyology uses its router and exchange API. The two competitors use one identical ServletAda servlet over AWS and EWS. Plain engines and application containers never share a result table.
- Transport
- HTTP/1.1 cleartext over loopback with persistent connections.
- Physical host
- MacBook Pro (Mac15,9), Apple M3 Max, 16 cores (12 performance and 4 efficiency), and 48 GB of memory.
- Build
- Release profiles with Flyology at
-O3; GNAT 15.3.1 and gprbuild 25.0.1. - Versions
- AWS 25.2.0, EWS 1.11.0, ServletAda 1.8.2, and the backend versions recorded in metadata.
- Campaign
- Three trials, one-second warmups, three-second measurements, rotating server order, and concurrency 1, 8, and 32.
Lightweight led every measured peer row.
At concurrency 32, Flyology lightweight served 68.5 thousand plaintext requests per second. AWS served 30.6 thousand and EWS served 28.8 thousand. The 1 KiB response produced a similar ordering: 63.7, 29.9, and 26.7 thousand requests per second.
| Concurrency | Flyology lightweight | AWS | EWS |
|---|---|---|---|
| 1 | 19.6k | 18.5k | 15.2k |
| 8 | 64.9k | 44.8k | 27.8k |
| 32 | 68.5k | 30.6k | 28.8k |
Application dispatch showed the same direction. At concurrency 32, Flyology's routed lightweight fixture reached 52.6 thousand requests per second, compared with 17.5 thousand for ServletAda over AWS and 24.7 thousand for ServletAda over EWS.
| Concurrency | Flyology lightweight | ServletAda / AWS | ServletAda / EWS |
|---|---|---|---|
| 1 | 19.2k | 10.0k | 14.8k |
| 8 | 53.9k | 34.1k | 24.3k |
| 32 | 52.6k | 17.5k | 24.7k |
Native bought throughput with threads and CPU.
Flyology native was the fastest fixture in this CPU-small workload, reaching 384.0 thousand plaintext requests per second at concurrency 32. It also created 257 server threads and accumulated 91.5 CPU seconds across the plain-tier trial. Flyology lightweight used two threads and 17.25 CPU seconds.
| Server | Plaintext req/s | CPU seconds | RSS MiB | Threads |
|---|---|---|---|---|
| Flyology lightweight | 68.5k | 17.25 | 10.1 | 2 |
| Flyology native | 384.0k | 91.50 | 12.8 | 257 |
| AWS | 30.6k | 25.64 | 24.8 | 258 |
| EWS | 28.8k | 17.89 | 2.1 | 2 |
This is why the finding is about balance rather than one universal winner. Native remains useful for CPU-heavy work, blocking libraries, and cases where a large OS-thread budget is acceptable. Lightweight is the stronger result here when throughput is considered with its scheduler footprint.
Throughput does not describe the whole response shape.
Flyology lightweight's plaintext p99 latency at concurrency 32 was 0.633 ms, with p99.9 at 0.979 ms. AWS recorded 1.326 ms and 3.431 ms. EWS had a very low 0.085 ms p99, followed by a 77.476 ms p99.9 tail. The routed EWS fixture showed a similar tail at 80.241 ms.
The EWS distribution is a useful warning against reading only its median latency. It is also a reason the harness retains raw observations rather than reducing a campaign to one throughput number.
The next experiment needs real waiting.
These endpoints perform almost no application work. They do not query a database, call a remote service, serialize a meaningful object, use TLS, or exercise connection churn. The comparison therefore isolates HTTP and routing overhead more than it represents a complete application.
A database-backed follow-up should hold query, connection-pool size, response encoding, and backpressure policy constant. A nonblocking database path would test the lightweight lane's intended advantage. A blocking driver would need a bounded native executor and would measure the hybrid design instead.
The restrained conclusion is specific: on this recorded host and these verified fixtures, Flyology lightweight delivered higher median throughput than the tested AWS and EWS configurations while using two server threads.
Run the same short snapshot.
The Docker image pins Alire, GNAT, gprbuild, oha, and the Ada server dependencies. Adjust or omit the CPU sets on hosts with fewer than 16 logical CPUs.
Three-trial development command
HTTP_BENCH_TRIALS=3 \
HTTP_BENCH_DURATION=3s \
HTTP_BENCH_WARMUP=1s \
HTTP_BENCH_CONCURRENCIES="1 8 32" \
HTTP_BENCH_COOLDOWN=1 \
HTTP_BENCH_SERVER_CPUSET="0-7" \
HTTP_BENCH_CLIENT_CPUSET="8-15" \
./showcases/http-comparison/scripts/run-linux-docker.sh
For a publishable machine comparison, the repository guide recommends seven 30-second trials on an otherwise idle native-Linux host, plus a second architecture. See the complete comparison guide.