
The Java monolith that keeps your business running and the cloud native architecture you need to grow are two different systems. The first one works. It has worked for years. But it slows every release, scales by buying bigger machines, and nobody on the team wants to be the one who touches the billing module on a Friday. The distance between that monolith and a cloud native platform is not set by the technology, which is available and well documented. It is set by the sequence you follow and by who executes it without stopping the business along the way.
Modernising a Java monolith to cloud native means incrementally transforming a tightly coupled application into a system deployed, scaled and operated in the cloud, without rewriting it from scratch. The hard decision in a legacy system is rarely technical. It is admitting that the full rewrite you sketched on the whiteboard will not happen this year, and designing instead a path that delivers value every few weeks while the monolith stays alive.
TL;DR. A Java to cloud native migration is not a rewrite: it is an incremental transformation of the monolith into an architecture operated in the cloud. You run it with the strangler pattern, extracting capabilities one by one behind a facade, not with a big-bang that freezes the business for months. Not every part of the monolith becomes a microservice: you extract what has a clear reason to change or scale and leave the rest. Cloud native is an operating contract, twelve factors, containers, continuous deployment and observability, not moving the virtual machine to the cloud. The bottleneck is rarely the technology. It is who executes and documents that last mile.
Modernising a Java monolith is not a rewrite from scratch
The full rewrite is the most expensive trap in this field. It sounds clean on the whiteboard. You start a new project, free of debt, with the stack you always wanted, and in eighteen months you switch off the monolith. It almost never ends that way. While the new team chases feature parity, the monolith keeps growing because the business does not stop, and the switch-off date drifts a quarter further every quarter. Martin Fowler sums it up in an uncomfortable idea: almost every large system that works started as a monolith that worked, and it pays to treat the monolith with respect before you take it apart.
The alternative that does survive contact with production is the strangler pattern. Instead of replacing the system in one go, you surround it. You put a facade in front of the monolith, extract one specific capability into a new cloud native service, route that capability's traffic through the facade, and repeat. The monolith empties out little by little, like a tree the strangler fig gradually covers, until what remains is residual or disappears. The canonical description of the strangler pattern is years old and is still the safest way to modernise a core that cannot be stopped. Every extraction is reversible. Every step delivers value. The business never freezes.
The phases of a Java to cloud native migration
An orderly migration moves through phases, and each phase forces a decision that, if you skip it, is paid for in production with a different failure. Not every capability passes through every phase. Part of the monolith only needs to move. Another part demands deep Java code refactoring to become genuinely cloud native. The expensive mistake is applying the same level of effort to all of it.
| Phase | The decision you make | Risk if you ignore it |
|---|---|---|
| Assessment and domain mapping | Which capabilities have their own reason to change or scale and which do not | Extracting by fashion and ending up with a distributed monolith, worse than the original |
| Containerising the monolith | Packaging the Java application as-is into containers and externalising configuration | Dragging application-server dependencies along and blocking automated deployment |
| Capability extraction (strangler) | Which service goes first, behind which facade and with which own data | Services that share the same database and stay coupled in practice |
| Continuous deployment and platform | Integration pipeline, orchestration and self-service for teams | Modern microservices deployed by hand, with the slowness of the monolith |
| Observability and operation | Traces, metrics and logs end to end from the first extraction | A distributed system that fails with no one knowing in which service or why |
The phase most often neglected is the first one. Skipping the domain map and slicing by intuition produces the worst possible outcome, a distributed monolith: the same tangle as before, now spread across services that call each other over the network and share a database. You get the complexity of microservices with none of their benefits. Before extracting anything it pays to understand microservices-based architecture properly and, above all, when not to apply it.
Not every part of the monolith should become a microservice
The reflex to slice everything is the most common mistake in these migrations. A microservice carries a fixed cost that never goes away: its own deployment, its own database, its own observability, its network contract, its team keeping it alive at three in the morning. That cost is only justified when a capability has a real reason to live apart. It changes at a different pace from the rest. It scales differently. A different team owns it. If none of those three conditions holds, extracting it adds complexity and returns nothing.
The honest criterion is bounded contexts from domain-driven design. A capability with its own business language, its own rules and its own data is a microservice candidate. The stable, heavily coupled core of the monolith, the part that barely changes, should almost always stay where it is. Modernising is not splitting, it is deciding what deserves to come out. The underlying criterion, when each architecture fits, is the question of microservices versus monolith. A well containerised monolith deployed continuously is already, for many organisations, a sufficient cloud native architecture.
Cloud native is an operating contract, not an infrastructure destination
Moving the virtual machine to the cloud is not being cloud native. That is a change of postal address. Cloud native is a way of building and operating applications that exploit the cloud model: decoupled services, containers, automation and resilience by design. The CNCF cloud native definition frames it as scalable, resilient systems operated with frequent, low-impact deployment. The question is not where the application runs. It is how it is built, deployed and recovered.
For a Java application, that operating contract comes down to a handful of properties. Configuration lives outside the code, in the environment, not in a file packaged inside the artifact. Processes hold no state, so they can be started and killed without losing anything. Deployment is automated and repeatable, not a twelve-step manual on a wiki. Logs are treated as an event stream, not as files someone opens over SSH. That discipline has been codified for years in the twelve-factor methodology, and it is still the most useful checklist for telling whether a Java application is ready for the cloud or merely hosted in it.
Signs a Java monolith is not yet cloud native
- Configuration (credentials, URLs, parameters) travels inside the artifact and changes between environments by editing the package.
- There is state in memory or on local disk that is lost if the process restarts, which prevents horizontal scaling.
- Deployment depends on manual steps on a specific application server and cannot be reproduced from scratch.
- There are no end-to-end traces or metrics: when something fails, diagnosis starts by reading logs by hand.
Source: the twelve-factor methodology (12factor.net) and the CNCF cloud native definition
A Java to cloud native migration fails on execution, not technology
This is the real bottleneck. Containers, orchestrators, deployment pipelines and modern Java frameworks are available and well documented. Google Cloud and Red Hat publish detailed modernisation guides anyone can read. The question is not whether the technology exists. It is whether your team has, at the same time, the hands to keep the monolith running in production and the specific skills to design the extraction, build the platform and govern the data during the transition.
That gap, between a cloud native plan on the whiteboard and a system actually in production, is rarely about the availability of tools. It is about execution and the skills to take what works in theory or in a trial all the way to production. The same pattern repeats in any ambitious modernisation: organisations sketch a cloud native architecture, then fail to deliver because the internal team is entirely consumed by the daily operation of the legacy monolith.
The sensible answer is not to hire a permanent team for an effort with a clear peak and an end, nor to buy generic development hours from a traditional consultancy that pulls the knowledge away from your team exactly when you need it most. It is to compose a blended team: your engineers, who know the domain and the monolith better than anyone, plus fully vetted IT contractors with proven Java modernisation and platform skills who have taken these migrations to production before. Structured as Statement of Work (SoW) engagements that sit Outside IR35, this supports IR35 compliance for UK businesses while keeping the relationship a genuine B2B one. The architectural knowledge stays in-house, exactly what you need when migrating your core. Shakers works as the hiring infrastructure for that last mile: skills verified and validated per engagement, not self-declared profiles. You can compose a team to design and execute the migration, rather than discovering the skills gap halfway through the rollout.
Frequently asked questions about migrating Java to cloud native
- Rewrite the monolith from scratch or migrate incrementally?
-
Incrementally, almost always. A full rewrite forces you to chase feature parity with a system that keeps growing, and the switch-off date drifts further every quarter. The strangler pattern extracts capabilities one by one behind a facade, delivers value at each step and keeps every change reversible. The business never freezes while the transition lasts.
- How long does a Java monolith to cloud native migration take?
-
It depends on how coupled the monolith is and on the availability of skills, not on the stack. Containerising and deploying continuously is measured in weeks. Emptying the monolith through successive extractions is measured in months or quarters, depending on how many capabilities have a real reason to come out. The factor that stretches the timeline most is the lack of hands to keep production running and migrate at the same time.
- Do you have to move to microservices to be cloud native?
-
No. Cloud native is an operating contract: externalised configuration, stateless processes, automated deployment and observability. A well containerised monolith deployed continuously already meets that contract. Microservices are only justified when a capability changes, scales or is owned by a different team from the rest. Slicing without that reason produces a distributed monolith, worse than the original.
- What are the risks of migrating a monolith in production?
-
The biggest is the distributed monolith: separate services that share a database and stay coupled in practice. Next come the manual deployment of modern services, which drags the slowness of the monolith along, and the lack of observability, which turns every failure into a blind investigation. The strangler pattern bounds the risk because each extraction is small and reversible.
- What roles do you need to modernise a Java monolith?
-
Java backend engineering that understands the domain, architecture to decide what gets extracted, platform engineering for containers and continuous deployment, and operations for observability. An organisation rarely has that full set free at once. A blended team that adds those skills to your internal team covers the peak without permanently inflating headcount.
Modernising a Java monolith to cloud native is not bought with a list of tools or with a flashy rewrite project. It is executed with people who know how to empty the monolith without stopping the business, decide what deserves to come out, and leave the platform and the documentation behind so your team can sustain it afterwards. That is the transition that matters: moving from static roles to verified skills, and securing the capability to close the last mile.