Bundle import is the metric that decides how a FHIR migration actually feels. The number tells the team how long it takes to load a real patient history, how the server behaves during a backfill, and whether the migration window has to stretch across a weekend. A new public benchmark from Health Samurai measured bundle import resources-per-second across four FHIR servers under identical conditions, and the spread is wide enough to change procurement decisions.
The benchmark runs Aidbox, HAPI FHIR, Medplum, and the Microsoft FHIR Server on the same bare-metal machine with the same Synthea dataset of 1,000 patients and roughly 2 million resources. For more practical FHIR walkthroughs, the broader FHIR coverage covers the surrounding topics.
The Bundle Import Numbers
Bundle import in the benchmark uses 20 concurrent threads pushing Synthea-generated transaction bundles. The report published the following resources-per-second figures, with the snapshot dated 2026-06-29:
| Server | Bundle import (resources/sec) |
|---|---|
| Aidbox | 2,678 |
| HAPI FHIR | 2,214 |
| Medplum | 764 |
| Microsoft FHIR Server | 448 |
The benchmark is open source and the live dashboard reruns daily at the public benchmark dashboard. Health Samurai authored the report and also makes Aidbox, so this is a vendor-run benchmark; the open repo is what lets anyone rerun the same scenario on their own hardware.
What the Spread Means for a Migration
A migration team loading two million FHIR resources sees the spread translate directly to wall-clock time. At roughly 2,600 resources per second, the load finishes in about thirteen minutes. At 450 resources per second, the same load takes close to ninety minutes. That difference reshapes how the migration window gets scoped, how rollback windows get planned, and how much downtime a hospital IT team has to absorb during cutover.
The indexing story also matters here. HAPI, Medplum, and the Microsoft FHIR Server pre-build search indexes on write, which pays a cost during bundle import and recoups it later in search. Aidbox ships without default indexes, which speeds the import path and shrinks storage, but turns indexing into a deliberate operator choice. Neither approach is universally right; the migration story for a team that imports once and queries forever is different from the team that imports continuously.
How to Read These Numbers Against Your Own Plan
The numbers in this report come from a 1,000-patient Synthea dataset that fits comfortably in memory. The next post in the series is expected to test at scale, which is where bundle import tends to behave differently. A few practical things to weigh against a real migration:
- Resource graph shape. Synthea data has a known distribution. A real EHR backfill often has heavier Observation tails or denser Provenance graphs, and bundle import behavior shifts under that distribution.
- Concurrency profile. The benchmark uses 20 threads. A production import job often runs higher concurrency against larger bundles, or lower concurrency to manage backpressure into the source EHR.
- Validation strictness. Servers that strict-validate against US Core during import pay a real per-bundle cost that small-dataset benchmarks underweight.
For broader context, the FHIR servers for medical software teams complete guide frames the wider selection question, and the best FHIR servers for mid-size hospital IT teams writeup covers the procurement shape that bundle import sits inside.
What This Report Settles, and What It Does Not
The benchmark settles the question of relative bundle import throughput on a clean dataset on a single bare-metal machine under one set of resource constraints. It does not settle the question of how each server behaves at five million patients, behind a hospital network, with real US Core validation turned on. Use the numbers as a starting point and rerun the open scenario against your own data shape before signing anything.
