Spring Boot microservices, split where the business splits
Microservices are worth their cost when each service maps to a part of the business that changes on its own schedule, owns its own data and can fail without taking the rest down. We design and build Spring Boot platforms on those terms — and tell you plainly when a well-structured modular monolith would serve you better.












































What we design and build
Six decisions that make or break a microservices platform
Splitting code into services is the easy part. What decides whether the platform is cheaper to change than the monolith it replaced is where the boundaries fall, who owns the data, how services talk, and whether the team can see and survive a failure — so we design those six things before the second service is written, on the same engineering rules as our Spring Boot builds.
Domain decomposition
Service boundaries drawn around bounded contexts found with the people who run the business, sized so one team owns each service end to end — not one service per table or per screen.
Data ownership & consistency
A database per service, no shared tables, and sagas with the transactional outbox for work that spans services — so consistency is designed, not assumed.
Events with Kafka or RabbitMQ
Asynchronous integration through Spring for Apache Kafka, Spring AMQP or Spring Cloud Stream, with idempotent consumers, dead-letter queues and versioned event schemas.
API gateway & BFF
Spring Cloud Gateway for routing, authentication and rate limits at the edge, and a backend-for-frontend per client where web and mobile need different shapes of the same data.
Resilience & observability
Timeouts, retries, circuit breakers and bulkheads with Resilience4j; metrics, logs and traces with Micrometer and OpenTelemetry, so one request can be followed across every service it touches.
Security & delivery
OAuth 2.0 and JWT at the gateway and in every service, secrets kept out of code, and each service built, tested and deployed by its own pipeline to containers or Kubernetes.
Fit first
When Spring Boot microservices pay off, and when a modular monolith is the better answer
Microservices trade simplicity in the code for complexity in the system. Every service boundary becomes a network call that can be slow or fail, every service needs its own pipeline, monitoring and on-call owner, and data that used to sit in one transaction is now spread across several. That trade is worth making when different parts of the platform change at different speeds, need to scale separately, are owned by different teams, or carry different compliance and availability requirements.
It is rarely worth making for a new product with one team and an unsettled domain. There we usually recommend a modular monolith: one deployable Spring Boot application with module boundaries enforced in code — Spring Modulith can verify that modules only talk through their public APIs — so that a module can be lifted out into its own service later, once the boundary has proved itself.
An architecture review answers the question for your system before any code moves. We look at how the domain is organised, how often each part changes, where load and failures concentrate, what the team can operate, and what the regulators expect, and recommend services, a modular monolith or a mix — with the reasoning written down so the decision can be revisited.
- Parts of the system change on different schedules, or are owned by different teams
- One workload — ingestion, search, pricing — needs to scale far beyond the rest
- A failure in one area must not stop the others, such as alerting during a batch load
- Different parts carry different compliance, audit or availability requirements
- Several clients — web, mobile, partners — consume the same business capabilities
Decomposition
Drawing service boundaries around the business, not the database
Good boundaries come from the domain. We run short workshops with the people who use and run the system to map its business events, the decisions taken on them and the language each group uses, and draw bounded contexts where that language and ownership change. A boundary drawn this way is stable: the business rarely reorganises the difference between pricing and booking, whereas a boundary drawn around a database table moves every time the schema does.
For BizGlobe, the boundaries were the travel verticals themselves — flights, hotels, trains, visas, insurance, cabs and cruises — each a Spring Boot service with its own suppliers, rules and release cycle, behind one API layer that serves both the React web app and the React Native mobile apps. Adding a vertical meant adding a service, not reopening the others, and the shared API layer cut backend duplication across web and mobile by 70 %.
Size follows ownership. A service should be small enough for one team to understand and change on its own, and large enough that a single business change rarely touches more than one of them. When a feature regularly needs coordinated releases across three services, the boundary is wrong, and we would rather merge them than add more coordination.
Data ownership
Each service owns its data — and consistency is designed, not assumed
The rule that does most to keep microservices independent is that each service owns its data and no other service reads its tables. Other services get the data through the owning service's API or from the events it publishes. Shared databases are the most common reason a microservices platform ends up as a distributed monolith, where nothing can be changed or deployed on its own.
Work that spans services cannot use one database transaction, so we design it as a saga: a sequence of local transactions, each publishing an event that triggers the next, with a compensating action for each step if a later one fails. Simple flows are choreographed through events; flows with many steps or strict audit needs get an orchestrator that records where every instance stands. To make sure an event is published exactly when the database change commits, services write events to an outbox table in the same transaction and a relay — a scheduled publisher or change-data capture with Debezium — sends them to the broker.
Reporting and search are given their own read models rather than queries across service databases. Events feed a reporting store or a search index such as Elasticsearch, which is how the Royal Monetary Authority of Bhutan's EWS-Plus returns sub-second search across millions of financial records without loading the systems that own the data.
Communication
Synchronous where you need an answer, events where you need decoupling
Services call each other synchronously — REST with an OpenAPI contract, or gRPC between internal services where latency matters — only when the caller genuinely needs the answer to continue. Everything else is an event: an order placed, a payment received, a risk threshold crossed. Events let the publisher carry on without knowing who listens, and let a new consumer be added without changing the publisher.
For the broker, Kafka suits high-volume event streams, replay and multiple independent consumers of the same events; RabbitMQ suits task queues, routing and request-reply with lower operational weight. Either way, consumers are idempotent so a redelivered message does no harm, failed messages go to a dead-letter queue that someone monitors, and event schemas are versioned so producers and consumers can be released independently.
At the edge, Spring Cloud Gateway routes requests, validates tokens, applies rate limits and hides the internal topology from clients. Where web, mobile and partner clients need different views of the same capabilities, each gets a thin backend-for-frontend instead of one API that serves everyone badly — in Spring Boot, or in Node.js when the front-end team owns it. Contract tests with Spring Cloud Contract or Pact run in every pipeline, so a change that would break a consumer fails the build instead of production.
Resilience & observability
Making partial failure stay partial, and visible
In a distributed system something is always failing somewhere, so every call between services is written to expect it. Each call has a timeout; retries use backoff and only apply to operations that are safe to repeat; circuit breakers stop a struggling service from being flooded by callers; bulkheads keep one slow dependency from exhausting the threads everything else needs. Resilience4j provides these through Spring Cloud CircuitBreaker, and each one is tested by deliberately failing dependencies in a test environment.
Observability is built in from the first service, not added after the first incident. Spring Boot Actuator and Micrometer publish metrics; Micrometer Tracing with OpenTelemetry propagates a trace across every service, queue and database a request touches; logs are structured and carry the trace ID, so an engineer can go from an alert to the exact failing call in minutes. Dashboards and alerts are defined against service-level objectives — latency, error rate, queue lag — that the business has agreed matter.
- Timeouts on every remote call, retries with backoff only where operations are idempotent
- Resilience4j circuit breakers, bulkheads and rate limiters, tested by injecting failures
- Micrometer metrics and OpenTelemetry traces across services, queues and databases
- Structured logs with trace IDs, shipped to one place your team already uses
- Alerts on agreed service-level objectives, not on every CPU spike
Proof from banking and travel
Spring Boot microservices we have put into production
CareEdge's early-warning system is built as Spring Boot microservices behind an Angular 14 dashboard. It ingests borrower data from financial statements, transaction histories and credit bureaus, applies a rule engine whose thresholds risk officers configure themselves, and raises real-time alerts. It integrates with five core banking systems over secure REST APIs without disrupting them, processes more than 100,000 borrower records a day with sub-three-second query response, and cut NPA escalation response time by 60 %. How the system is put together is written up in Building an Early Warning System on Spring Boot.
Bank of Baroda's early-warning system started as a monolith built for one bank's data. After the mergers with Vijaya Bank and Dena Bank we split it into Spring Boot microservices on Java 11 behind Liferay DXP 7.4, with data-ingestion pipelines for the merged entities' systems and an RBI-compliant maker-checker workflow. The platform absorbed three times the data volume, risk-review cycles fell from two days to four hours, and no data was lost in the move — the route from monolith to services is described on our Spring Boot migration page.
Outside banking, BizGlobe's seven travel verticals run as separate Spring Boot services behind one API layer, and the platform went live on web, iOS and Android within a four-month development cycle.
Running it
Security, deployment and what a microservices platform costs
Security is enforced at two layers. The gateway authenticates every request with OAuth 2.0 and OpenID Connect and passes a token inward; each service is an OAuth 2.0 resource server that checks the token and applies its own authorisation rules, so a compromised neighbour cannot simply call it. Service-to-service traffic is encrypted, secrets come from a vault or the cloud provider's secret store rather than configuration files, and every image is scanned for vulnerable dependencies in CI. For banks and regulators the audit trail — who did what, through which service — is part of the design.
Each service has its own repository or module, its own pipeline and its own release. Images are built by Jenkins or GitHub Actions and deployed with blue-green or canary releases, using Actuator's liveness and readiness probes and Spring Boot's graceful shutdown so that deployments drop no requests. Kubernetes — EKS, AKS, GKE or on-premise — is the default once there are many services; a handful of services run perfectly well as containers on virtual machines or a managed container service, and we do not add Kubernetes to a platform that does not need it.
Cost is driven by the number of services and teams, the number of systems to integrate, how much existing data and behaviour has to move, the availability and compliance targets, and whether the platform foundations — gateway, pipelines, observability, security — already exist. Those foundations are built once, with the first service, and every later service reuses them. We start with an architecture review that ends in a service map, the foundations needed and a fixed-price proposal for the first release.
Not sure microservices are right for you?
An architecture review tells you whether services, a modular monolith or a mix fits your system, with the service map and a fixed price for the first release — whether or not you build it with us.
Book an architecture reviewOur technology stack
What a Spring Boot microservices platform runs on
Spring Boot services on a long-term-support Java release, a database per service, Redis and Elasticsearch where they earn their place, and containers built and deployed by CI to the cloud or data centre you already use.
How we deliver
From architecture review to services in production
Five phases, each ending in something you can check: a decision, a service map, a working platform with one service on it, then services released one at a time and handed over to your team.
Review
Domain, load, failure and compliance review, ending in a written recommendation: services, a modular monolith or a mix.
Map
Bounded contexts, service ownership, data ownership, sync and async interactions, and a fixed price for the first release.
Foundations
Gateway, security, pipelines, observability and the first service in production — the platform every later service reuses.
Build in slices
One service or bounded context at a time, each with contract tests, dashboards and alerts before it takes traffic.
Hand over & scale
Runbooks, on-call training and architecture records for your team, then new services or support on retainer.
Case studies
Spring Boot microservices in production
Early-warning systems for banks and a regulator, and a travel platform with one service per vertical — each with the outcome the client measured.
CareEdge Analytics & Advisory
Early Warning System (EWS) for Predictive Credit Risk Management. ATS Global Techsoft designed and built a full-stack EWS application using Spring Boot microservices for backend analytics and Angular 14 for a responsive dashboard.
Read case study
Public Sector BankingBank of Baroda — EWS Migration
Early Warning System Migration & Enhancement for Public Sector Bank. ATS led the complete migration to a Spring Boot + Angular architecture on Liferay DXP 7.4, introducing Angular portlets for dynamic UI, a multi-level maker-checker approval workflow, and predictive analytics modules for real-time financial risk flagging.
Read case study
Travel TechnologyBizGlobe Travel Tech
Unified Multi-Service Travel Booking Platform (Web + Mobile). ATS developed a comprehensive travel platform with Spring Boot microservices powering each travel vertical (Flights, Hotels, Trains, Visa, Insurance, Cab, Cruise) via well-defined REST APIs.
Read case study
Central Banking / Financial RegulationEWS-Plus — Royal Monetary Authority of Bhutan
National Banking Sector Early Warning System for Fraud & Financial Stability Monitoring. ATS built a comprehensive Liferay DXP 7.4 EWS platform featuring Liferay REST service modules for data ingestion, a multi-level Kaleo workflow for indicator data review (maker-checker), custom Elasticsearch integration for real-time indexed search and alerting, an automated notification system (in-app and email), and dynamic Excel reporting.
Read case study
Also in our Java practice
Spring Boot & Java development
REST APIs, batch pipelines and Java services of every size — and the full list of our Spring Boot case studies.
ExploreSpring Boot & Java migration
Spring Boot 2 to 3 and 4, Java 8 to 17 or 21, and monoliths split into services one bounded context at a time.
ExploreNode.js development
Backend-for-frontend layers and real-time services in Node.js, in front of Spring Boot microservices.
ExploreFAQs
Spring Boot microservices — questions we are asked first
Do we need microservices, or would a modular monolith do?+
If one team owns the product and the domain is still settling, a modular monolith is usually cheaper and faster: one Spring Boot application with module boundaries enforced in code, for example with Spring Modulith, so modules can become services later. Microservices pay off when parts of the system change, scale or fail independently, or are owned by different teams. Our architecture review recommends one or the other, or a mix, for your system.
Should we use Kafka or RabbitMQ?+
Kafka suits high-volume event streams, replaying history and many independent consumers of the same events. RabbitMQ suits task queues, flexible routing and request-reply, and is lighter to operate. Many platforms need only one; some use Kafka for business events and RabbitMQ for work queues. Spring supports both through Spring for Apache Kafka, Spring AMQP and Spring Cloud Stream.
How do you handle transactions that span several services?+
With sagas rather than distributed transactions: each service commits its own local transaction and publishes an event that triggers the next step, with a compensating action for each step if a later one fails. Events are written to an outbox table in the same transaction as the data change and relayed to the broker, so a change and its event are never out of step.
Do we need Kubernetes to run Spring Boot microservices?+
Not always. A handful of services run well as containers on virtual machines or a managed container service. Kubernetes earns its operational cost when there are many services, frequent releases and a need for autoscaling and self-healing. We deploy to EKS, AKS, GKE or on-premise clusters, and to plain servers where that is what the bank or regulator requires.
Can you take over or fix an existing microservices platform?+
Yes. We start with a review of the service boundaries, shared databases, synchronous call chains, observability and pipelines, because those are where distributed monoliths come from. The output is a prioritised list — merge these services, give this data an owner, add tracing here — that we can implement with your team or hand to them.
How long does it take to build a Spring Boot microservices platform?+
It depends mostly on the number of services, the systems to integrate and whether the foundations — gateway, pipelines, observability, security — already exist. Those are built once, with the first service. For scale, BizGlobe's seven travel verticals went live on web, iOS and Android within a four-month development cycle. The architecture review turns this into a dated plan and a fixed price for the first release.
Let’s work together
Tell us what you are building
Send a short description of the system, the teams that will own it and the systems it has to talk to — we will come back within a couple of days with a view on services versus a modular monolith, and a fixed price after the architecture review.