Agnotic Technologies Logo
    Blog

    HAPI FHIR Performance Tuning for Production

    By GauravJanuary 15, 202612 mins read
    On this page

    Why is my HAPI FHIR server slow, and how do I fix it?

    HAPI FHIR is the most widely used open-source FHIR server, and it is entirely capable of running in production — but not with its out-of-the-box defaults under real load. Most "HAPI is slow" complaints trace back to database and search configuration, not the framework. This guide covers the tuning that actually moves the needle: indexing, search parameter management, paging, and caching, plus the traps that quietly destroy throughput.

    The database is almost always the bottleneck

    HAPI's JPA server stores resources and a set of search-index tables (HFJ_SPIDX_*) that back FHIR search. Under load, poorly indexed or bloated search tables are the number-one cause of slow queries. Use a production-grade database (PostgreSQL is the common choice), give it real resources, and treat its tuning as part of your FHIR tuning — connection pool size, work_mem, and vacuum/autovacuum settings all matter because the search-index tables churn heavily.

    Only index the search parameters you use

    By default HAPI can index a large number of search parameters, and every indexed parameter is write amplification — more rows in the SPIDX tables on every create/update, and larger tables to query. One of the highest-leverage optimizations is to disable search parameters you don't actually support and keep the ones you do.

    • Enumerate the search parameters your consumers really use (your API contract should already say this).
    • Disable unused built-in search parameters so writes don't pay to index them.
    • Add custom indexes on the SPIDX columns behind your hottest searches.

    Paging: never count what you don't need

    FHIR search bundles can include a total count, and computing an exact total over a large result set is expensive. HAPI lets you control this — using an estimated total, or omitting it — which can turn a slow search into a fast one. Combine that with keyset/offset paging tuned to your access patterns, and cap _count so a client can't request an unbounded page.

    Caching the right things

    • Terminology (ValueSet/CodeSystem) validation is expensive; cache it and pre-expand large value sets rather than expanding per request.
    • Cache the CapabilityStatement and other rarely-changing metadata responses.
    • Be careful caching clinical resources — freshness matters; prefer caching reference data over patient data.

    Validation in the hot path

    Full profile validation (e.g. against US Core) on every write is correct but costly. Decide deliberately where validation runs: strict validation on ingestion boundaries, and lighter checks internally, rather than validating everything everywhere. Precompiling and caching the validation support (structure definitions, value sets) avoids repeated expensive setup.

    Bulk and $export

    Large data movement should not go through normal search. Use HAPI's bulk export ($export) for population-scale reads, run it against a read replica where possible, and keep it off the interactive path so a big export doesn't degrade clinician-facing latency.

    Measure, don't guess

    • Turn on slow-query logging in the database and look at the actual SPIDX queries behind slow FHIR searches.
    • Load-test with realistic search patterns, not just reads by id — search is what falls over.
    • Separate read and write workloads (replicas) once a single node is saturated.

    Tuned properly — right database, only the search parameters you need, controlled totals, cached terminology, and bulk kept off the hot path — HAPI FHIR runs comfortably in production. Almost every performance problem is a configuration decision, not a framework limit.

    Frequently Asked Questions

    Almost always the database and search configuration, not the framework. Bloated search-index (SPIDX) tables, indexing search parameters you don't use, and computing exact search totals over large sets are the top causes. Tune the database and disable unused search parameters first.

    Building on FHIR?

    We build production-grade FHIR services, facades, and integrations for healthcare teams — HIPAA-ready and interoperable from the first commit.