Legacy Catalog Service Deprecation
A redundant catalog service that four engineering teams maintained daily, with no owner and no roadmap slot. Retired by moving its consumers onto their real dependencies first, then deleting the service and its infrastructure outright.
Context
A Kotlin/Spring catalog service sat in the middle of the commerce stack, duplicating capability that cart-checkout and Commercetools already provided directly. Four engineering teams touched it daily, because it stood between them and the systems they needed to reach.
Problem
The service was widely recognized as redundant, but nobody could justify the quarter to remove it. Deleting a service ships no feature and moves no metric, and getting it wrong takes down the systems that depend on it. So it survived, accumulating maintenance cost and acting as a shared point of failure across four teams.
What I did
- Made the case for removal on operational cost and blast radius instead of code cleanliness, which is what got it prioritized.
- Mapped every consumer of the service across the teams and applications that depended on it, before changing anything.
- Refactored the frontend to call cart-checkout and Commercetools directly, with 3 engineers, removing the service from that path instead of reimplementing it.
- Deleted the service once nothing depended on it: the code, the deployment, and the supporting infrastructure.
Why it survived
The service was not a feature, so it never won a roadmap slot, and it was load-bearing, so nobody wanted to be the person who touched it. Those two facts kept it alive for years.
Inventory
Every consuming team and application had to be identified before anything moved. The way this kind of project fails is discovering a dependency after removing the thing it depended on.
The inventory also turned an unbounded project into a finite list. "Retire the catalog service" cannot be estimated or staffed. A counted sequence of consumer migrations can be.
Migrate the consumers, then delete the service
Nothing was removed while anything still depended on it. Consumers moved off the service first, which left deletion as the final step, with no traffic behind it.
- Enumerate every consumer across the dependent teams and applications.
- Refactor the frontend to call cart-checkout and Commercetools directly, with 3 engineers, removing the service from that path instead of reimplementing it.
- Confirm nothing still depends on the service before touching it.
- Delete the service and its infrastructure together, code and deployment, so no orphaned infra outlives the code.
A retired service whose deployment, alerts, and dashboards remain still pages someone, still appears in reviews, and still has to be reasoned about during an incident. Deleting the infrastructure with the code is what ends that.
Result
- An entire Kotlin/Spring service and its infrastructure deleted, including the deployment and its alerts.
- Four engineering teams stopped maintaining the redundant service after its consumers were migrated off it; the frontend now calls cart-checkout and Commercetools directly.
- A shared point of failure removed from between four teams and the systems they depended on.
- The migration path (enumerate consumers, move them off, then delete) reusable for the next piece of unowned infrastructure.
Tech
- Kotlin
- Spring
- GraphQL
- Commercetools
- TypeScript
- React
- Terraform
- Argo CD