Skip to main content
Version: 4.x

Performance and quality

Design choices that matter for throughput​

  • One serialization per broadcast. A broadcast is serialized once and the same bytes are written to every local recipient.
  • Parallel fanout. Local recipients are written in parallel, each bounded by BroadcastSendTimeout, so a slow socket is aborted without holding up the rest.
  • Bounded work per connection. At most MaxConcurrentRequestsPerConnection requests run at once; further reads wait, so one busy client cannot queue unbounded work.
  • Serialized writes. Each socket has one writer at a time; responses and broadcasts never interleave frames.

Benchmarks​

Microbenchmarks from a local Release run of tag v4.0.0 on .NET 10.0.12, AMD Ryzen 7 3700X, Windows 11 (median of five samples, 364-byte payload). The transport is an in-memory sink that performs no network I/O, so these numbers show library overhead, not end-to-end latency.

ScenarioRecipientsTime per operationAllocated per operation
Serialize per recipient1000.356 ms39.2 KB
Serialize once1000.004 ms1.2 KB
In-memory fanout1000.210 ms36.3 KB
Serialize per recipient1 0003.693 ms385 KB
Serialize once1 0000.010 ms1.2 KB
In-memory fanout1 0002.680 ms268 KB
Serialize per recipient10 0006.431 ms3.84 MB
Serialize once10 0000.023 ms1.2 KB
In-memory fanout10 00013.656 ms2.65 MB
Parse 1 000 requests–2.349 ms984 KB
  • Serialize per recipient and serialize once compare naive per-client serialization with DarkWS's shared payload.
  • In-memory fanout is a real broadcast through IBroadcaster and the in-memory backplane to every recipient.
  • Parse 1 000 requests parses request envelopes, about 2 µs per request.

5.0 reworked local delivery: the same fanout to 1 000 recipients takes about 0.14 ms and 12 KB there (see the 5.x documentation).

Results depend on hardware and runtime; compare runs on the same machine. They do not model TLS, slow clients, or handler work.

Tests​

The 4.0.0 suite runs on .NET 8, 9, and 10:

SuiteTests
Server (DarkWS)109
.NET client and DI41
Redis backplane (real Redis in Docker)14
Browser client (Vitest)41

Coverage gates fail the build below 90% lines or 80% branches for any package. Coverage at 4.0.0:

PackageLinesBranches
DarkWS95.4%91.8%
DarkWS.Redis96.1%100%
DarkWS.Client98.4%91.7%
DarkWS.Client.DependencyInjection100%100%
darkws97.4%92.6%

Besides unit tests, the gate tests the Redis backplane against StackExchange.Redis 2.13.17 and 3.2.1, packs every NuGet package, checks its XML documentation and symbols, installs it into a clean consumer project, runs it on all target frameworks, and packs the npm package from a clean copy to verify its build.

API stability​

Public APIs are tracked with PublicApiAnalyzers: any change to the public surface must be declared and reviewed, or the build fails. Breaking changes ship only in major versions, with migration notes in the changelog.