From Months to Days: A Self-Service Migration Pipeline Between Two SaaS Products
How a practice-management software provider serving the elective medical industry rebuilt customer migration between two of its products — replacing months of engineering-led work with a self-serve, AWS-native pipeline that the service team runs in days, with two-hour turnarounds in sight.
$ cat case-study/details.yaml
The Problem.
The client operates two practice-management products serving overlapping customer segments. The legacy product was built around the workflow of cosmetic and plastic surgery clinics. The modern product is purpose-built for med spas. A meaningful share of the legacy product's customer base is structurally a better fit for the modern product — and moving them onto the right product was both a customer success story and a retention strategy.
The problem was getting them there. The two products were architected for different operating models, and the database structures reflected that. The legacy product's data sits in MySQL, sharded per customer, producing thousands of shards across the customer base. The modern product uses a non-sharded model with tenant segregation expressed through a TenantId column. The shapes of the data, the schemas, and the assumptions baked into them — none of them lined up.
The modern product shipped with an importer tool designed to ingest standardized CSV files into its database. But the importer is a Windows-native application that has to be installed on a service team member's machine, and it expects data already shaped to the importer's exact format. The bridge from a per-customer legacy shard to the importer's CSV format didn't exist. Building it for one customer was a manual, multi-week engineering exercise. Doing it across the customer base, repeatably, with the service team rather than engineering doing the work, was a different problem entirely.
There was also the matter of the customer's images and files — radiology images, before/after photos, documents — which had to move with the structured data, with their metadata intact, into the new tenant's S3 storage in the modern product.
The objective for the engagement: build a tool that compresses migration from months to days (with a two-hour ceiling in sight), runs as self-service for the service team, scales across the customer base, and is extensible to ingest data from other EMR systems in the future.
What we built.
Quest1 designed and built an end-to-end, AWS-native migration platform that takes a customer all the way through from the legacy product to a fully populated tenant on the modern product, with a self-service UI for the service team and structured orchestration underneath.
The networking and platform layer — VPC, subnets, NAT gateway, S3 endpoints, SQS for buffer where stages decouple — was structured to keep the data path private and the failure modes recoverable, so a stalled migration could be resumed rather than restarted from zero.
The Impact.
The platform compressed migration from a months-long engineering exercise into a service team task that takes days, with a two-hour ceiling in sight as the next round of improvements lands. The cost structure of customer migration changed from "an engineering project per customer" to "a service team workflow," and that change held up at volume.
In the first month after deployment, more than ten customers were migrated through the platform — comfortably faster than the prior model would have permitted, and a meaningful early signal on the platform's repeatability.
- A self-service migration tool, owned and operated by the service team, with the engineering team out of the per-customer critical path.
- A configurable, orchestrated pipeline in Step Functions whose stage definitions and per-customer specifics live in DynamoDB rather than code — extensible to additional data shapes without re-architecting.
- A SparkSQL-based transform library that's accessible to the data engineering team for extension rather than ownership-locked to one author.
- A pattern that extends beyond legacy-to-modern migration to ingest data from external EMR systems — the same orchestration carries other source-system shapes through with new transforms.
- An AWS-native architecture with TCO modeled and consolidated across services rather than fragmented across third-party tools.
