LMS Migration Without Losing a Single Grade

We move Moodle, Blackboard, Canvas, and Brightspace sites with the grade history intact — and hand you a verification report that proves it.

  • A row-count + checksum verification report on every move — proof, not "it transferred fine."
  • Grade history preserved, including mdl_grade_grades_history — the table careless moves drop.
  • Fix-it-free guarantee plus 30 days of post-move support.
ZERO-DATA-LOSS MIGRATION Every row reconciled PASS LEARNER-DATA TABLE SOURCE DEST mdl_grade_grades 48,210 48,210 mdl_grade_grades_history 191,884 191,884 mdl_scorm_scoes_track 62,540 62,540 mdl_user · active 3,412 3,412 per-course grade checksum MATCH ✓ Source vs destination, reconciled before cutover. sha256 a1f93c7e = a1f93c7e byte-for-byte
A zero-data-loss LMS migration means grades, grade history, user accounts, and SCORM tracking all arrive intact — verified by row counts and checksums, not promises. Sternfast migrates sites in or out of Moodle, quoted per project after a free scoping call, with a byte-for-byte verification report, a fix-it-free guarantee, and 30 days of post-move support.

The part nobody warns you about

Why most LMS migrations quietly lose grade history

Content moves easily. Records don't. Every migration rescue we've been called into — and we've done plenty — traces back to one of three gaps that standard export tools simply don't cover.

1. SCORM packages don't carry runtime history

The .zip you export from Blackboard or Brightspace contains the course itself. The tracking data — cmi.core.lesson_status, cmi.completion_status, scores, attempt timestamps — lives in the platform's database and never travels with the package. Re-upload that package on the new platform and every learner starts from zero.

2. Most platforms have no historical-import API

Canvas will happily accept a current grade through its Submissions API. It has no endpoint for "this student scored 71% on attempt two in March 2024." Neither does Blackboard. Neither does Brightspace. If a vendor tells you history "comes across automatically," ask them to show you the endpoint. There isn't one.

3. Moodle keeps history — its backup tool skips it by default

Every change to every grade in Moodle is written to mdl_grade_grades_history. But course backups honor a site setting called backup_general_histories, and it ships disabled. A naive backup-and-restore migration drops every historical grade event without a single warning — the current grades look fine.

For a school district or a compliance-training operation, that history is the audit trail. Losing it isn't cosmetic.

Our process

How a zero-data-loss migration works

Five stages. The first three happen before your live site is touched at all.

1. Discovery

We inventory every table that holds learner records — grades, grade history, SCORM attempts, users, enrollments, courses — and record baseline row counts. That snapshot becomes the contract: these numbers must reconcile on the other side.

2. Mapping

Field-by-field map of where each data class lands on the destination. Anything the target platform can't hold natively gets an archive strategy, agreed in writing, before we move a byte. No surprises discovered after cutover.

3. Dry run

Full migration into a staging environment. We re-run the counts, checksum every course gradebook, and hand you the keys so your own instructors can click through before anything is scheduled.

4. Cutover

Maintenance window — usually under four hours, scheduled overnight or on a weekend. Final delta sync, URL switch, and a fresh verification pass before we unlock the doors.

5. Verification report

Source-versus-destination row counts, per-course grade checksums, and an exception log. You get the proof in writing.

Under the hood

Anatomy of a grade-history-preserving migration

Here's the actual playbook for the most common case — moving a self-hosted Moodle site to new infrastructure or a new host. We're publishing it because most of it isn't secret; it's just tedious, and tedious is where shortcuts get taken.

  1. Baseline the source. Before anything else, capture the numbers you'll verify against later:
    SELECT COUNT(*) FROM mdl_grade_grades;
    SELECT COUNT(*) FROM mdl_grade_grades_history;
    SELECT COUNT(*) FROM mdl_scorm_scoes_track;
    SELECT COUNT(*) FROM mdl_user WHERE deleted = 0;
    Save the output. Both sides sign it.
  2. Match versions, then upgrade. A database restore must land on the exact same Moodle version it came from — you upgrade after the move, not during. Sites still on 4.1 or 4.4 have been past security EOL since December 8, 2025, so we fold the upgrade into the same project: restore on the matching version, then step up to 4.5 LTS, which is supported into October 2027. We steer institutions away from 5.0 — its end-of-support lands this October, which makes it a strange target for a fresh migration.

Directions we run

Migration paths, and what each one involves

In or out of Moodle — we don't care which direction the ship is sailing, only that nothing goes overboard.

DirectionWhat moves cleanlyThe hard partWhere the history goes
Moodle → CanvasCourse content, users, enrollments, current grades via APICanvas has no historical-grade import; question banks need restructuringSealed read-only archive of mdl_grade_grades_history (CSV + database extract), delivered with the report
Blackboard → MoodleCourse exports convert; Grade Center final grades importQuestion pools and adaptive-release rules need hands-on rework; SCORM attempts don't travel in exportsHistorical grade events archived; SCORM packages re-linked and re-verified in SCORM Cloud
MoodleCloud → self-hostedEverything — a full site archive restores complete, history includedGetting the archive and sizing the new server correctlyNothing to archive: mdl_grade_grades_history lands intact. The clean escape from the 750-user cap
Brightspace → MoodleContent via Common Cartridge; gradebook export → final gradesQuizzes and release conditions need rebuilding by hand, not scriptsHistorical grades archived in agreed format before cutover

MoodleCloud-to-self-hosted deserves the highlight: it's the one direction where full history preservation is straightforward, and if you land on our managed Moodle hosting, the migration itself is free. A different direction not listed here? Ask — the mechanics rhyme.

Project sizes

How we scope it — openly

Agencies often quote a wide range for a migration, usually without defining what "done" means. Our scope is on the page, and "done" means the verification report reconciles.

Small site

Up to 200 users. Full process — discovery, mapping, dry run, cutover, verification report. No abridged version.

Start with the free risk review

Mid-size site

The typical school, association, or training company. Exact quote after the risk review — the scope moves with data complexity, not user count alone.

Get a fixed quote

Large or multi-site

Districts, multi-tenant setups, sites with years of SCORM attempt data. Scoped after discovery, agreed before work begins, never open-ended.

Talk to us

Proof, not promises

The verification report you receive at handover

"Everything transferred fine" is not a deliverable. This is:

✓

Row-count reconciliation — source vs destination, side by side, for grades, history, attempts, users, and enrollments.

✓

Per-course grade checksums computed on both sides. Matching hashes are mathematical proof that a gradebook survived unchanged.

✓

SCORM attempt counts per package. If a package was mistracking before the move, the report says so — and our flat-fee SCORM repair can fix it.

✓

User account reconciliation — created, merged, and suspended accounts, each one accounted for by name.

✓

Exception log — anything excluded or archived, why, and exactly where it now lives.

The guarantee, in plain words: if anything turns out to be missing after cutover, we fix it free. Every migration includes 30 days of post-move support for the small stuff that only surfaces in real use. And because grade data is student-record data, the whole process runs FERPA-aware, with a DPA template ready for your counsel — details on our compliance page.

FAQ

LMS migration questions we get asked

How long does an LMS migration take?

Small sites: one to two weeks end-to-end, and most of that is dry run and verification, not downtime. Mid-size: three to six weeks. The cutover window itself — the only time your site is actually offline — is usually under four hours, scheduled overnight or on a weekend.

Will my learners lose their grades or course progress?

No. Current grades, grade history, and SCORM attempt data are all in scope, and the verification report proves they arrived. Where a destination platform can't hold something natively — historical grade events on Canvas, for example — it's archived in a format we agree on before cutover, never silently dropped.

Can you get us off MoodleCloud?

Yes — usually a site hitting the 750-user cap. It's the cleanest direction: a full site archive restores with grade history intact, and migration is free if you land on our managed hosting.

Do we need to upgrade Moodle before migrating?

No — we fold the upgrade into the migration. If you're on 4.1 or 4.4, you've been past security end-of-life since December 8, 2025, and the move is the right moment to land on 4.5 LTS, which is supported into October 2027.

Further reading. Migrating because your Moodle version went end-of-life? Start with Moodle 4.1 and 4.4 are end-of-life: your three upgrade paths — it maps the costs before you commit.

Start here

Start your free migration risk review

Tell us your platform and version. An engineer replies within one business day with your data-loss risks, a version path, and a fixed quote — a working call, not a sales pitch.

  • An engineer replies within one business day.
  • You leave with your version path, data risks, and a fixed quote.
  • Useful even if you never hire us.

Goes to an engineer's inbox and nowhere else — no newsletter, no list. Prefer to talk? Call (615) 396-7139.