FHIR Conformance And Benchmarks
sct keeps four different checks separate:
- Repository regression checks: do the documented query-string operations still return the expected results over the committed synthetic fixture?
- FHIR structural validation: are representative responses valid base-R4 resources according to the independent HL7 FHIR Validator?
- Official terminology interoperability tests: does the server pass the selected released suites from the HL7 FHIR Terminology Ecosystem?
- Performance benchmarks: once the relevant correctness profile passes, how fast is it compared with local SQLite and other terminology servers?
The distinction matters. A fast server that returns the wrong $expand result
is not useful, a structurally valid response can still contain the wrong concept
set, and a repository-owned suite is not independent conformance evidence.
Evidence, Not Certification
The current CI runner is a repository-specific smoke/regression profile aligned with these FHIR R4 terminology operations:
/metadataCodeSystem/$lookupCodeSystem/$validate-codeCodeSystem/$subsumesValueSet/$expandValueSet/$validate-codeConceptMap/$translate
It proves the local contract remains stable; it is not an official HL7 suite and not an HL7 certification badge. The independent layers are:
| Layer | Tool | What it checks |
|---|---|---|
| Base R4 structure | HL7 FHIR Validator | Resource cardinalities, datatypes and invariants |
| Terminology interoperability and semantics | FHIR Terminology Ecosystem txTests |
Released operation requests and expected responses for selected modes |
| Proposed HL7 ecosystem approval criteria | Unreleased 1.9.5-SNAPSHOT draft at a pinned upstream commit | Passing released tests, a public reproducible endpoint, and FHIR Product Director review; draft guidance, not a published approval standard |
The reproducible baseline pins FHIR Validator 6.10.4 and
hl7.fhir.uv.tx-ecosystem#1.9.3; never use the mutable current package in CI.
The published test registry currently uses an unversioned page while the package
coordinate and hash pin the executable corpus. The separate approval-page source
above is explicitly an unreleased draft and must not be presented as a current
published HL7 requirement.
The official command is:
java -jar validator_cli-6.10.4.jar txTests \
-tx http://127.0.0.1:8080/fhir \
-test-version 1.9.3 \
-mode general \
-output ./tx-results \
-fhir-settings ./fhir-settings.json
The Validator blocks plain HTTP and private-network targets by default. For this loopback URL, use a narrowly scoped settings file rather than disabling checks globally:
{
"servers": [{
"url": "http://127.0.0.1:8080/fhir",
"type": "fhir",
"authenticationType": "none",
"allowHttp": true,
"allowPrivateNetwork": true
}]
}
Retain the complete runner output directory for every evidenced R4 run,
including test.log, test-results.json, report.json, actual/, expected/
and conversions/. The conversion output distinguishes server failures from
failures while converting the test corpus between FHIR versions.
The first baseline is an interoperability diagnosis, not a semantic score. The
general run executed 597 tests: 593 operation requests were refused at the
standard POST Parameters boundary, two $batch-validate requests reached
unsupported routes, and two metadata comparisons failed. The sct-ecl suite's
103 requests were also refused before ECL evaluation because they carry inline
ValueSet bodies. They target a licensed SNOMED test subontology that is not the
committed 22-concept synthetic fixture, so those results must not be reported as
"0% ECL conformance".
The local runner remains useful because benchmark evidence needs a stable,
reproducible workload on developer machines, deployments and CI. The detailed
pins, licensing boundary, staged external-gate plan and exact claim language are
in the R17 conformance evidence record.
Run Conformance First
Start a terminology server:
sct serve --db snomed.db --host 127.0.0.1 --port 8080 --fhir-base /fhir
Then run:
benchmarks/conformance.sh --server http://localhost:8080/fhir
The runner checks:
| Area | What is asserted |
|---|---|
| CapabilityStatement | FHIR R4 version and advertised terminology operations |
$lookup |
Parameters shape, display text, designations and parent properties |
CodeSystem/$validate-code |
true/false outcomes, including display mismatch |
$expand |
ECL expansion, text filtering, result totals and expected members |
$subsumes |
subsumes, subsumed-by, equivalent, not-subsumed |
ValueSet/$validate-code |
membership against implicit SNOMED ECL ValueSets |
$translate |
SNOMED to ICD-10 and reverse mapping when advertised |
| Errors | FHIR OperationOutcome responses and expected HTTP status codes |
Write machine-readable output for CI or later reporting:
benchmarks/conformance.sh \
--server http://localhost:8080/fhir \
--output reports/sct-conformance.jsonl
If a target server does not advertise ConceptMap/$translate, the translate
checks are skipped by default. Use --strict when comparing only servers that
are expected to support the full sct surface.
Then Benchmark
After conformance passes:
benchmarks/bench.sh \
--db snomed.db \
--server http://localhost:8080/fhir \
--runs 20 \
--warmup 5 \
--write-benchmarks
The existing benchmark covers:
- concept lookup
- free-text search
- direct children
- ancestor traversal
- subsumption
- bulk lookup
The benchmark reports wall-clock medians and standard deviation. Local SQLite timings include process startup. FHIR timings include HTTP overhead.
Compare Against Snowstorm Or Ontoserver
To make a credible public claim:
- Load the same SNOMED CT release into every server.
- Run each server on the same hardware class.
- Warm the filesystem, JVM, Elasticsearch/Lucene and SQLite caches.
- Run
benchmarks/conformance.shfirst. - Only publish benchmark results for servers that pass the relevant conformance profile.
- Record exact versions, heap settings, database size, disk type, CPU, RAM, operating system and release package.
Example:
# sct
benchmarks/conformance.sh --server http://localhost:8080/fhir
benchmarks/bench.sh --db snomed.db --server http://localhost:8080/fhir --runs 20 --warmup 5
# Snowstorm Lite
benchmarks/conformance.sh --server http://localhost:8081/fhir
benchmarks/bench.sh --db snomed.db --server http://localhost:8081/fhir --runs 20 --warmup 5
# Ontoserver or another FHIR terminology server
benchmarks/conformance.sh --server http://localhost:8082/fhir
benchmarks/bench.sh --db snomed.db --server http://localhost:8082/fhir --runs 20 --warmup 5
The conformance checks are deliberately fixture based so the same request matrix can be used across implementations. The benchmark fixtures should be expanded over time with more high-fanout hierarchies, deep concepts, inactive concepts, refsets and cross-map workloads.
Public Methodology
When publishing results, include:
- exact
sctversion and git commit - SNOMED CT edition and release date
- whether refsets and crossmaps were loaded
- server base URL path, for example
/fhir - hardware and operating system
- Docker image tags or binary versions for comparator servers
- cache state: cold start, warm cache, or both
- number of runs, warmup runs and timeout
- full conformance pass/fail output
- raw benchmark output
The headline number should be scoped. For example, "sct serve is faster for
these read-only SNOMED CT terminology operations on this release and hardware"
is defensible. A general claim that one terminology server is universally
faster than another is not.