Decommissioning is the milestone
We replaced the helpdesk our support team works in. Not a background service, not a batch job — the application several dozen people have open all day, every day, and through which customers reach us.
The interesting constraint is that support cannot pause. There is no maintenance window for "customers stop having problems for a weekend". Whatever you do has to happen around people who are mid-conversation with somebody annoyed.
Your platform is a helpdesk user too
The obvious half of a helpdesk migration is the helpdesk: move the tickets, train the agents, redirect the inbound email. That part is largely somebody else's job and the vendor has tooling for it.
The half that lands on engineering is that your own systems are prolific ticket creators. Ours raise tickets when a customer migration needs checking, when an identity verification completes, when an automated process needs a human, when something fails in a way that requires follow-up. Every one of those paths is an integration with the old helpdesk, and every one has to be rewritten.
So the work is not "move to the new tool". It is "find every place in a decade of code that creates, updates or references a ticket, and re-express it against a different API with different concepts" — while the old paths keep working, because support is using them today.
Tickets are created by somebody
The detail that consumed the most time was identity, and it is the one I would warn anyone about.
When a system raises a ticket it has to raise it as someone. That submitter determines who gets replies, what the customer sees as the sender, which team it routes to, and whether it looks like a request from a customer or a note from a colleague. Get it wrong and a customer receives an email apparently from an automated process, or an internal note becomes a customer-visible reply.
That means maintaining a mapping between your users and their agents — and letting people set their own identifier, with administrators able to set it for others, because nobody is going to do it for fifty staff by hand. It is unglamorous user-management work sitting squarely in the critical path of a migration that looks, from the outside, like a procurement decision.
Small vocabulary differences cost real time
Two systems that both have tickets do not have the same tickets.
One example I like: tickets we created had to land as open rather than new. That is a one-word difference and it matters, because the two states mean different things in the team's workflow — new is unclaimed and waiting for triage, open is live work. Creating everything as new quietly dumped automated tickets into the triage queue, which is exactly where they should not be.
Similarly: forms determine which fields a ticket carries, tags drive automation and reporting, groups determine routing. None of that maps across from the old system, all of it has to be decided rather than translated, and the people who know the right answers are the support team, not you.
Several brands, one platform
A white-label platform makes this harder in a specific way: there is not one helpdesk relationship, there are several, and a ticket has to be raised into the right one with the right branding and the right domain. Configuration that would be a constant in a single-brand product becomes a per-brand lookup in every integration point.
This is the recurring tax of white-labelling. Nothing about it is conceptually hard; it just means every "put the value in config" decision is instead "put the value in config, per brand, with a sensible default and a way to see which brands have been set up".
Removing the old one is the actual goal
The change I would point at as the milestone is not the one that added the new integration. It is the one that removed the old system completely — and, in the same change, added the canned-response support that had been the last thing keeping it alive.
That pairing is the whole lesson. There is always a final feature gap that stops you finishing, and it is usually small and unglamorous — here, the stock replies agents use fifty times a day. It is tempting to leave both systems running and come back to it. Two systems running is the expensive state: double integration surface, tickets in two places, and an ambiguity about where the truth lives that leaks into every conversation.
Closing the gap is what lets you delete, and deleting is what makes the migration real. Until then you have added a system rather than replaced one.
The long tail is longer than you think
The bulk of the work happened over a few months. The commits did not stop there.
Over the following year and a half there were ticket subject fixes, tag adjustments, submitter corrections, routing changes, reminder wiring, and eventually a change to how we authenticate against the vendor's API — because they moved to a different scheme and the deadline was theirs, not ours.
That last one is worth internalising. Replacing a self-hosted system with a vendor's means accepting a permanent, low-level stream of work on their timetable. It is usually a good trade. It is not a saving, and treating the integration as finished is how you end up doing it urgently.
What I took from it
Internal tool migrations are harder than they look because the users are colleagues. They cannot stop working, they will tell you immediately and directly when something is wrong, and the things that matter to them are workflow details invisible from the code.
Find the last feature gap early. The thing blocking decommissioning is rarely architectural. It is a small habit the old system supported. Identify it at the start, because it determines when you can finish.
Automated actors need identities. Any system where your software acts on behalf of people needs an explicit model of which person, maintained by someone. It will not be inferrable and it will not be optional.
Replacing is not adding. A migration that leaves the old system running has not reduced anything — it has increased the number of places a thing can be, which is the cost you were trying to remove.
Also in this series
- The tool your colleagues live in — maintaining the portal a company runs on
- One person, several accounts — SSO when identity isn't one-to-one
- Hiding a button is not a permission — retrofitting granular access control
- Reports are a scheduling problem — building call reporting end to end
- A catalogue is a query — selling hardware and addons through partners