HAPI FHIR MDM for patient matching: when your server needs it
If a FHIR-based system holds duplicate Patient or Practitioner records that arrive from several sources, the HAPI FHIR MDM module links those records to golden resources inside a HAPI FHIR JPA server. The module is designed for organizations that need the matching logic to live on the server itself, so every client that writes to the server gets the same linking behavior. The HAPI FHIR JPA server documentation lists MDM among the capabilities it covers, alongside FHIR DSTU2, DSTU3, R4, R4B and R5 support, terminology services, validation and partitioning.
Before you commit to this approach, be aware that the EMPI module, an older master patient index option in the same ecosystem, is deprecated. If your current design or an earlier proof of concept assumes EMPI, plan the move to the MDM module at the start rather than treating it as a later cleanup. Confirm with your HAPI FHIR version which MDM configuration options are available, since the module's behavior and settings can change between releases, and check the versions documentation for the release line you intend to run.
The decision comes down to where matching should happen. If your sources can each run their own matching, or if a separate master data system already owns patient identity and feeds clean data into FHIR, a server-side MDM module may add a second source of truth you then have to govern. If instead your FHIR server is the point where records from registration, referrals, laboratory and imports converge, and you need one consistent answer regardless of which client writes, the module fits the problem. Ask who owns the matching rules, who reviews possible matches, and whether clinical and data governance teams have agreed on what a golden record means for your organization.
Plan for the operational load early. MDM adds work on every write that touches Patient or Practitioner resources, so you should size the database and test write volumes against realistic import patterns before go-live. You also need a process for possible matches that a person must resolve, with roles, service levels and an audit trail for merges and unmerges. Confirm the database platform you intend to use, because the JPA server starter defaults to an embedded H2 database, supports PostgreSQL and Microsoft SQL Server for production and does not support MySQL.
Finally, decide how MDM interacts with the rest of your server design. If you plan to use partitioning for multitenancy or regional separation, test whether matching should cross partitions and document that boundary before loading production data. The security layer is also yours to design: HAPI FHIR provides building blocks such as the AuthorizationInterceptor and BALP audit logging rather than a complete control set, so confirm who may view, merge or unmerge golden records before the matching rules are finalized.
Which HAPI FHIR MDM matching options fit your patient data
This table compares the decisions a team makes before writing MDM matching rules, with the review workload each option tends to create. Read each row as a question to answer for your own data sources, then check the option against the MDM documentation for your HAPI FHIR release before committing.
| Decision | When it fits | Review workload trade-off |
|---|---|---|
| Exact or identifier-based matching | Sources share a reliable national or organizational identifier that is consistently populated and correctly entered | Lowest review volume, but missing or mistyped identifiers create false negatives that surface later as duplicates |
| Fuzzy or attribute-based matching | Identifiers are sparse or inconsistent and demographics such as name, birth date and address are captured reliably | Catches more duplicates, but produces more possible matches that staff must review before linking |
| Auto-link threshold | Source data quality is high and reviewers accept automatic links for high-confidence pairs | Reduces queue size, but wrong automatic links are harder to unwind once downstream systems use the golden resource |
| Possible-match review threshold | Mid-confidence pairs need a human decision because demographics overlap for families, twins or common names | Largest reviewer workload; plan staffing, queue ownership and turnaround expectations before go-live |
| Golden resource survivorship | Several sources supply conflicting values for the same field and one trusted value must be chosen for the golden record | Simple rules are easier to explain to clinicians; complex per-field rules need test cases and ongoing governance |
| Separate Practitioner matching | Practitioner records come from a different directory or credentialing source with its own identifiers | Adds a second rule set and review queue; confirm how your release configures Practitioner matching separately from Patient matching |
| Matching against live feeds or batch loads | Source systems send continuous updates that must be linked as they arrive | Requires throughput and error handling planning; batch loads allow reviewers to work in scheduled windows but delay linkage |
How the MDM module links duplicates to golden resources
The MDM module decides, for each incoming Patient or Practitioner record, whether it describes someone the server already holds, and it records that decision as a link. When a source record is created or updated, MDM compares it with candidate records selected by the matching rules you configure, then assigns each candidate an outcome based on how well the compared fields agree. Because candidate selection depends on which fields the rules use, the quality of your identifiers, names, birth dates and other match fields determines what the module can ever find. Confirm in the MDM documentation for your release how candidates are selected, how scores or thresholds are set, and whether evaluation runs when a record is written or in a separate batch step.
The golden resource is the surviving record that represents one person or practitioner in the MDM view, and the source records are the duplicates that link to it. Each source record stays in the server with its original content, so the link is a relationship rather than a merge that discards data. Downstream systems that query through MDM-aware search see the golden resource, which carries the consolidated view. Your clinical and data governance teams should decide, before go-live, which source system is trusted for each field, because the golden resource is what clinicians and integrations will rely on. Confirm how golden resources are created, whether a source record can become the golden resource, and how audit trails show which source contributed each value.
A possible match means the module found a candidate that is close enough to review but not close enough to link automatically. A confirmed match means the link is accepted and the source record is attached to the golden resource. Possible matches usually need a person to decide, so your operations team must own the review queue, define who can confirm or reject a candidate, and agree on how quickly reviews are completed. Downstream consumers should generally treat only confirmed links as established identity. Confirm the exact link state names used in your release, the steps a reviewer uses to confirm or reject a candidate, and what the module does with a rejected candidate the next time the source record changes.
Before go-live, run a test set that includes known duplicates and known distinct people through your matching rules, record which links are created, and review every possible match outcome. Plan for the cases where a source record's identifiers change, and for correcting an incorrect link, since removing a link can change what the golden resource shows. Ask your platform team to confirm in the release documentation how unlinking, re-evaluation and reprocessing of existing records behave. Use synthetic or governed test data so that the validation itself does not expose patient information outside approved environments.
Setting up HAPI FHIR MDM patient matching step by step
This sequence takes a HAPI FHIR JPA server from a confirmed JDK and database choice to an MDM setup that has been tested on known duplicates before any production data arrives. Each step closes with a check, so the team can confirm the server, rules and results are working before a production feed is connected.
Confirm the JDK and release pairing
The platform engineer checks the target HAPI FHIR release against the HAPI FHIR versions documentation before installing anything. HAPI FHIR 8.2.0 requires JDK 17, so the build pipeline, runtime image and host must all use that JDK. Record the chosen release, JDK build and base image in the change record. The step is complete when the server starts on that JDK and its capability statement reports the expected release version.
Choose and provision the production database
The architect selects PostgreSQL or Microsoft SQL Server, since the starter supports both for production and does not support MySQL. The embedded H2 default is for evaluation only and should not carry patient data. The database team provisions the instance, creates a dedicated schema owner account, and agrees on backup and restore ownership with the DBA. The step is complete when a connection test from the server host succeeds and the backup job is confirmed in writing.
Deploy the JPA server starter
The platform team deploys the hapi-fhir-jpaserver-starter using the method that matches the organization's runtime, such as the hapiproject/hapi Docker image, Docker Compose, Spring Boot, a WAR on Tomcat, Jetty or Wildfly, or a Kubernetes Helm chart. Database connection settings point to the chosen production database, and secrets are injected from the organization's secret store. The step is complete when startup logs show the database connection opened without errors and the server answers a metadata request through the intended ingress.
Enable and configure the MDM module
The engineer enables the MDM module in the JPA server configuration and sets the resource types it manages to Patient and Practitioner. The team decides how golden resources will be exposed to consuming systems and which identifiers are retained on linked records. Settings should be stored in version control with the rest of the deployment configuration. The step is complete when MDM processing runs on a test Patient create without errors in the logs and the configuration is committed.
Define matching rules for Patient and Practitioner
The informatics lead writes separate matching rules for Patient and Practitioner, using fields such as identifiers, names, birth date and gender for patients and practitioner identifiers and names for clinicians. Confirm the exact rule syntax, match result categories and field weighting against the MDM documentation for the release in use, because the format changes between versions. The step is complete when the rule file loads at startup and a set of sample record pairs produces the outcomes the team expects.
Load a test dataset with known duplicates
The data team builds an illustrative synthetic dataset that includes exact duplicates, near duplicates with spelling or date variations, and clearly different people, with an answer key stating the expected outcome for each pair. Records are loaded through the server's standard API, using transaction bundles where practical. Use only synthetic data in non-production environments. The step is complete when every seeded pair resolves to its expected link state or possible-match state.
Review links and possible matches before go-live
The data steward reviews the links, possible-match queue and golden resources produced by the test load, comparing each result with the answer key. Where results are wrong, the team adjusts the rules, reloads the same dataset and confirms that results repeat. The agreed thresholds, known limitations and review workflow for possible matches are documented. The step is complete when the repeated reloads produce identical results and the steward signs off before any production feed is connected.
Handling possible matches and duplicate golden records
Once MDM matching is switched on, the work that matters most is operational: someone has to decide what happens to every link the engine is unsure about, and someone has to notice when the golden records themselves drift out of step with the source data. Plan that work before go-live. In HAPI FHIR's MDM module, a possible match is a candidate link that the matching rules scored as plausible but not certain, and it sits in a queue until a person acts on it. Name the reviewers (typically data stewards or registration staff who understand patient identity, not general developers), agree on how many people will cover the queue, and decide who can override a decision made by someone else.
A reviewer confirms or rejects a link through the MDM link workflow exposed by the module's operations. Confirming a possible match turns it into a match, which attaches the source Patient or Practitioner to an existing golden resource. Rejecting it records a no-match decision, so the engine should not propose the same pair again on the next evaluation. Merged and split golden resources need a separate procedure. A merge combines two golden records after a link shows they describe the same person, and a split undoes a link that was wrong. Confirm with your release how merge and split operations are exposed, whether they carry an audit trail of who acted and why, and how links to downstream systems are updated after a split. Do not assume the module gives you a reviewer interface. Build or buy one if your release does not supply it.
Duplicate golden records are a different problem. They appear when the matching configuration or data quality changes after records were already linked, or when two golden resources are created for the same person before the engine connects them. Schedule a recurring check that compares golden resources on identifiers and key demographics, and route suspected pairs into the same review queue. Review workload rises as matching rules become looser, because more pairs fall into the possible-match band, and it rises again when source data is poor, such as missing dates of birth, inconsistent name formats or reused identifiers. A small change to thresholds can multiply the queue, so test rule changes against a sample of historical data and measure the queue before enabling them.
Expect some of this work to need custom tooling. Confirm in your HAPI FHIR release which of these exist out of the box: a reviewer interface, the confirm and reject operations, merge and split operations, an audit record for each decision, and a report of possible duplicates. Anything missing becomes a build item with its own scope, testing and support. Also confirm how decisions are secured, since reviewers must not see or change records outside their permissions. Write these answers into your scope document before the first live queue so that operations, security and compliance teams agree on the same process.
Protecting patient identifiers during MDM matching
HAPI FHIR provides security building blocks that your team assembles into one access design for matching data. The cards cover how to control access to golden resources and review queues, how to audit access, how the database and backups hold patient data, and how to test the rules against the matching feature.
Combine the security interceptors deliberately
HAPI FHIR documents authentication interceptors, the AuthorizationInterceptor, consent and search narrowing interceptors, CORS support and BALP audit logging as separate components. Decide which ones your deployment needs and the order in which they apply to each request. Write this design down before configuring anything, because MDM adds resource types and endpoints that a generic rule set may not cover.
Limit reads of golden resources
Golden resources combine data from several source records, and possible-match links expose candidate pairs that carry identifiers from both sides. Use AuthorizationInterceptor rules to separate who can read golden Patient records from who can see possible-match queues. Consider search narrowing so results only include records a user is allowed to see. Illustrative: a registration clerk may need one patient's demographics without seeing every pending candidate pair.
Authenticate every caller, including jobs
Authentication interceptors decide who reaches the server at all, and matching work involves staff, integration engines and scheduled loaders calling the same endpoints. Give automated loaders and matching jobs their own identities so their access can be scoped and revoked without touching staff accounts. Review CORS settings as well, since they control which browser origins can call the server, and limit them to applications that need access.
Audit access with BALP logging
BALP audit logging records access to FHIR resources through the server, giving you a trail of who read patient data. Confirm with the HAPI FHIR security documentation exactly which operations BALP covers, and whether MDM link changes and merge decisions appear in that trail or need separate logging. Plan log retention and shipping to a central store, since the trail only helps if reviewers can search it during an investigation.
Protect the database and its backups
The JPA server starter defaults to an embedded H2 database, so production deployments use PostgreSQL or Microsoft SQL Server, which the starter supports. Restrict database accounts to the server process and to named administrators. Treat every backup as a full copy of patient data, including golden and link records. Confirm encryption at rest, backup retention and restore testing with your platform team before go-live.
Test access rules against matching
Access rules are proven only when tested with the request patterns people and jobs actually send. Build a test matrix of roles and resource types that covers direct reads of golden resources, searches that could reveal possible matches, and the MDM operations your staff and jobs call. Rerun the matrix after each rule change and each upgrade, and keep the results with your change records. Use test accounts and synthetic patients, never production identifiers.
Moving from the deprecated EMPI module to HAPI FHIR MDM
Teams running the deprecated EMPI module need a planned migration path before support pressure forces a rushed move. The move changes three things: matching configuration, stored links and golden resource state. Start by confirming the current deprecation status and any support end dates in the HAPI FHIR documentation for your version, because this page does not set those dates. Decide early who owns the migration, who signs off on matching behavior, and how long EMPI stays available for rollback.
Matching configuration does not carry over as a copy. Each EMPI setting needs a mapped equivalent in MDM rules and thresholds, or a written reason for dropping it. Stored links between source Patient and Practitioner records and their golden resources must either be carried over or rebuilt, and the match results behind them should stay traceable for audit. Golden resource state also needs attention, because clients may hold references to golden records that will look different or be reconciled after the move.
Take the inventory before designing any migration step. Export the matching rules and thresholds as they run in production, not as they appear in original design documents, and record which rules drive the most links. Export existing links and group them by status. Review the possible-match backlog and decide, item class by item class, whether each entry is resolved, carried forward or re-evaluated. Then list every client and integration that depends on EMPI behavior: which resources they read, whether they assume particular golden identifiers, how they handle merged records, and whether they call EMPI-specific operations. Each dependency becomes a test case.
Run MDM in parallel with EMPI before any cutover. Use a copy of production data or a sanitized replica in an environment you control, send the same incoming Patient and Practitioner submissions to both systems, and compare link decisions, possible-match output and golden record selection. Classify each difference as an expected improvement, a rule gap or a defect, and agree in advance which categories block cutover. Script the comparison so it can be rerun after every rule change, since a single rerun rarely settles the matching behavior.
The exact data migration steps depend on the EMPI version in use. Confirm the procedure, supported upgrade paths and any prerequisite fixes against the current HAPI FHIR documentation and the release notes for your target version before setting a cutover plan. Also confirm the JDK and database requirements for that release using the HAPI FHIR versions documentation, and rehearse the full sequence in a test environment. Record which steps were verified and which still need confirmation with the vendor or the documentation owner.
What to confirm before relying on MDM for patient matching
Before you rely on HAPI FHIR MDM to link patient and practitioner records, confirm the technical limits of your chosen release and environment. The checks below cover versions, databases, matching rules, write load, partitions and compliance evidence, and each one should be closed in writing before a production decision.
Release and JDK requirement
Confirm which HAPI FHIR release your MDM configuration will target and the JDK that release requires before you pin versions. The project's versions documentation states that HAPI FHIR 8.2.0 requires JDK 17, so a newer release line may need a different runtime. The most recent release at the time of writing is v8.8.2, released 25 September 2026. Review the release notes for MDM changes between your chosen version and the one you plan to run.
Supported production databases
The JPA server starter defaults to an embedded H2 database, which is suited to evaluation. For production, the project documents PostgreSQL and Microsoft SQL Server, and it does not support MySQL. Confirm that your MDM tables, matching indexes and backup tooling work with the database engine and version your organization runs, and that your database team can operate it.
Practitioner matching rules
MDM links duplicate Patient and Practitioner records, so the matching rules for Practitioner resources must exist in your configuration. Check whether the rule set you need for Practitioner records is available as configured in your chosen version, including the identifiers your source systems use for clinicians. Run a sample of known duplicate Practitioner records through the rules and review the candidate links before any production load.
Behavior under high write volume
Confirm how MDM processing is triggered by create and update events in your version, and whether it keeps pace with your expected load. Test with peak create and update traffic, including bulk loads from source systems. Measure queue backlog, link latency and database load, and decide whether matching should be deferred or re-run after large imports.
Matching across partitions
Partitioning places each resource in a partition for multitenancy, separate data sources or regional grouping. Confirm whether MDM links can span partitions, which partition holds golden resources, and how possible matches are reviewed for each tenant. Test with two partitions holding overlapping patients before you rely on any cross-partition outcome, because linking with partitioning needs confirmation for your release.
Compliance outcomes stay with you
Compliance outcomes depend on your organization's own assessment and on the independent auditor or certification body that reviews it. DeployOpen can prepare configurations, test evidence and documentation for a compliance assessment, but it does not issue audit reports, attestations or certifications. Ask your assessor which matching evidence they need before the build starts.
Questions buyers ask before hiring help with HAPI FHIR MDM
What drives the cost and effort of a HAPI FHIR MDM project?
The main drivers are the number of source systems feeding Patient and Practitioner records, the complexity of matching rules, the state of data quality in those sources, the design of the review workflow for possible matches, whether you are migrating off an existing EMPI, and how many client systems must read golden resources.
Who is paid for what: an implementation partner is paid for analysis, rule design, configuration, testing, integration and handover. Your team pays for its own reviewers and decision time, plus the infrastructure you run the server on.
One-time versus recurring: build work is one-time. Rule tuning, review queue operations and server upgrades recur.
Ask any provider for a quote that lists each driver separately, names the source systems, and states what is excluded.
How long does a HAPI FHIR MDM implementation take?
Duration depends on the same drivers as cost: how many sources you have, how many matching rules you need, how dirty the data is, and how much migration or client integration is in scope. A project with one clean source and a simple rule set takes far less time than one that merges several legacy registries and replaces an EMPI.
DeployOpen does not publish durations. A timeline follows from the written scope, which should break work into phases such as discovery, rule design, build, test with reviewers, and cutover. Ask for the assumptions behind each phase, including how many review cycles are expected.
What does the client need to provide for an MDM project?
Expect to provide representative test data from each source system, including known duplicates if you have them. You will also need clinical or data governance reviewers who can judge whether two records describe the same person, and a decision owner who can approve matching thresholds and the handling of possible matches.
Infrastructure access matters too: a test environment, database access for the HAPI FHIR JPA server, and network paths to source systems. Confirm early who owns each of these items, because delays in reviewer time or data access usually affect the schedule more than the code does.
Can our in-house team implement HAPI FHIR MDM without a partner?
Yes, a team with Java, FHIR and database skills can build MDM with the HAPI FHIR JPA server, since it is open source under the Apache Software License 2.0. The harder part is usually not the software but the matching decisions, the review workflow and the validation against real records.
Assess your team on four points: FHIR resource modeling, Java and Spring operations, PostgreSQL or Microsoft SQL Server administration, and clinical data governance. If any of these is thin, a partner can cover the gap, or your team can own the decisions while a partner handles build and testing.
What should we ask for in a written scope for MDM help?
Ask for a scope that names each source system, each resource type in scope (Patient, Practitioner or both), the matching rules to be designed, and how possible matches will be reviewed and by whom. The scope should state whether an existing EMPI is being retired and what data migration that requires.
Also ask for the deliverables (configuration, rule documentation, test evidence, runbooks), the acceptance criteria, what is excluded, the client inputs and their owners, and the support options after handover. A fixed-scope agreement should record all of this before work starts.
Does the MDM module need a specific database or Java version?
The JPA server starter defaults to an embedded H2 database for evaluation and supports PostgreSQL and Microsoft SQL Server for production, but not MySQL. Confirm the database choice early because it shapes backup, high availability and operations.
For Java, the HAPI FHIR documentation states that version 8.2.0 requires JDK 17. Check the release you plan to use against the versions documentation and your organization's supported runtime policy before you commit to a build.
What happens to our existing EMPI when we move to HAPI FHIR MDM?
The HAPI FHIR MDM module replaces the deprecated EMPI module, so a move usually means planning how existing links and golden records are carried across rather than simply switching on a new server. Plan this as a distinct migration workstream with its own test cases.
Ask the provider how they will compare match results between the old and new systems, how they will handle records the old EMPI linked differently, and who signs off the cutover. Confirm the exact migration steps against the current HAPI FHIR documentation for your version.
How DeployOpen scopes and delivers HAPI FHIR MDM
DeployOpen plans, implements, customizes, hardens, documents and supports self-hosted open-source platforms inside your own infrastructure, and that includes HAPI FHIR MDM for patient matching. Each engagement starts from a written, fixed scope that names the record types, source systems, matching rules and handover deliverables before any build begins. The work runs in your cloud accounts, data centers or air-gapped networks, so patient data stays under your control.
How we scope
- The written scope names the Patient and Practitioner resource types and the source systems whose records feed matching.
- Matching rules, thresholds and the handling of possible matches are agreed with your data stewards before build starts.
- Work is fixed-scope, with deliverables and timelines agreed in writing before any build begins.
How we build
- Run the JPA server on PostgreSQL or Microsoft SQL Server for production, since the starter defaults to embedded H2.
- Write MDM matching rules as version-controlled configuration, then test them against labeled sample record pairs.
- Set up the review queue for possible matches and the merge process for confirmed duplicates with roles defined.
How we hand over
- Documentation covers the rule set, thresholds, golden resource behavior and the steps to review possible matches.
- Your team receives runbooks for rebuilding links, reprocessing records and changing rules after go-live.
- Knowledge transfer sessions walk operators and data stewards through the review workflow before handover is signed off.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers once the system is live.
- Plan HAPI FHIR upgrades against the JDK requirement for each release, such as JDK 17 for version 8.2.0.
- Re-run match tests after each rule change, library upgrade or onboarding of a new source system.

