✦ Financial Services · Enterprise Software Modernisation
Modernising a Financial Services Platform Without a Big-Bang Rewrite
How we are migrating a business-critical Java monolith to Go microservices while preserving existing integrations, transaction integrity and operational continuity.
- ~422API endpoints assessedDocumented design
- 24 wksthree-phase programmeIn delivery
- ~850contract-parity scenarios plannedTeam-reported
- Programme
- ~24 weeks, 3 phases
- Team
- 6.25 FTE
- Pattern
- Strangler Fig
→ or swipe to begin
✦ The challenge
Where it started
Modernising a financial platform is not simply about replacing old technology. Existing integrations, transaction flows and business rules must continue to work throughout the transition.
Our client operated a complex Java-based banking platform, with business logic and external dependencies spread across multiple modules.
The challenge was to modernise the platform without requiring a single, high-risk replacement of its existing backend. In financial services, preserving transaction consistency, API contracts and integration behaviour is just as important as improving the underlying architecture.
- 22Application modules
- ~422API endpoints
- 28External integrations
- ~112,000Lines of production code
✦ Our approach
How we tackled it
We designed a phased migration using the Strangler Fig pattern: the legacy system and new Go services run side by side while functionality moves over domain by domain. Traffic is routed progressively through a gateway, with rollback available at every step.
- 01
Discovery & Foundation
4 weeksMap existing endpoints, integrations and business rules. Define service boundaries, architectural decisions and automated testing procedures.
- 02
Incremental Migration
14 weeksImplement Go services by business domain, validate behaviour against the existing platform and progressively redirect traffic.
- 03
Cutover & Ownership
6 weeksComplete the planned migration, verify data consistency, transfer ownership to the new services and retire legacy components.
Each stage has measurable acceptance criteria and a rollback strategy. Using our AI-assisted engineering workflow, the initial reverse-engineering assessment and technical proposal took about two calendar days; detailed validation still happens during implementation.
✦ Architecture
Modernisation without disruption
Existing API consumers keep one entry point; the gateway splits traffic between legacy and new services.
Drag to pan · Ctrl/⌘ + scroll or pinch to zoom · click a block to trace its connections
The Test Oracle: capture real behaviour, replay it against new services, block any difference.
Drag to pan · Ctrl/⌘ + scroll or pinch to zoom · click a block to trace its connections
✦ Technology
The stack, and why
- GoIndependent, testable services with clean architecture boundaries.
- JavaThe legacy monolith being strangled, module by module.
AWS Aurora PostgreSQLDomain-owned databases with transaction consistency.
- PostgreSQLThe existing relational store, kept until each domain moves.
- AWS SQSReliable, idempotent asynchronous processing with Outbox / Inbox.
- AWS ECSIndependent deployment of each service.
- TerraformRepeatable infrastructure provisioning.
- WWireMockCaptures and sanitises real downstream interactions.
KarateReplays interactions against Go services and checks contracts.
- GitHub ActionsAutomated quality gates on every pull request.
- New RelicProduction observability across old and new.
Hover or tap a technology to see why it is there.
All key engineering decisions
| Technology / pattern | Why it matters |
|---|---|
| Go + Clean Architecture | Independent, testable services with clear business boundaries |
| Strangler Fig + API Gateway | Gradual migration while the legacy platform remains operational |
| AWS Aurora PostgreSQL | Domain-specific data ownership and transaction consistency |
| AWS SQS + Outbox/Inbox | Reliable, idempotent asynchronous processing across services |
| WireMock + Karate | Automated validation of API contracts and expected behaviour |
| AWS ECS + Terraform | Repeatable infrastructure provisioning and independent deployments |
| GitHub Actions + New Relic | Automated quality checks, controlled releases and production observability |
✦ The key differentiator
Verify behaviour before migrating traffic
Legacy systems often contain undocumented behaviours that traditional unit tests fail to capture. Rewriting the application without understanding them introduces significant regression risk.
Our Test Oracle turns real interactions into repeatable automated tests. Changes that fail contract validation are blocked before production promotion.
- CaptureReal downstream interactions are recorded with WireMock and sanitised.
- ReplayKarate replays them against the new Go services.
- CompareResponses are checked against the expected contract.
- ValidateAny unexpected difference fails the pipeline before promotion.
The team reports meeting its planned coverage target of at least one success and one error scenario per mapped endpoint, about 850 contract-parity scenarios on the assessed API scope.
✦ Evidence
The numbers
Planned programme: 24 weeks across three phases.
Design target per migration step. Dual-read routes reads only; rollback is available through the gateway.
Estimates by endpoint group (sum 353). The assessed total is about 422, within a 353–422 range.
✦ Results & impact
What we can say, and what we can't yet
The technical proposal was approved and the project is in active implementation. The solution is designed to provide four practical improvements.
- Reduced migration riskServices replaced incrementally with controlled traffic migration and rollback.
- More predictable deliveryDefined milestones, automated testing and measurable acceptance criteria.
- Architectural flexibilityIndependently deployable services with clearer responsibilities and less coupling.
- Lower operational complexityOpportunities to simplify infrastructure and reduce maintenance overhead.
| Metric | Result | Evidence |
|---|---|---|
| Minimum automated test coverage | 95% CI gate | Delivered |
| Contract verification | Automated replay on pull requests | Delivered |
| Story quality assessment | 7 validation checks | Delivered |
| Production deployment | Controlled manual approval | Delivered |
Infrastructure cost savings, API latency improvements and productivity gains remain subject to measurement against the completed target architecture. They are not presented as achieved results. Benchmarks from our earlier production migration (a 11-second contract-parity suite, a 3-minute pull-request pipeline) are not outcomes of this project.
✦ What this project demonstrates
Principles that travel
This engagement turns a complex legacy environment into a structured, executable modernisation programme. The principles apply beyond financial services: ERP integrations, middleware replacement, payment platforms and other business-critical systems.
- Assess business-critical systems and map their integration dependencies
- Balance modernisation with operational continuity
- Introduce automated contract verification into complex environments
- Combine AI-assisted engineering with measurable quality and human accountability
- Coordinate a multidisciplinary team around incremental delivery
✦ Your turn
Your monolith has secrets it has never told anyone.
Let us go and find them together, before a migration finds them for you. Bring us the system nobody dares to touch and we will tell you how we would approach it.
Next case studyA legacy batch integration replaced by an event-driven architecture and a canonical employee layer→