← Back to resources

Playbook · for IT and support leads running a migration

The ticket history import checklist

8 min read · Last reviewed August 2026

Key takeaways

  • Export threads, not just ticket rows — a ticket without its conversation is a spreadsheet row, not history.
  • Decide the live import window early: import what people still act on, archive the rest read-only.
  • Map identities before importing anything, or you will own thousands of tickets belonging to "imported user".
  • Verify by counts per status and per month, then read twenty tickets end to end. Nothing else catches a truncated thread.

Reading is free — the full guide is right below. Want it as a PDF to share with your team?

Whichever tool you are leaving, the import is the same job. And it is where migrations go wrong — not in a dramatic way, but in a set of small, boring, entirely predictable ways that surface three weeks later when someone opens an old ticket and finds the conversation stops after the second message.

This is the mechanical checklist: what to pull out, what to bring across, how to keep tickets attached to the people who filed them, how to prove it worked, and how to move intake without asking the whole company to change habit.

What to export

Export more than you intend to import. Deciding later what to drop is free; going back for something after the source system is gone is not.

  • Ticket records: original id, subject, status, priority, category or queue, created, updated and closed timestamps, requester, assignee, and tags.
  • The full conversation thread per ticket, with author, timestamp, and the public-versus-internal distinction preserved on every entry.
  • Custom field definitions exported alongside their values, so stored codes remain interpretable.
  • User records for requesters and agents alike, with email addresses — this is the join key for identity mapping.
  • Knowledge base articles, canned responses, and macro text, as plain text.
  • An attachment inventory — ticket id, filename, size, content type — even if you decide not to move the files themselves.

Carry the original ticket id into a field on the new record. Every postmortem, change record, wiki page, Slack thread, and vendor email in your company references tickets by number, and a migration that silently renumbers everything breaks years of cross-references in a way nobody notices until they need one. If the new tool also numbers tickets, keep both and make the legacy number searchable.

Then prove the export is complete before you build anything on it. Paginated APIs cap out, exports time out at large row counts, and a job that quietly stopped at ten thousand records looks exactly like a job that finished. Compare your row counts against the source system’s own reporting, per year and per status, and run the export twice at different times to diff the results. An incomplete export discovered on day one is an inconvenience; discovered after cutover it is a data-loss incident.

The attachments decision

Attachments are most of the bytes and a small share of the value. Screenshots of error dialogues, logs, and exported spreadsheets dominate the volume, and migrating binaries multiplies the runtime, the cost, and the number of ways the job can fail halfway through. Have the argument early, because it changes the shape of everything else.

The default that works for most teams: migrate binaries only for tickets still open at cutover, migrate the inventory for everything else so the thread reads "3 attachments, held in the archive" with a link, and keep the files in the read-only archive. Requesters almost never reopen a two-year-old ticket to look at a screenshot; when they do, the archive answers it.

Two exceptions. Regulated records with a retention obligation must remain retrievable for the retention period — but that is a retention requirement, which an archive satisfies as well as a live import, so check whether it genuinely demands migration. And attachments carry the highest concentration of personal data in the whole export: payslip screenshots, ID documents, exported employee lists. Whatever you decide, that content needs the same review and the same access controls in its new home as it had in the old one, and any staging bucket you use in between needs a deletion date.

Import window versus read-only archive

The decision rule is simple to state: import what people still act on, plus enough recent history for the new system to learn the shape of your queue. That is usually all open tickets plus six to twelve months of closed ones. Everything older goes to a read-only archive — the old system kept alive with logins restricted, or a searchable export sitting somewhere queryable.

Two things should push you wider. A genuinely seasonal queue needs at least thirteen months, because year-end, open enrolment, the academic intake, or the audit cycle only appear once per year and a twelve-month window can miss the peak entirely. And a low-volume queue may simply not contain enough tickets in a year to be useful, in which case take what there is.

One thing should push you narrower, and it is the point most teams miss: old history is not neutral. If you migrated your identity provider two years ago, replaced the VPN, or moved off an old finance system, tickets from before that change describe processes that no longer exist. To a human reading the archive that is obviously historical. To a retrieval system grounding an answer, it is confident instruction to follow a procedure you retired. When a platform change is large enough, the tickets that predate it belong in the archive rather than in the live corpus, regardless of how recent they are.

Identity mapping

This is the step teams underestimate, and it is the one that visibly ruins an import. Tickets attach to people; if the people do not resolve, you get a queue of history owned by nobody, and history you cannot attribute is history nobody trusts. Build the mapping table as an explicit artifact before the import runs, not as a fallback rule inside the script.

Map on email address rather than display name — names collide, change, and get typed inconsistently, while addresses are the key both systems actually used. Then work through the cases that will not match cleanly. People who have left the company should be imported as inactive users with their real names, not collapsed into a shared placeholder; the value of an old ticket is largely in knowing who handled it and who asked. People whose address changed through marriage, rebranding, or an acquisition domain migration need explicit aliases. Shared mailboxes and distribution lists appear as requesters and need a decision about whether they become users or a team. Agents appear as both requester and assignee, sometimes on the same ticket. And system or automation accounts should map to something clearly labelled as automated rather than to a human.

Before importing, count how many distinct source identities fail to match, and treat that number as a gate. If more than a small fraction are unmatched, stop and fix the mapping table — the alternative is fixing it afterwards, ticket by ticket, which nobody ever finishes.

Verification

Verify in two passes, because the two passes catch different failures. First, counts: total tickets, then by status, then bucketed by month of creation. The monthly buckets are the important part — a single total can match while an entire quarter is missing if a second job double-counted somewhere else, and a truncated export shows up immediately as a cliff on a month boundary.

Second, read twenty tickets end to end, chosen deliberately rather than at random. Pick the oldest ticket in the import, the one with the longest thread, one containing non-English characters or emoji, one with a large attachment, one that was merged or linked to another, one filed by someone who has left, one with several custom field values populated, and one closed by an automation. Read the whole thing, thread included, against the source.

100%
ticket counts matched by status and by month
20
tickets read end to end, threads included
0
tickets owned by a placeholder user
1
announced end date for the parallel run
An acceptance checklist, not a benchmark — the four numbers to agree on before anyone calls the migration done.

That spot-check is looking for five specific things, all of which are common. Truncated threads, where the importer took the first few entries per ticket and stopped. Lost internal-versus-public distinction, where an agent’s private note becomes visible to the requester — treat that one as an incident rather than a bug, because it will eventually be a note about a person. Timestamps collapsed to the import date, which destroys every trend report and any sense of chronology in the thread. HTML rendered as escaped tags, or conversely raw HTML rendered as markup that reformats the whole ticket. And encoding damage in names and quoted strings, which is easiest to spot on non-English names.

Running two helpdesks in parallel

Every migration runs both systems for a while, and the version that works is deliberate about it. New tickets go to the new tool from day one. Open tickets drain where they are — never migrate a ticket mid-conversation, because the requester loses the thread and the agent loses the context, and the handful that are still open at the end of the window can be closed and refiled or simply finished late. One team works both queues, with the old one checked on a schedule rather than watched, so attention is not permanently split.

Report volume as a sum across both systems during this period. If you report on the new tool alone, the first week looks like a collapse in demand and someone will draw the wrong conclusion from it in a leadership meeting.

Set and announce an end date before you start. Two weeks is enough for most internal queues. Without a date the parallel run does not end — it becomes the permanent state, with two intake paths, two sets of habits, and agents who keep the old tool open because a few requesters still use it. That is the single most common failure of this phase and it is entirely self-inflicted.

Redirect intake at the source, not the requester

The strongest opinion in this playbook: requesters do not change their behaviour because you asked them to. They change when the old path stops working. Every migration that depends on training the company to use a new address or a new URL runs three intake paths for years afterwards.

So change the source rather than the audience. Repoint the mail forward on the support address so the existing address delivers into the new tool — do not replace it with an auto-reply asking people to write to a different one. Swap the target of the existing Slack workflow or emoji shortcut in place, keeping the same trigger the team already uses. Point the existing portal URL at the new form rather than publishing a new URL, and keep the redirect alive for at least a quarter. Then update the places the old link is written down: the intranet tile, the wiki page, the onboarding checklist, the email signature block, the laminated sign by the printer. Someone has to walk around and find those, and it is worth the afternoon.

The single announcement that does earn its place is a pinned message in the channels where people already file: new requests here as before, open requests finish where they started. If intake genuinely moved at the source, most requesters will never notice the tool changed, which is exactly the outcome you want.

Where FlowTux fits into this is mostly the redirect step: intake arrives from Slack, Teams, email, and WhatsApp into one queue, so in most cases the migration is a forwarding change rather than a new destination anyone has to learn. Imported history starts paying immediately, because triage is grounded in resolved tickets and the linked codebase, and semantic deduplication collapses the repeat asks that a fresh queue would otherwise treat as unrelated. Per-category suggest, approve, and autonomous modes let you keep everything human during the parallel weeks and promote categories afterwards, with allow-listed autonomous resolution and a full audit trail on the ticket timeline. Pricing is flat from $49 a month rather than per agent, and data can be held in the EU, US, or India — a question worth settling before the import rather than after.

Frequently asked

How much ticket history should we migrate?

Import all open tickets plus a recent window of closed ones, commonly six to twelve months, and keep the rest as a read-only archive. Go wider for seasonal queues, where a full year plus a month is the minimum to capture the peak. Go narrower where a major platform change makes older tickets describe processes that no longer exist — to a retrieval system those are not merely old, they are confidently wrong instructions.

Should we migrate ticket attachments?

Usually not in bulk. Attachments are most of the bytes and little of the value, and migrating binaries multiplies runtime, cost, and failure modes. Move the files for tickets still open at cutover, move the inventory for everything else so threads show what existed and where it lives, and keep the binaries in the archive. Attachments also hold the densest personal data in the export, so they need the same access controls in their new home.

How do we avoid orphaned tickets after an import?

Build an explicit identity mapping table before the import, keyed on email address rather than display name. Import departed employees as inactive users under their real names instead of collapsing them into a placeholder, add aliases for changed addresses and acquisition domains, and decide up front what happens to shared mailboxes and automation accounts. Count the unmatched identities before you run the import and treat a high number as a stop condition.

How long should we run two helpdesks in parallel?

About two weeks for most internal queues, with the end date announced before you start. New tickets go to the new tool from day one and open tickets drain where they are. The failure mode is not a parallel run that is too short — it is one with no end date, which quietly becomes permanent, leaving two intake paths and two sets of habits indefinitely.

Ready to stop
fighting fires?

14-day free trial. Every team up and running the same day.
No credit card. No sales call. No implementation consultant.

No credit card. No sales call. No implementation partner. No nonsense.