Performance¶
Note
Example runs were conducted on the following hardware:
Load test with bombardier¶
Prerequisites: bombardier
The server is started in the Development environment with Kafka disabled and the default log
level, so that the debug logging and the Kafka consumer from appsettings.Development.json
don't skew the results:
ASPNETCORE_ENVIRONMENT=Development \
ASPNETCORE_URLS=http://localhost:5000 \
Kafka__Enabled=false \
Logging__LogLevel__Default=Information \
dotnet run -c Release --no-launch-profile --project=src/FhirPseudonymizer
Note
On Windows, the Prometheus metrics listener binds to http://+:<MetricsPort>/metrics/, which
requires an elevated shell (or a URL ACL reservation via netsh http add urlacl).
In a different terminal:
which produces output like:
Bombarding http://localhost:5000/fhir/$de-identify for 1m0s using 125 connection(s)
[====================================================================================================================] 1m0s
Done!
Statistics Avg Stdev Max
Reqs/sec 26416.66 5890.85 35211.27
Latency 4.73ms 747.37us 148.68ms
Latency Distribution
50% 4.43ms
75% 4.85ms
90% 5.51ms
95% 8.10ms
99% 10.95ms
HTTP codes:
1xx - 0, 2xx - 1582351, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 214.17MB/s
Static vs. dynamic config¶
benchmark/k6/ contains a k6 script that compares
latency and throughput between the /fhir/$de-identify endpoint using the server's statically
configured rules and the same endpoint using a per-request dynamic config
(rules sent as a base64-encoded YAML Attachment). See its
README for how to run it.
Microbenchmarks¶
src/FhirPseudonymizer.Benchmarks contains
BenchmarkDotNet microbenchmarks for the anonymization engine
itself (no HTTP involved). Besides benchmarking the parsing of the sample anonymization.yaml
and hipaa-anonymization.yaml configs, AnonymizationBenchmarks runs a full de-identify pass
(parse + anonymize + serialize) using a "complex" config
(complex-anonymization.yaml,
combining redact, cryptoHash, dateshift, perturb, encrypt and pseudonymize rules)
against the large Synthea-generated bundle also used by the
snapshot tests. The pseudonymize
rule is handled by a trivial mocked IPseudonymServiceClient so the benchmark doesn't depend on a
running gPAS/Vfps/entici/MII instance.
Run all benchmarks with:
Results are tracked over time using
github-action-benchmark via the
microbenchmarks job in ci.yaml. On every pull request, it
compares the new results against the stored history and comments on the PR if a benchmark
regresses beyond the configured threshold. On every push to master, it instead appends the new
results to that history and publishes the rendered dashboard as part of the same GitHub Pages
deployment as this site, at
https://miracum.github.io/fhir-pseudonymizer/benchmarks/.