Forum Migration

Importers for sources nothing off the shelf covers

Sometimes the source is a bespoke forum, an abandoned platform, or a heavily modified installation that no converter was written for. That is a development project rather than a configuration one, and the work is in understanding what the source actually contains before deciding how it maps.

The problem

An uncovered source has no documented mapping, so the mapping is the work

Where a supported importer exists, someone has already decided how source structures become target structures. Where none exists, every one of those decisions is yours, and they cannot be made from the source's own documentation — because a bespoke platform's real schema is whatever its code does, not what it says it does. The work starts with reading the source.

  • The forum runs on software nobody currently maintains
  • The source was customised heavily, so it no longer matches its own documented schema
  • No converter exists for the source platform, or the available one does not fit
  • Nobody can describe the source's data model with confidence
  • Derived values — post counts, last activity, thread position — exist only as computed state
  • Content lives in places a database dump alone does not capture
  • Members' identities and the relationships between accounts must survive intact
  • The community's history is the reason the migration is worth doing at all
Who this is for

The people who usually bring us this problem

A community on bespoke or abandoned software

There is no importer because the platform is the only one of its kind, and you need the conversion built rather than found.

An operator whose platform was heavily modified

It began as something standard and no longer is, which means a supported importer would meet data it does not recognise.

Someone with content outside the database

Attachments, galleries or generated files stored somewhere the platform's own export does not reach.

What it costs

What this costs while it goes unfixed

Engineering faults are rarely confined to the engineering layer. These are the commercial consequences we see most often.

Derived state is the part that has no source to copy

Post counts, last-activity timestamps and thread ordering are frequently computed rather than stored. A conversion that moves the raw content and leaves the derived values empty produces a forum that looks migrated and behaves as though it has no history.

Relationships are harder to preserve than records

Moving a comment is straightforward. Moving who replied to whom, who moderated what, and which private messages belonged to which conversation is where an importer either works or produces a plausible-looking archive nobody can navigate.

An importer written without reading the source guesses

Assumptions made from the platform's own name or documentation are frequently wrong on a customised installation, and the errors appear as missing content weeks after cutover rather than as a failure during it.

A one-off conversion cannot be trusted without counting

Nothing about a bespoke import is standard, so nothing about it can be assumed. Reconciliation is not a formality here; it is the only evidence the migration is complete.

What we do about it

Capabilities

Each of these is work we carry out, not an area we advise on.

Source reverse-engineering

Reading the application to establish what its data model actually is — tables and their real relationships, computed columns, content in files outside the database, and the places where the code has diverged from its own documentation.

Data model mapping

Deciding how each source construct becomes a target construct, including the structures with no equivalent. The output is a written mapping, because a mapping that exists only in the developer's head cannot be reviewed and cannot be tested against.

Derived-value reconstruction

Rebuilding the state the source computed: counts, timestamps, ordering, unread markers, reputation. This is usually the largest single piece of work in a bespoke import and the part most often underestimated.

Relationship preservation

Keeping the connections that make a forum navigable — reply structures, conversations and their participants, moderation history, subscriptions, memberships.

Filesystem and foreign content

Attachments, avatars, galleries and generated files captured from wherever they live rather than only from the database, with the references that point at them rewritten to the target's scheme.

Identity reconciliation

Mapping accounts and authentication material safely, handling duplicates and orphans, and deciding explicitly what happens to accounts that cannot be carried — stated rather than silently dropped.

Idempotent, repeatable runs

The importer is built to be run repeatedly against fresh copies, because a one-shot conversion cannot be rehearsed and a migration that cannot be rehearsed cannot be trusted.

Reconciliation and cutover

Per-type counting between source and destination with every variance explained or resolved, then a rehearsed cutover with a tested rollback and an agreed observation period.

How we work

Engineering methodology

The sequence is deliberate. The order is usually what determines whether the work holds or has to be repeated.

  1. Read the source before designing anything

    On an uncovered platform the schema is discovered rather than known, and the discovery is the first phase of work. A mapping proposal produced before that reading is a proposal about a system nobody has looked at.

  2. Write the mapping down where it can be reviewed

    Every construct gets a stated outcome, including the ones with no equivalent. The document is what makes the work reviewable by the person who understands the community's history, which is frequently not the person who wrote the software.

  3. Treat derived state as primary work

    Counts, ordering and timestamps are rebuilt deliberately rather than expected to emerge. They are invisible when correct and immediately obvious when wrong, and they are the difference between a migrated forum and a migrated archive.

  4. Make the importer re-runnable

    Every rehearsal runs against a fresh copy, so the conversion is exercised many times before it faces real members. This is what makes the problems that only appear on real data appear during rehearsal rather than during cutover.

  5. Count everything, per content type

    Source against destination, with every difference either resolved or accounted for. On a bespoke import there is no supported baseline to appeal to, so the counts are the entire evidence base for completeness.

  6. Cut over once and stay for the settling period

    A rehearsed window with a rollback and a defined trigger, then support through the weeks in which members encounter the parts testing did not reach. On an unusual source those are more likely than on a supported one.

Deliverables

What an engagement produces

Documentation is a deliverable, not an afterthought. On most of these engagements a large part of the value is a defect report precise enough for another team to act on.

Discovery

  • Source data model established from the application rather than its documentation
  • Content inventory including anything outside the database
  • Derived values identified, with how each is computed
  • Relationships that must be preserved, enumerated
  • Written mapping with an outcome for every construct
  • Explicit list of content that cannot be carried, with the reason

Importer

  • Conversion built for this schema specifically
  • Repeatable, re-runnable against fresh copies
  • Derived state reconstructed
  • Relationships preserved across the conversion
  • Attachments and media captured from wherever they live
  • Redirect rules for the URL structure

Verification

  • Reconciliation counts per content type, with variances explained
  • Rehearsals against copies of the production data
  • Rehearsed cutover with a tested rollback
  • Post-migration verification with real data and real member behaviour
  • Support through the initial period of live use
Under the hood

Architecture and technology

What makes a bespoke importer different

  • No documented mapping exists, so every decision is made during the work
  • The real schema is whatever the code does, not what it is called
  • Derived state may exist only as computed output with no stored form
  • Content may live in files, blobs or generated artefacts
  • There is no supported baseline to compare output against
  • Rehearsal is the only way to find the parts that do not convert

What the work needs from your side

  • Access to the source application and its data
  • Somebody who understands the community's history and can review the mapping
  • A destination environment to rehearse against
  • Willingness to rehearse repeatedly rather than cut over early
  • Agreement on what happens to content that cannot be carried
Adjacent problems

If this is not quite your problem

These overlap at the edges. Sending you to the right page is more useful than having you work it out.

Your source is a platform an importer already covers

Supported imports and the version positions that determine them.

Forum migration to XenForo

Your source is vBulletin or Invision

Sources with their own importer coverage position.

vBulletin to XenForo migration

The community is large enough that scale is the problem

Volume, timing and constraint management rather than schema conversion.

Large forum migration

Search visibility is the main risk

Redirects, canonicals and indexation recovery.

Website migrations
Questions

Frequently asked

How do you decide what the source data model actually is?

By reading the application rather than its documentation. On a bespoke or heavily modified platform, the documentation describes an intention and the code describes what happened. That reading is the first phase of work and it is why we do not scope an importer before it — the scope is a function of what the source turns out to contain.

Can everything be carried over?

Everything that maps, and there is always something that does not. The usual candidates are derived state with no stored form, content in a structure the destination has no equivalent for, and material in files nobody enumerated. Each gets an explicit outcome in the mapping document: converted, reconstructed, approximated with the limits stated, or excluded with the consequence made clear to you before the work starts.

The forum has been running for fifteen years. Does that change anything?

It changes the volume rather than the nature of the work, and it raises the value of rehearsal. Long histories accumulate edge cases — imported content from an earlier platform, accounts with unusual states, threads with structures the current software would not allow you to create. Those appear during rehearsal on real data, which is the argument for running it more than once.

How long does a custom importer take?

It follows what the source contains, and that is established by the discovery phase rather than estimated in advance. A small bespoke forum with clean data is a very different project from a fifteen-year-old installation that has itself been migrated once before. We will give a sequence and an estimate after the discovery, and we will not give one before it.

Do you have examples of custom importers you have built?

Not in a form we can publish, and we would rather say so than show work that is not comparable. Our published community work is migration and platform operation, and presenting it as bespoke importer development would mislead you about what is being bought. What we can do is describe the method precisely enough for you to judge it, and establish what your source actually contains — which is the part that determines whether this project is straightforward.

Bring us the problem you have not been able to fix

Describe what is happening rather than what you think the cause is. If we are not the right people for it, we will say so.