A mid-size logistics company runs shipment tracking, dispatch and customer notifications on a monolith that is over a decade old. This blueprint shows how we replace it piece by piece, routing traffic to new services one capability at a time while the business keeps shipping.
Every release touches a single shared codebase, so small changes need long regression cycles and weekend deployments.
Carrier and customer integrations run as nightly batch jobs, so tracking data is hours out of date.
The database schema is shared by every module, and nobody is sure what breaks when a column changes.
The on-premises servers are near end of life, and peak season traffic regularly slows the whole system.
What the Solution Delivers
New capabilities released independently of the legacy monolith
Near-real-time shipment status from carrier events instead of nightly batches
Each retired module removed behind a routing switch that can be rolled back
Services that scale on their own during peak shipping periods
Architecture
Strangler-fig modernization architecture
The routing layer sends each request either to a new service or to the legacy monolith. Change data capture streams legacy database changes into Kafka, so new services stay in sync until each old module is retired.
The situation
Many logistics companies run their core operations on a system that was built well for its time: one application, one database, a set of nightly jobs that exchange files with carriers. Over the years, features pile up, the original authors move on, and the system becomes the thing everyone is afraid to touch. Customers now expect live tracking, partners expect APIs instead of file drops, and the hardware is due for replacement.
A full rewrite is tempting, but it usually means a year or more of parallel development with nothing in production, followed by a risky cutover. Teams in this situation need a way to modernize that delivers value early and can be stopped or redirected at any point.
Our approach
1. Map the domain before touching code
We start with a three-to-four-week assessment. We trace how shipments, stops, carriers and customers flow through the monolith, read the database schema, and measure which modules change most often and cause the most incidents. The output is a capability map and a migration order: which parts to extract first based on business value, risk and how tangled they are with the rest of the system.
2. Put a routing layer in front of everything
Before extracting anything, we place an API gateway in front of the monolith and route all traffic through it unchanged. This is the core of the strangler-fig pattern. Once the gateway is in place, moving a capability is a routing change per endpoint, and moving it back is the same change in reverse.
3. Stream changes out of the legacy database
New services need legacy data without writing their own nightly exports. We use change data capture with Debezium to publish inserts and updates from the legacy database into Kafka topics. New services build their own read models from those events, and the monolith does not need to be modified to feed them.
4. Extract one capability at a time
We usually start with shipment tracking, because it is read-heavy, customer-facing and benefits most from real-time carrier events. The new service consumes carrier status updates directly, owns its own PostgreSQL database, and is released behind the gateway for a small share of traffic first. Once its results match the legacy output, the old module is switched off. Notifications, rating and dispatch follow the same path.
5. Move to cloud hosting as services appear
New services run on Amazon EKS from day one, defined in Terraform with automated pipelines. The monolith can be rehosted to the cloud early to retire the ageing servers, or left on-premises until it is small enough to decommission. We plan that decision with the operations team based on hardware timelines and network links to warehouses.
How we deliver it
We work in extraction cycles of six to ten weeks, each ending with a capability in production and a legacy module retired or scheduled for retirement. Every cycle includes contract tests between the new service and the monolith, dashboards built on OpenTelemetry traces that follow a request across old and new code, and a documented rollback path. Your engineers pair with ours throughout, so they own the new services when we step back. Our IT consulting team leads the assessment and migration plan, and our cloud services team builds the hosting platform.
Is this relevant to you?
If your core system is too important to replace in one go and too slow to keep extending as it is, this approach is a good fit. It also suits teams that have already tried a rewrite and want a lower-risk path. Talk to us about where your monolith hurts most, and we will suggest where to start.
Building something similar?
We'll walk through your requirements and share how we'd approach architecture, timeline and team for your project.
We use essential technologies to run this site. With your OK, we also use cookieless analytics and Google Maps, which may set cookies. No ads, and we never sell your data. Cookie Policy
Privacy preferences
Choose which optional technologies we may use. Strictly necessary ones are always on because the site can’t work securely without them. Details are in our Cookie Policy.
Your browser sends a Global Privacy Control signal, so optional technologies are off by default.
Strictly necessary
Security and spam protection (Cloudflare, Google reCAPTCHA), form delivery, and remembering these choices.
Always on
Cloudflare Web Analytics counts page views without cookies or cross-site tracking.
Shows our office on Google Maps. Google may set cookies and receive your IP address.