You migrate an LMS without losing completion records by auditing the source data first, exporting completions in a format the target platform can import, mapping statuses and dates explicitly, and validating record counts against the source before cutover. VertoLaunch has run this process across Moodle, Docebo, Cornerstone, and LearnWorlds, including migrations with hundreds of thousands of user records.
Harshita C, Director of Platforms · 2026-07-31
Completion records do not live inside your courses. A SCORM package is a zip of content; the completion data it generates lives in the LMS database. Moving your course files to a new platform moves zero history. The records need their own migration path, and that path has three common failure points.
SCORM 1.2 stores learner status in a single field, cmi.core.lesson_status, with six possible values: passed, completed, failed, incomplete, browsed, and not attempted. SCORM 2004 splits this into two independent fields, cmi.completion_status and cmi.success_status. A learner can be completed but failed under SCORM 2004; that state cannot exist in SCORM 1.2. When records cross versions during a migration, a careless mapping collapses passed and completed into one value, and your compliance reports lose the difference between "finished the module" and "passed the assessment". Write the mapping table down before anything moves, and get sign-off from whoever owns compliance reporting.
suspend_data is the string a course writes to the LMS so a learner can resume where they left off. SCORM 1.2 caps it at 4,096 characters; SCORM 2004 4th edition allows 64,000. Authoring tools write it in their own internal formats, which means it is meaningful only to that course running in that environment. In practice it does not survive a platform move, so learners who are mid-course restart in the new system. Plan the cutover around that fact instead of promising otherwise.
If your training reports through xAPI, the statements sit in a Learning Record Store, not in the LMS proper. Statements are immutable by design, and the xAPI specification includes a query API built for transferring statements between LRSs, so the export side is usually clean: a JSON stream of everything ever recorded. The catch is on the import side. The new platform's reporting may not treat imported statements as first-class completion records. Verify how the target handles imported xAPI history before you assume the standard makes you portable.
Every rushed migration we have been asked to rescue skipped this step. Before anything moves, inventory what exists in the source system:
Then check what each platform will actually give you and accept. Moodle exports activity and course completion reports to CSV or Excel, and Moodle Workplace documents a historical completion upload on the import side. TalentLMS publishes a supported import path for historical course completion data. Docebo can mark users complete through its CSV enrollment import, but the standard import stamps the record with the import date; preserving original completion dates typically requires the enrollment API instead. Absorb routes historical completion imports through its technical services team rather than the standard admin tools. Enterprise platforms such as SAP SuccessFactors Learning, Cornerstone, and Workday Learning load learning history through structured connector and data-load processes, usually with the implementation team involved. None of these paths is exotic, but each has its own field formats and quirks, and you want them identified in week one, not the week of cutover.
Users come first, because every other record hangs off a user. You need one stable, unique identifier per person. Email looks obvious and fails regularly: addresses change, inboxes get shared, people leave and come back. An employee ID or a source-system GUID is safer. Deduplicate before import; a learner with two accounts has their history split in half, and no report will ever add it back together.
Enrollments need an explicit state map: what the source calls "in progress" or "waived" versus what the target supports. Decide deliberately what happens to expired and cancelled enrollments rather than letting the import tool decide for you.
For certificates, the issue date matters more than the certificate file. Recertification schedules key off original issue or expiry dates. If your import stamps every record with today's date, an entire workforce comes due for recertification on the same day next year, and that is a genuinely bad day for whoever runs the platform. Test one record end to end, check the dates it produces, and only then load the rest.
Not every record needs to live in the new LMS. For each class of record, ask two questions. Does it drive anything in the future, such as a recertification cycle, a prerequisite, or an audience rule? And does anyone need to query it day to day, or just retrieve it if an auditor asks?
Records that drive future automation belong in the new platform, imported with their original dates. Everything else can go into an archive of record: a final, validated export from the old system, completion reports as CSV and certificates as PDFs, stored somewhere durable and access-controlled outside any LMS. Auditors generally care that records are retrievable and credible, not which database serves them. A hybrid is common: import the records tied to active certifications, archive the completed one-time training. The archive route also sidesteps the platforms where importing historical dates is awkward or requires paid services.
The safest cutover is boring. Migrate records in controlled batches while the old system stays live. Have a pilot group verify their own history in the new platform, because learners spot missing certificates faster than any query does. Then set a short freeze window, run a delta sync to pick up records created since the batch migration, and go live. The old platform does not get switched off; it goes read-only, because it is your comparison baseline for everything that follows. This is the sequence we run inside our LMS implementation and migration service, and it is why launch day should be the least eventful day of the project.
For agencies, the entire run can happen under your brand. Migration is delivered the same way as our white-label eLearning development work: your client sees your team, and we stay invisible.
Validation is a checklist, not a vibe. Before the read-only source is decommissioned, all of these should pass and be documented:
A focused implementation with migration typically runs 4–8 weeks. Within that, the record-migration work usually breaks down as an audit in the first 1–2 weeks, mapping and test imports in the next stretch, then batch migration, delta sync, and validation around cutover. Complex estates run longer: enterprise platforms with connector-based history loads, multiple source systems, or years of instructor-led records all add time. The variable that moves timelines most is source data quality, which is exactly what the audit exposes early. Anyone quoting you a fixed timeline before seeing what your current platform can export is guessing.
Related reading: migrating to LearnWorlds and SCORM vs xAPI.
We'll send you our white-label partner evaluation checklist: the 30+ checks we'd run on any eLearning vendor before handing them client work, including us.
Book a 20-minute call. We'll look at what your current platform can export and tell you honestly what will survive the move, whether or not we work together.
Book Your 20-Min Discovery Call →