Every core has work to do.
CoreMach9 is a C++ HTTP performance lab built with Drogon and RapidJSON. It explores how request handling, JSON processing, and native multithreading affect throughput, latency, and network bandwidth under load.
Two endpoints provide different levels of processing:
| Method | Endpoint | Workload |
|---|---|---|
| GET | /simple |
Return a minimal JSON response |
| PATCH | /update-something/{id}/{name} |
Process input and generate a larger JSON response containing 100 history records |
The PATCH route reads path and query parameters, processes fields from a JSON request body, and serializes the response using RapidJSON.
These are synthetic benchmark workloads. The PATCH route does not update a database.
| Component | Role |
|---|---|
| C++17 or newer | Native application code |
| Drogon | HTTP handling and event-loop threads |
| RapidJSON | JSON parsing and serialization |
| CMake | Build configuration |
config.json |
Runtime configuration |
main.cc |
Endpoints, listener, and thread setup |
The server listens on port 5555.
Worker thread count is derived from std::thread::hardware_concurrency(), with a fallback to one thread when detection returns zero.
Response compression is disabled in the supplied configuration. Logging is set to WARN, and a Prometheus exporter is configured at /metrics.
The larger endpoint includes both request-body parsing and response serialization. RapidJSON handles these operations directly.
Measure parsing and serialization separately when investigating bottlenecks. A faster parser does not automatically imply faster response generation.
Drogon distributes work across event-loop threads within the application process.
Additional threads can increase throughput when enough independent work is available. Gains depend on CPU capacity, contention, memory bandwidth, connection behavior, and network limits.
A small JSON response and a response containing 100 records exercise different constraints.
Larger payloads increase serialization work and network traffic. Always record response size alongside requests per second.
Use an external load generator and system monitoring to collect:
| Metric | What it reveals |
|---|---|
| Successful requests/sec | Completed application work |
| p50, p95, and p99 latency | Typical and tail response times |
| HTTP errors and timeouts | Failures under pressure |
| Transfer rate | Network traffic generated by responses |
| CPU utilization | Processing demand across cores |
| Memory usage | Resource consumption during the run |
Check which metrics your chosen tools expose. Throughput alone is insufficient: fast error responses can inflate request counts.
The following commands target Linux or WSL with:
- A C++17-compatible compiler
- CMake and a supported build tool
- Drogon installed and discoverable by CMake
- RapidJSON headers available to the compiler
Clone the repository:
git clone https://github.com/ATLURI0001/CoreMach9.git
cd CoreMach9Configure and compile a release build:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17
cmake --build build --parallelRun from the build directory:
cd build
./cpp-serverThe executable retains the name cpp-server defined in CMakeLists.txt.
Run it from build because the application loads its configuration from ../config.json.
In a second terminal:
curl http://localhost:5555/simpleExpected response:
{"message":"hi"}Exercise the larger endpoint:
curl -X PATCH \
"http://localhost:5555/update-something/123/john_doe?value1=abc&value2=xyz" \
-H "Content-Type: application/json" \
-d '{"foo1":"hello","foo2":"world"}'The response contains the supplied identifiers, query values, processed text, and generated history records.
Amdahl’s Law illustrates how serial work limits theoretical speedup:
Where:
pis the parallelizable fraction of the workload.Nis the number of processing units.S(N)is the theoretical speedup relative to serial execution.
For illustration, at 192 processing units:
| Assumed parallelizable fraction | Theoretical speedup |
|---|---|
| 95% | Approximately 18.2× |
| 99% | Approximately 65.98× |
These fractions are hypothetical, not measured properties of Node.js, C++, or Drogon. The calculation does not establish that one implementation is faster.
Actual performance must be measured with equivalent workloads and controlled configurations.
The upstream project reports reaching 1 million requests per second for its larger PATCH workload on an AWS c8gn.48xlarge instance.
That result belongs to the upstream experiment. It is not an independently reproduced CoreMach9 benchmark or a guarantee for other hardware.
When publishing new results, include:
- Hardware and operating system
- Compiler, dependency versions, and build flags
- Server thread count
- Endpoint, request body, and response size
- Load-generator hardware and configuration
- Connection count, pipelining, warm-up, and test duration
- Successful throughput, latency percentiles, and error counts
- CPU, memory, and network utilization