Benchmarks

What each code system costs to build and serve, and how fast it answers

Every number on this page is rendered from a benchmark record committed to the repository, one file per code system and run; a check fails when this page and the records disagree. The machine, the method, and the conditions stand beside every figure, and a number that was not measured says so.

Method

How a record is taken

The harness (ferroterm-bench, in the repository under tools/) builds the release into an index with ferroterm-build, timing the build and reading its peak resident memory from the operating system; starts the server over the index and times the wait until /health answers; reads the server's resident memory after start and again after the warm requests; and, for each operation, sends one cold request followed by the warm requests, timing every HTTP round trip from the same machine. The latency columns are the cold request and the nearest-rank p50, p95, and p99 of the warm requests.

A request that answers anything other than a 2xx status fails the run for that system and no record is written, so a record never holds the latency of an error response. Every record states the machine it was taken on, and whether that machine was a container; the repository carries one (bench/compose.yaml), which builds the server, the build tool, and the harness on digest-pinned images and mounts the licensed releases read-only, but a record is only from it when the record says so. Resident memory is what starting the server loads: the hierarchy, the text index, and the other structures it reads whole, which is why the figure when the server reports ready and the figure after the warm requests are close. Units fit the value: seconds, milliseconds, or microseconds; GB, MB, or KB.

The repository ships no code system content. To take a record over the releases you are licensed for, follow the benchmarks chapter of the book; a record you take on your hardware is the number that matters for your deployment.

The records

Per code system

Each row links to the record it was rendered from. A cell reads n/a when the system defines no such operation, for instance a code system with no whole-system value set to expand.

Warm p50 over 200 HTTP round trips on one machine (Apple M2, 17.18 GB, macos/aarch64), FerroTERM 0.1.4 serving FHIR R4B, taken 2026-09-22.

Footprint

Code systemReleaseConceptsBuildPeak build memoryIndex on diskTime to readyResident, openResident, warm
ICD-10-CM202698,8271.51 s359 MB44 MB206.51 ms91 MB91 MB
ICD-10-NL202142,769880.52 ms221 MB21 MB103.55 ms66 MB66 MB
ICD-11 MMS2026-0137,211n/an/a44 MB206.06 ms99 MB99 MB
LOINC2.83257,2668.15 s2.54 GB310 MB310.16 ms438 MB440 MB
RxNorm (prescribable subset)0908202681,4684.58 s667 MB77 MB205.2 ms132 MB133 MB
SNOMED CT (International edition)20260901535,50214.12 s3.06 GB559 MB512.21 ms941 MB943 MB
SNOMED CT (Netherlands edition)20260630548,94917.66 s3.88 GB864 MB618.67 ms1.14 GB1.14 GB

Latency per operation

Each operation: the first request cold, then the nearest-rank p50, p95, and p99 over the warm requests.

$lookup

Code systemColdp50p95p99
ICD-10-CM1.16 ms105 µs146 µs160 µs
ICD-10-NL801 µs96 µs149 µs172 µs
ICD-11 MMS1.01 ms138 µs182 µs222 µs
LOINC1.35 ms136 µs174 µs190 µs
RxNorm (prescribable subset)1.81 ms388 µs505 µs545 µs
SNOMED CT (International edition)2.28 ms217 µs301 µs349 µs
SNOMED CT (Netherlands edition)2.05 ms222 µs263 µs277 µs

$validate-code

Code systemColdp50p95p99
ICD-10-CM121 µs60 µs92 µs129 µs
ICD-10-NL118 µs60 µs92 µs97 µs
ICD-11 MMS80 µs59 µs76 µs96 µs
LOINC94 µs56 µs70 µs77 µs
RxNorm (prescribable subset)146 µs114 µs134 µs182 µs
SNOMED CT (International edition)93 µs66 µs77 µs86 µs
SNOMED CT (Netherlands edition)176 µs66 µs84 µs127 µs

$subsumes

Code systemColdp50p95p99
ICD-10-CM70 µs58 µs70 µs93 µs
ICD-10-NL81 µs64 µs75 µs79 µs
ICD-11 MMSn/a
LOINCn/a
RxNorm (prescribable subset)n/a
SNOMED CT (International edition)581 µs59 µs76 µs88 µs
SNOMED CT (Netherlands edition)630 µs59 µs74 µs83 µs

$expand (a small value set)

Code systemColdp50p95p99
ICD-10-CMn/a
ICD-10-NLn/a
ICD-11 MMS926 µs129 µs149 µs166 µs
LOINC2.79 ms126 µs145 µs160 µs
RxNorm (prescribable subset)n/a
SNOMED CT (International edition)889 µs215 µs239 µs273 µs
SNOMED CT (Netherlands edition)1.31 ms285 µs323 µs343 µs

$expand (the whole system, one page)

Code systemColdp50p95p99
ICD-10-CMn/a
ICD-10-NLn/a
ICD-11 MMS122 µs116 µs149 µs204 µs
LOINC10 ms7.23 ms7.9 ms8.77 ms
RxNorm (prescribable subset)n/a
SNOMED CT (International edition)2.16 ms1.7 ms1.84 ms1.92 ms
SNOMED CT (Netherlands edition)3.02 ms2.28 ms2.51 ms2.55 ms

$expand with filter (designation search)

Code systemColdp50p95p99
ICD-10-CMn/a
ICD-10-NLn/a
ICD-11 MMS164 µs139 µs157 µs166 µs
LOINC3.61 ms283 µs310 µs339 µs
RxNorm (prescribable subset)n/a
SNOMED CT (International edition)1.33 ms353 µs422 µs488 µs
SNOMED CT (Netherlands edition)1.72 ms817 µs898 µs1.02 ms

Reference-server comparison

A comparison is stated only when the reference server ran on the same machine over the same release, with its configuration recorded in the record.

  • ICD-10-CM: not run
  • ICD-10-NL: not run
  • ICD-11 MMS: not run
  • LOINC: not run
  • RxNorm (prescribable subset): not run
  • SNOMED CT (International edition): not run
  • SNOMED CT (Netherlands edition): not run