Symphony Apps Development logo — teal interlocking S monogram beside the studio wordmark
All writing

Migrating a client off a legacy database without downtime

A build note on moving a live booking system between databases while it kept taking bookings, and the dual-write period that made it boring.

Category
Case notes
Reading time
7 min
Published
17 Aug 2026
Topics
Case study, Engineering, Delivery

The client's booking system ran on a database that had been end-of-lifed by its vendor, on a schema that had accumulated a decade of undocumented triggers. It could not go offline for a migration weekend, because weekends were when it took the most bookings.

Why "just switch it over" was never an option

The obvious plan — build the new system, cut over one night, done — assumes you can freeze writes during the cutover. This system had customers actively booking around the clock across several time zones, and a frozen write window of even twenty minutes would have meant lost business the client could point to directly. The plan had to keep both databases genuinely live during the transition.

Dual writes, then dual reads, then one of each

  • Phase one — every write goes to the old database as before, and is also written to the new one, with a background job reconciling anything that drifts.
  • Phase two — reads move to the new database for an increasing share of traffic, with a fallback to the old one on any discrepancy, logged rather than silently swallowed.
  • Phase three — writes stop going to the old database once reads have run cleanly off the new one for a full billing cycle, so any monthly-only process gets exercised before the old system is retired.

The undocumented triggers were the real risk

The legacy database had triggers that recalculated a loyalty balance on certain writes, discovered only because the new system's numbers quietly diverged from the old one during phase one. Nobody at the client remembered these existed. Dual writes surfaced the discrepancy within days rather than after cutover, which is the entire argument for running the two systems in parallel rather than trusting a migration script and a prayer.

A migration that cannot be observed running in parallel is a migration you are trusting rather than verifying.

How long this actually took

Four months from first dual write to retiring the old database, considerably longer than a cutover weekend would have taken on paper. The client's booking system had zero unplanned downtime attributable to the migration in that period, which was the number that mattered to them far more than the calendar time.

What we would tell anyone about to do this

Budget for the reconciliation job to find something you didn't know about. It always does, and finding it during a quiet dual-write phase is a non-event; finding it after the old system is gone is an incident.

Tell us what you’re trying to ship

A first call is thirty minutes and costs nothing. Bring the problem, not a spec — working out what to build is the part we are good at.

Or email office@symphonyapps.ro. We reply within one business day, in English or Romanian.