What CRUD Throughput Means When 4 FHIR Servers Are Tested Side by Side

What CRUD Throughput Means When 4 FHIR Servers Are Tested Side by Side

CRUD throughput is one of those numbers everyone quotes and almost nobody tests under fair conditions. A new public benchmark from Health Samurai changes that by running Aidbox, HAPI FHIR, Medplum, and the Microsoft FHIR Server against the same Synthea dataset on the same bare-metal machine, with the live dashboard rerun daily. The CRUD numbers are the part most US implementation teams read first, and the spread is wider than most teams expect.

The benchmark is open source and lives on GitHub. The numbers in this piece all come from that report. For the broader FHIR knowledge base, the rest of the FHIR coverage on this site walks through the surrounding topics.

The Per-Server CRUD Throughput Table

The benchmark reports total CRUD requests per second across create, read, update, and delete operations on nine resource types, with 300 concurrent threads. The published snapshot, dated 2026-06-29, shows the following:

Server CRUD throughput (RPS)
Aidbox 5,212
HAPI FHIR 3,058
Medplum 1,420
Microsoft FHIR Server 440

Same hardware (64 CPU cores, 500 GB RAM), same per-container allocation (8 vCPU and 24 GB RAM per server, with Medplum running its documented 8 replicas of 1 vCPU and 3 GB each), same Synthea dataset of 1,000 patients. Health Samurai authored the benchmark and ships Aidbox, so this is a vendor-run report; the value of the open repo is that anyone can rerun it.

What a 5,212-to-440 Spread Actually Tells You

A spread of more than 10x between the top and bottom of the table is not noise. It points to architectural decisions that show up in production the first week a real workload hits the server.

Aidbox at the top of the CRUD chart at 5,212 RPS reflects an approach that does not pre-build search indexes on write. That decision speeds up writes and shrinks the storage footprint, with the trade that indexing becomes a deliberate operator choice rather than a built-in default. HAPI FHIR at 3,058 RPS, with its JPA-backed PostgreSQL design, is the open-source baseline that most US implementation teams already know. Medplum at 1,420 RPS shows the cost of the replica-based deployment model under the per-server allocation used in this run. Microsoft at 440 RPS, running on SQL Server 2022 Developer Edition, lands at the back of the CRUD pack in this configuration.

P99 Latency Behind the Throughput

Throughput is half of the story. The tail latency is what shows up in user-facing SLOs. The benchmark publishes P99 numbers per operation:

Server Create P99 Read P99 Update P99 Delete P99
Aidbox 106 ms 91 ms 110 ms 93 ms
HAPI FHIR 276 ms 225 ms 271 ms 239 ms
Medplum 758 ms 404 ms 626 ms 647 ms
Microsoft FHIR Server 1,180 ms 379 ms 1,233 ms 1,064 ms

The Microsoft numbers on create and update are the ones to notice. A P99 above one second on a write operation means that one in every hundred writes will visibly stall for a user clicking a button in an EHR. HAPI's P99 stays in the 200-300 ms range, which is fine for most workflows. Aidbox's P99 stays under 110 ms across all four operations.

What This Means for a US Implementation Team

Honestly, the operational read here is that CRUD throughput is one metric among several, but it is the one a clinician notices first. A US health system picking a FHIR server for an EHR-adjacent workflow should expect the production behavior to roughly match what the open benchmark shows, especially because the report is rerun daily and the live dashboard is at the open benchmark dashboard. For a deeper view of related FHIR plumbing decisions, C-CDA vs FHIR documents when migrating EHR data covers the document side, and the FHIR terminology for US value-based care guide covers the terminology layer that any of these servers will sit underneath.

A Sensible Way to Read This Report

The catch is that the published snapshot uses a 1,000-patient Synthea dataset that fits comfortably in memory, and Health Samurai has said the next post in the series tests at scale. That means the CRUD numbers here are a clean baseline rather than a production stress test. Read them as the floor of how each server behaves on a well-shaped workload, not as the only number that decides a procurement.