Every FHIR API sizing exercise runs into the same wall in the first week: nobody actually knows what production traffic will look like yet. The workflows are half-designed, the integration partners have not signed off on their access patterns, and the vendor conversations are still trading rough calendar dates. You are being asked to pick server tiers, cache budgets, and database sizings against a target that will not exist for another quarter.
The trick is to stop treating sizing as a single number and start treating it as a bounded range with named assumptions. For the wider set on FHIR mechanics, the FHIR explainers on astrocasts collects the surrounding walkthroughs. This piece is about the specific sizing habit that survives the fog.
Start With the Range, Not the Number
The most common sizing failure is picking a target RPS out of nowhere, provisioning against it, and then discovering that the real workload is either three times higher or a tenth of the estimate. Neither outcome makes anyone happy.
The alternative is to bracket the range explicitly. Write down the assumed low-water number, the assumed high-water number, and the ratio between them. If the ratio is more than ten times, the sizing exercise is not really about capacity yet; it is about narrowing the assumption. A pass through the site's FHIR server throughput sizing widget can turn a range like that into concrete server-tier options in seconds.
Name Every Assumption Behind the Range
Behind every range sits a small set of assumptions. Concurrent users, actions per user per minute, reads and writes per action, ratio of chatty clients to well-behaved ones, expected burst multiplier during peak hours. Each of these is a knob you can tighten as the workflow gets sharper.
When the range is unnamed, sizing conversations run in circles. When each number is tied to a named assumption, the conversation moves quickly from "we don't know" to "here is the number that would change our answer". For the concrete formula that translates those assumptions into reads per second, the numbers you actually need to estimate FHIR read RPS is the developer-facing reference.
Plan for the Ratio, Not the Absolute
Read/write ratios matter more than absolute numbers early on. A workload that is ninety percent reads scales very differently from one that is fifty-fifty, even at the same total RPS. Database index strategy, cache sizing, and replica placement all bend around the ratio.
If you pick a ratio and defend it explicitly, the sizing decisions cascade cleanly. If you leave the ratio implicit, every downstream conversation reopens the same debate. For the mixed-workload case, planning read/write ratio for a mixed FHIR workload walks through the tradeoffs.
Reserve Headroom for the Batch Traffic
Batch endpoints inflate effective RPS in ways that raw formulas miss. A single POST /Bundle transaction with fifty entries counts as one HTTP request against the CDN but as fifty inserts against the database and cache layer. Sizing that ignores the split under-provisions the persistence tier.
Reserve at least thirty percent of the write budget for batch amplification if the workflow involves any transactional payloads. The number can move up or down as the load shape sharpens.
Rehearse Against a DevDays Talk
The FHIR community publishes real scaling numbers through DevDays and connectathon talks. Reading a scaling talk before you finalize sizing calibrates your gut against numbers that came from production systems. Translating those numbers into your own workload is exactly the capacity-planner skill that reading DevDays scaling talks like a capacity planner covers.
Sizing a FHIR API before the load pattern exists is not a prediction exercise. It is a discipline of naming assumptions cleanly and revisiting them as the workflow gets sharper. Teams that treat sizing as a range with named knobs converge on a stable answer faster than the ones that keep asking for the missing number.

Sources
- HL7 FHIR Bulk Data Access IG - HL7 FHIR Bulk Data Access IG, canonical evergreen reference for FHIR-scale API load patterns and export bursts