Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ A modern C++ HTTP server implementation with routing, testing, and CI-driven qua
## Table of Contents

* [Features](#features)
* [Benchmark Results](#benchmark-results)
* [Benchmark Comparison](#benchmark-comparison-cpp_http_server-versus-express-server)
* [Usage](#usage)
* [Project Structure](#project-structure)
* [Using Docker](#using-docker)
Expand Down Expand Up @@ -40,6 +42,58 @@ A modern C++ HTTP server implementation with routing, testing, and CI-driven qua

---

## Benchmark Results

This project was benchmarked using k6 to evaluate HTTP request throughput, latency, and stability under sustained load. It sustained ~27,000 RPS locally with p99 < 30 ms (using a Ryzen 5 5600G). Keep in mind, that this was a local benchmark that does not reflect real networks and it does not utilize TLS, auth, databases, or disk usage. Check out `benchmarks/benchmark-results.txt` to see the benchmark results captured with k6.

### Test Setup

Load generator: k6 (local execution)
Scenario: `constant_request_rate`
Target rate: 30,000 requests/second
Duration: 10 seconds
Max VUs: 20,000 (only reached a maximum of 945 VUs)

Client machine:
AMD Ryzen 5 5600G (local Linux system)

The load generator and server were executed locally. As a result, the benchmark reflects the combined limits of the server and the client machine.

### Interpretation

- The server maintained low and stable latency even at very high request rates.
- No errors or timeouts occurred, indicating the server was not saturated.
- The test experienced dropped iterations, which suggests the benchmark was limited by the local load generator and PC hardware, not the server itself.

As such, these results demonstrate that the server can reliably handle at least ~27k requests per second on the tested hardware.

## Benchmark Comparison (cpp_http_server versus Express server)

I made sure that the node express server implemented multi-threading to provide a more fair comparison with the cpp_http_server.
Check out `benchmarks/node_server` to see the node express server implementation.

The cpp_http_server is ~1.562x faster in throughput or about 56.2% higher request rate.

Calculation: 27,366.734925 RPS / 17,524.167725 RPS = ~1.5612

| Metric | **C++ Server** | **Node + Express** |
| ------------------ | ----------------- | ------------------ |
| Target rate | 30,000.00 RPS | 30,000.00 RPS |
| Actual RPS | 27,366.734925 RPS | 17,524.167725 RPS |
| Total requests | 280,791 | 176,924 |
| Dropped iterations | 19,214 | 123,126 |
| Average latency | 5.47 ms | 46.88 ms |
| Median latency | 3.44 ms | 34.1 ms |
| p90 latency | 13.55 ms | 103.24 ms |
| p95 latency | 17.34 ms | 132.88 ms |
| p99 latency | 26.06 ms | 192.68 ms |
| Max latency | 219.18 ms | 445.75 ms |
| Error rate | 0.00% | 0.00% |
| Peak VUs | 945 | 1,693 |
| Iterations/sec | 27,366.734925 | 17,524.167725 |

---

## Usage

```cpp
Expand Down
55 changes: 55 additions & 0 deletions benchmarks/benchmark-results.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/

execution: local
script: k6.js
output: -

scenarios: (100.00%) 1 scenario, 20000 max VUs, 40s max duration (incl. graceful stop):
* constant_request_rate: 30000.00 iterations/s for 10s (maxVUs: 100-20000, gracefulStop: 30s)



█ THRESHOLDS

http_req_duration
✓ 'p(99)<1000' p(99)=26.06ms

http_req_failed
✓ 'rate<0.01' rate=0.00%


█ TOTAL RESULTS

checks_total.......: 280791 27366.734925/s
checks_succeeded...: 100.00% 280791 out of 280791
checks_failed......: 0.00% 0 out of 280791

✓ response code was 200

HTTP
http_req_duration..............: avg=5.47ms min=60.06µs med=3.44ms max=219.18ms p(90)=13.55ms p(95)=17.34ms
{ expected_response:true }...: avg=5.47ms min=60.06µs med=3.44ms max=219.18ms p(90)=13.55ms p(95)=17.34ms
http_req_failed................: 0.00% 0 out of 280791
http_reqs......................: 280791 27366.734925/s

EXECUTION
dropped_iterations.............: 19214 1872.654198/s
iteration_duration.............: avg=10.01ms min=188.24µs med=6.19ms max=1.08s p(90)=20.55ms p(95)=26.14ms
iterations.....................: 280791 27366.734925/s
vus............................: 506 min=77 max=506
vus_max........................: 945 min=223 max=945

NETWORK
data_received..................: 24 MB 2.3 MB/s
data_sent......................: 30 MB 2.9 MB/s




running (10.3s), 00000/00945 VUs, 280791 complete and 0 interrupted iterations
constant_request_rate ✓ [======================================] 00000/00945 VUs 10s 30000.00 iters/s
55 changes: 55 additions & 0 deletions benchmarks/node-benchmark-results.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/

execution: local
script: k6.js
output: -

scenarios: (100.00%) 1 scenario, 20000 max VUs, 40s max duration (incl. graceful stop):
* constant_request_rate: 30000.00 iterations/s for 10s (maxVUs: 100-20000, gracefulStop: 30s)



█ THRESHOLDS

http_req_duration
✓ 'p(99)<1000' p(99)=192.68ms

http_req_failed
✓ 'rate<0.01' rate=0.00%


█ TOTAL RESULTS

checks_total.......: 176924 17524.167725/s
checks_succeeded...: 100.00% 176924 out of 176924
checks_failed......: 0.00% 0 out of 176924

✓ response code was 200

HTTP
http_req_duration..............: avg=46.88ms min=180.69µs med=34.1ms max=445.75ms p(90)=103.24ms p(95)=132.88ms
{ expected_response:true }...: avg=46.88ms min=180.69µs med=34.1ms max=445.75ms p(90)=103.24ms p(95)=132.88ms
http_req_failed................: 0.00% 0 out of 176924
http_reqs......................: 176924 17524.167725/s

EXECUTION
dropped_iterations.............: 123126 12195.522797/s
iteration_duration.............: avg=50.97ms min=253.76µs med=37.01ms max=468.22ms p(90)=112.5ms p(95)=142.84ms
iterations.....................: 176924 17524.167725/s
vus............................: 1679 min=249 max=1679
vus_max........................: 1693 min=474 max=1693

NETWORK
data_received..................: 46 MB 4.6 MB/s
data_sent......................: 19 MB 1.9 MB/s




running (10.1s), 00000/01695 VUs, 176924 complete and 0 interrupted iterations
constant_request_rate ✓ [ 100% ] 00000/01695 VUs 10s 30000.00 iters/s
Loading
Loading