EHR MigrationData MigrationFHIRGuide

EHR Data Migration: A Step-by-Step Guide to Moving Patient Data (2026)

March 14, 202614 min readUpdated Oct 19, 2026
Written by
Yogesh Daga
Yogesh Daga

Founder & CEO

15+ years building healthcare technology. Founder & CEO of Nirmitee.io, whose teams deliver EHR integrations, FHIR and HL7 platforms, ABDM and NHCX connectivity, and clinical AI for health systems and healthtech companies.

EHR Data Migration: A Step-by-Step Guide to Moving Patient Data (2026)

EHR data migration is the work of moving patient records from an old electronic health record (EHR) into a new one so clinicians can treat patients on day one without opening the old system. Done well, it is a short list of decisions (what moves, in what form, and who signs it off) followed by repeated test loads that are checked until the numbers and the charts match.

Updated October 2026. This is a full guide on health data migration for US providers and digital health companies. It covers the full data migration process from EHR to EHR: the phases, what to migrate and what to archive, how mapping works, the checks that prove the data arrived, cutover and rollback, the special case of Cerner (Oracle Health), the drivers of cost, and a checklist you can use as acceptance criteria. If you would rather hand the work to a team that does it, see our healthcare data migration services. It is part of our EHR software development guide.

What is EHR data migration?

EHR data migration, also called EMR data migration, health data migration or healthcare data migration, is the transfer of clinical, administrative and billing data from a legacy system to a new one, converted into the structure and codes the new system expects. It is different from an interface. An interface keeps two live systems in step every day; a migration is a one-time move (usually in several test rounds and one final load) after which the old system stops being the source of truth.

Most EHR data transfer projects include three kinds of data:

  • Discrete data: structured values the new EHR can calculate with, such as allergies, medications, problems, immunizations, lab results and vitals.
  • Documents: notes, discharge summaries, scanned PDFs and images that clinicians need to read but the system does not need to compute.
  • Administrative and financial data: demographics, insurance, appointments, balances and open claims.

Each kind moves differently, and most of the cost and risk sits in the first one.

The EHR data migration process in six phases

A reliable electronic health record data migration follows six phases: inventory, scope decisions, extraction and mapping, test loads, reconciliation, and cutover. The loop between test loads and reconciliation is where the real work happens; plan for several rounds, not one.

PhaseWhat happensOutput you should hold
1. InventoryList every source system (EHR, practice management, lab, imaging, scanned document store), the tables or exports each offers, record counts and the years covered.Source inventory with volumes
2. Scope decisionsFor each data type decide: migrate as discrete data, migrate as documents, archive read-only, or leave. Clinicians and compliance sign each line.Signed scope matrix
3. Extract and mapPull data out (FHIR Bulk export, EHI export, database extract or vendor tool) and map fields, codes, units, providers and locations to the target.Mapping specification and code crosswalks
4. Test loadsLoad into a copy (test environment) of the new EHR, never into production first.Load logs with rejected rows and reasons
5. ReconciliationCounts, values, codes and clinician chart review. Fix and reload until it passes.Reconciliation report per round
6. CutoverFreeze the old system, run the final delta load, go live, keep a rollback path until sign-off, then archive.Go-live sign-off and archive access

Before phase 1, it helps to size the job. Our legacy EHR data migration sizing guide shows how to estimate volumes and effort from the source system before anyone quotes a price.

What should you migrate, convert to documents, or archive?

Migrate as discrete data only what a clinician needs to treat the patient in the coming weeks; convert older clinical history into readable documents; archive the rest read-only for the legal retention period. Trying to convert every historical value into discrete data is the most common reason migrations overrun.

Data typeUsual decisionWhy
Demographics, identifiers, insuranceMigrate, discreteEvery downstream record hangs off the patient
Allergies, active medications, active problemsMigrate, discreteDrive safety checks such as drug-allergy alerts
ImmunizationsMigrate, discrete (full history)Needed for schedules and registry reporting
Lab results and vitalsRecent period discrete, older as a summary documentTrends need discrete values; old values are read, not graphed
Clinical notes, discharge summariesMigrate as documentsRead by clinicians, rarely computed
Scanned documents and imagesMigrate as documents, or link to the image archiveLarge files; keep links valid
Future appointments, open orders, referralsMigrate, discreteMissed ones become missed care
Closed claims and old balancesArchive, read onlyNeeded for audits and appeals, not daily work
Audit trails and old user accountsArchive, read onlyLegal record; rarely needed in the new EHR

How long you must keep archived records is set by state law and by payer contracts, not by HIPAA alone, so the archive period is a decision for your compliance lead. The cutoff for "recent" discrete data (for example, the last two years of results) is a clinical decision; there is no single correct number.

How do you get data out of the old EHR?

There are four practical extraction routes, and most projects use more than one.

RouteWhat you getGood forWatch for
FHIR Bulk Data export ($export)NDJSON files of FHIR resources for a group of patientsStructured clinical data in a standard shapeCovers the US Core data set, not everything in the chart
EHI exportThe vendor's full electronic health information export, often as tablesCompleteness; certified EHRs must offer itVendor-specific table layouts that still need mapping
Database extract or reporting copy (an EHR database migration)Raw tablesVolume and history the APIs do not exposeNeeds access rights and deep knowledge of the schema
Vendor or third-party conversion toolPre-built extract and load for known source and target pairsCommon pairs where a tool existsCoverage gaps for custom fields

The EHI export route exists because of the ONC certification criterion for electronic health information export (45 CFR 170.315(b)(10)), which requires certified EHRs to export a single patient's EHI and a whole population's EHI. The information blocking rule (45 CFR Part 171) limits how a vendor can refuse or delay access to that data, though it allows reasonable, cost-based fees under defined exceptions. Read your contract's data return clause before you give notice to your current vendor.

How does data portability with FHIR help an EHR migration?

FHIR data portability means patient data can leave an EHR in a published, standard format (FHIR R4 resources, as profiled by US Core) instead of a proprietary dump. For an EHR migration, that gives you a known starting shape for the most important clinical data and a way to pull it in bulk.

  • Bulk export: the HL7 FHIR Bulk Data Access specification defines $export at system, patient and group level. The server works asynchronously: you start the export, poll a status URL, then download NDJSON files.
  • Group export for phased moves: exporting by group lets you migrate one clinic or one cohort at a time.
  • Certification: ONC-certified EHRs must support the standardized API for patient and population services (170.315(g)(10)), which includes bulk export for a group of patients.

FHIR portability does not remove mapping. The target system may use different code systems, local value sets, provider IDs and location IDs, and notes may arrive as references to documents that still need to be fetched. Treat FHIR as the best available extraction format for core clinical data, not as a migration that runs itself. Our bulk FHIR export guide for Epic, Oracle Health and athenahealth shows how each vendor implements it.

# Start a group-level bulk export (FHIR Bulk Data Access)
GET [fhir-base]/Group/[group-id]/$export?_type=Patient,AllergyIntolerance,MedicationRequest,Condition,Observation,Immunization
Accept: application/fhir+json
Prefer: respond-async
Authorization: Bearer [token]

# 202 Accepted, Content-Location: [status-url]
# Poll the status URL until 200, then download each NDJSON file listed in "output"

Questions to ask your current vendor before you sign the new contract:

  1. Which FHIR resources does your bulk export include, and for which patient groups?
  2. What does your EHI export contain beyond FHIR, and in what file format?
  3. Are notes, scanned documents and images included, or exported separately?
  4. What fees apply to exports, and on what basis?
  5. How long will you keep read access to the old system after the contract ends?
  6. Will you provide the data dictionary for custom fields and local codes?
  7. Who on your side supports the export, and with what response time?

How does mapping work? A worked example

Mapping translates each source field and code into the target's field and code, and records what happens to anything that does not fit. Below is a small, invented example for an allergy record moving from a legacy system into a FHIR-based target.

Source field (legacy)Example valueTarget (FHIR AllergyIntolerance)Rule
PAT_IDLEG-004211patient (reference)Look up the new patient ID from the identity crosswalk
ALG_CODEPCN01 (local)code: SNOMED CT 764146007 "Penicillin"Local code crosswalk, reviewed by a pharmacist
ALG_FREE_TEXT"pcn - hives"code.text, reaction.manifestationKeep the original text; map "hives" to urticaria
SEVERITY3reaction.severity: severe1-2 = mild, 3 = severe; agreed with clinicians
STATUSAclinicalStatus: activeA = active, I = inactive, E = entered in error (do not migrate)
ENTERED_DT03/07/2019recordedDate: 2019-03-07Source is MM/DD/YYYY; confirm with a sample
(no code match)"tree nut mix"Not loaded as coded dataSent to a review queue; never silently dropped

Three rules keep mapping honest. Keep the original text alongside every converted code. Send anything that does not map to a human review queue with a reason. Version the mapping specification, because it will change after every test load.

How do you prove the data arrived? Reconciliation checks

You prove a migration with four kinds of checks run on every test load: counts, values, meaning and clinician review. Passing counts alone is not proof; a load can have the right number of rows with the wrong units or the wrong patient.

CheckHowPass rule (set before the first load)
Patient countsSource patients in scope vs target patients created plus rejectedEvery patient accounted for
Per-type countsAllergies, medications, problems, results, immunizations per patientDifferences explained row by row
Values and unitsSample of lab values compared after unit conversionNo unexplained difference
Dates and time zonesBirth dates and result times comparedNo shifted dates
Financial totalsOpen balances and open claimsMatch to the cent
Code mappingShare of codes mapped; review queue sizeEvery unmapped code reviewed
DuplicatesPatient matching on name, birth date and identifiersPossible duplicates reviewed by registration staff
Clinician chart reviewClinicians compare sample charts side by side, high-risk patients firstSigned off by a named clinician

Cutover and rollback

Cutover is the short window in which the old system stops taking new data, the final changes move across, and the new EHR becomes the source of truth. Plan it as a rehearsed script, not an event.

  1. Rehearse the full load at least once in the test environment with production-sized data, and time it.
  2. Freeze the old system for new entries (or switch it to read-only) at an agreed time.
  3. Delta load only the records created or changed since the last full load.
  4. Run the reconciliation checks again on the delta, with a smaller clinician review.
  5. Go live, with go-live support staff watching for missing data reports.
  6. Keep rollback possible until clinical sign-off: the old system stays readable, and the decision to roll back has a named owner and a deadline.
  7. Archive the old system read-only once sign-off is complete.

Cerner (Oracle Health) EMR migration: what is different

A Cerner EMR migration, now an Oracle Health Millennium migration, follows the same phases, with a few specifics worth planning for.

  • Two ways out: Millennium supports the FHIR R4 APIs and bulk export required for ONC certification, and Oracle Health offers an EHI export. Data outside those, such as custom forms, usually needs a database or reporting extract written in CCL (Cerner Command Language) or through Oracle Health's reporting tools.
  • Code sets: Millennium uses its own code values for many concepts; plan crosswalks from those code values to SNOMED CT, LOINC and RxNorm.
  • Moving into Oracle Health: when Oracle Health is the target, loads usually go through Oracle Health's conversion services or HL7 interfaces; agree the method and the test domain early.
  • Existing interfaces: list every HL7 feed into and out of Millennium; each one needs a replacement in the new EHR. Our Oracle Health integration team handles both directions.

What drives the cost of an EHR data migration?

Cost depends far more on scope decisions and data quality than on record count. These are the main drivers, roughly in order of impact.

Cost driverPushes cost upKeeps cost down
Scope of discrete historyEvery year of every value convertedShort discrete window, older data as documents
Number of source systemsSeveral systems with overlapping patientsOne main source
Data qualityFree text, local codes, duplicatesClean coded data
Custom fields and formsMany specialty templatesMostly standard content
Extraction accessVendor-only extracts, slow supportBulk FHIR and EHI export available
Number of test loadsNo clear pass rules, so loads repeatPass rules agreed before the first load
Archive approachKeeping the old EHR licensed for yearsA read-only archive with search

For how migration sits next to licenses, training and interfaces in an EHR budget, see our EHR implementation cost guide.

Patient data migration best practices

  • Agree written pass rules for reconciliation before the first test load.
  • Give each data type a named clinical owner who signs it off.
  • Never load into production first; use a copy of the new EHR.
  • Keep source text next to every converted code.
  • Route unmapped values to a review queue; never drop them silently.
  • Resolve patient identity (duplicates and merges) before loading clinical data.
  • Rehearse cutover with production-sized data and time it.
  • Keep the old system readable until sign-off, then archive it.
  • Log every load, every rejected row and every decision; the log is your audit trail.
  • Treat all extracts as protected health information: encrypted storage, access limited to the project, deletion when done.

EHR data migration acceptance checklist

Use this as the acceptance criteria in your statement of work.

#ItemEvidence
1Source inventory complete with volumesInventory document
2Scope matrix signed by clinical and compliance ownersSigned matrix
3Mapping specification and code crosswalks versionedSpec in version control
4Identity crosswalk and duplicate review completeDuplicate report signed by registration lead
5Reconciliation pass rules agreedSigned pass rules
6Final test load passed all checksReconciliation report
7Clinician chart review signedNamed reviewer sign-off
8Cutover rehearsed and timedRehearsal log
9Rollback owner and deadline namedCutover plan
10Archive access tested by end usersTest record
11Extracts deleted or secured after go-liveDeletion record

Who should do your EHR data migration?

You have three options: the new EHR vendor's conversion team, a specialist data migration firm, or your own team with outside help for the hard parts. Vendor teams know their target well but often limit what they will load. Specialist firms that do data migration for EHR projects bring tools and experience across source systems. Doing it yourself works when you have strong analysts and a single, well-understood source.

Nirmitee handles extraction, mapping, FHIR and HL7 conversion, reconciliation and archive design as one team, and works alongside the vendor's conversion team where the vendor owns the load. We are ISO 27001:2022 certified and sign BAAs. Talk to us about your EHR data migration.

Planning an EHR data migration?

Define what moves, what stays in an archive and how you will reconcile the result. Bring your source EHR, target system, available exports and proposed cutover window.

Frequently Asked Questions

What is EHR data migration?

EHR data migration is the one-time transfer of patient records from a legacy electronic health record into a new one, converted into the fields and codes the new system expects. It usually covers discrete clinical data, documents, and administrative and billing data, moved in several test loads and one final load.

What are the steps in the data migration process from EHR to EHR?

Six phases: inventory the sources, decide per data type what to migrate or archive, extract and map, load into a test copy of the new EHR, reconcile counts, values, codes and charts until checks pass, then cut over with a freeze, a final delta load and a rollback plan.

How much data should be migrated to a new EHR?

Migrate as discrete data what clinicians need to treat patients soon (demographics, allergies, active medications and problems, immunizations, recent results, open orders). Move older notes and results as documents, and archive the rest read-only for the retention period your state and payers require.

How does FHIR data portability help EHR migration?

Certified EHRs must offer FHIR R4 APIs with bulk export for groups of patients, so core clinical data can leave in a standard format (NDJSON files of FHIR resources). It gives a known starting point, but codes, provider IDs and documents still need mapping into the target.

What is the difference between EHR data migration and EHR integration?

Integration keeps two live systems exchanging data every day through interfaces or APIs. Migration moves data once so the old system can be retired; after go-live the new EHR is the only source of truth.

How do you migrate data from Cerner (Oracle Health)?

Use Millennium's FHIR R4 bulk export and Oracle Health's EHI export for standard data, and a reporting or CCL extract for custom forms. Plan crosswalks from Millennium code values to SNOMED CT, LOINC and RxNorm, and replace every HL7 interface the old system fed.

What are patient data migration best practices?

Agree reconciliation pass rules before the first load, give each data type a clinical owner, never load into production first, keep source text next to converted codes, review unmapped values instead of dropping them, resolve duplicates first, rehearse cutover, and keep the old system readable until sign-off.

What drives the cost of healthcare data migration?

Mainly scope: how many years of discrete history you convert, how many source systems there are, data quality, custom fields, how easy extraction is, how many test loads you need, and whether you archive or keep the old EHR licensed.
Share