Skip to main content

Benchmarks

Memory and performance benchmarks for the Warp server. These verify that the server has no memory leaks and provide baseline allocation numbers for capacity planning.

Test Environment​

ComponentDetails
CPUIntel Core Ultra 7 255U (12 cores / 14 threads)
RAM32 GB
OSWindows 11 Enterprise
Runtime.NET 10.0.5, X64 RyuJIT AVX2
GCConcurrent Workstation
DatabasePostgreSQL (latest, Testcontainers)

Memory Per Job​

How much memory does processing a single job cost?

OperationAllocated
DI scope create + dispose34 KB
DI scope + DB query79 KB
Full worker cycle (fetch, execute, finalize)358 KB

The full worker cycle includes two transactions, two DbContext scopes, JSON deserialization, handler execution, and counter + log writes.

:::caution Figures predate a measurement fix

The tables below were produced when the benchmarks either could not run at all or reported a column that measured the wrong process, so treat them as indicative until they are re-measured. Two defects were found and fixed: the fixture never registered a database provider, so every server benchmark reported NA; and a custom "Total Allocated (all threads)" diagnoser read the host process while the work happened in a child, reporting 0 GB beside a real 2.87 GB. That diagnoser has been removed as redundant — MemoryDiagnoser already measures process-wide.

:::

Server Throughput​

Full server with 5 workers and the background tasks. Allocated is process-wide, so it covers the worker and background-task threads rather than only the publishing thread.

WorkloadJobsMeanAllocatedPer Job
Simple jobs200935 ms10 MB50 KB
Simple jobs2,0006.3 s100 MB50 KB
Simple jobs10,00022.5 s450 MB50 KB
Messages (3 handlers each)2001.2 s13 MB66 KB
Mixed (jobs + messages + failures)200862 ms14 MB69 KB
Idle (background tasks only)05.0 s7 MB-

Per-job allocation is constant at ~50 KB regardless of scale. 10x more jobs = 10x more allocation, no superlinear growth.

Memory Leak Test​

The definitive leak test: 10 workers, 100,000 jobs processed in 10 rounds. After each round, a full GC is forced and the managed heap is measured.

RoundTotal JobsTimeHeap (MB)Retained (MB)Jobs/sec
base0-10.8--
110,00023.7s10.9+0.1421
220,00022.4s10.90.0447
330,00023.4s10.9+0.1427
440,00023.9s10.9+0.1419
550,00021.4s10.9+0.1467
660,00020.2s10.9+0.1496
770,00020.7s10.9+0.1483
880,00021.2s10.9+0.1471
990,00021.5s10.9+0.1465
10100,00021.5s11.0+0.2465

Result: No memory leak. The heap stays at ~10.9 MB across all rounds. After 100,000 jobs, total retained memory is 0.3 MB (GC noise). Per-job retained memory is 0.00 KB. Throughput stays consistent at 420-496 jobs/sec with no degradation.

Running Benchmarks​

The benchmark project is at src/benchmarks/Warp.ServerBenchmarks/.

# BenchmarkDotNet — per-operation allocation
dotnet run --project benchmarks/Warp.ServerBenchmarks -- --filter *ScopeMemory*
dotnet run --project benchmarks/Warp.ServerBenchmarks -- --filter *WorkerMemory*
dotnet run --project benchmarks/Warp.ServerBenchmarks -- --filter *ServerMemory*

# Memory leak stress test (configurable)
dotnet run --project benchmarks/Warp.ServerBenchmarks -- stress
dotnet run --project benchmarks/Warp.ServerBenchmarks -- stress --workers=10 --jobs=10000 --rounds=10

The stress test boots a real server with Testcontainers, so Docker must be running. No external database setup needed.