Performances
Performance is a built-in feature, not an optional optimization.
Thanks to its architecture, SimpleW can handle the 10K connections problem.
Server Comparison
Monitoring requests-per-second is not relevant as it depend on the hardware.
What matters is how each server performs relative to the others in the same conditions.
All tests are performed on Linux on a capable machine.
Evaluate request with a server containing a single route that returns a json serialized object
Command : bombardier -c 200 -d 30s http://127.0.0.1:8080/api/test/hello
| Server | Perf (%) | Total (req) | Max (req/s) | Average (req/s) |
|---|---|---|---|---|
| ActixWeb 📄 | 100 | 10.680.216 | 494.036 | 356.369 |
| Node 📄 | 94 | 10.080.386 | 464.080 | 335.814 |
| SimpleW 📄 | 90 | 9.620.831 | 458.121 | 320.991 |
| AspNetCore 📄 | 84 | 9.064.941 | 396.917 | 302.554 |
| FastEndpoints 📄 | 83 | 8.887.823 | 403.860 | 296.483 |
| FastHttp 📄 | 64 | 6.846.205 | 276.119 | 228.399 |
| GenHttp 📄 | 62 | 6.709.236 | 318.067 | 223.971 |
| Gin-Gonic 📄 | 11 | 1.255.802 | 53.615 | 41.869 |
| Fastify 📄 | 8 | 958.221 | 35.793 | 31.940 |
| EmbedIO 📄 | 1 | 144.493 | 10.934 | 4.819 |
SimpleW is very close to Node. ActixWeb is still on top.
NOTE
The bombardier command is run three times, then keep the best result.
Performance-Oriented Configuration
To get the best performance, enable the following options :
var server = new SimpleWServer(IPAddress.Any, 2015);
server.Configure(options => {
// Always beneficial socket options
options.TcpNoDelay = true;
options.ReuseAddress = true;
options.TcpKeepAlive = true;
// Advanced tuning (platform dependent)
options.AcceptPerCore = true;
options.ReusePort = true; // linux only
});2
3
4
5
6
7
8
9
10
11
These options improve :
- Connection acceptance scalability
- Latency under load
- CPU core utilization
Common Performance Killers
Even a fast server can be made slow by misuse.
Excessive Middleware
- Middleware runs on every request
- Each middleware adds overhead
- Complex middleware stacks multiply cost
Use middleware only for true cross-cutting concerns.
Manual Request Parsing
Do not parse raw request data yourself.
- Use
HttpRequesthelpers - They are optimized and allocation-aware
- Custom parsing often introduces bugs and hidden costs
If something is missing, open an issue instead of reimplementing it.
Console Output
Console.WriteLine(...);This is extremely slow under load.
- Introduces global locks
- Destroys throughput
- Skews benchmarks
Never use it in production hot paths.
