DevNotes
Support
Microservices Fundamentals · Chapter 01

Introduction to Microservices

Monolith vs microservices, what makes a service "micro", the real benefits and costs, the Spring Cloud toolbox, when microservices are the wrong choice, and the modular monolith alternative.

◷ 6 min read§ 12 sections? 6 interview questions{ } 0 code examples

#Introduction

A microservices architecture builds one application as a set of small, independently deployable services, each owning one business capability and its own data, communicating over the network through APIs or events.

#The Monolith

A monolith is one deployable unit containing every feature:

  • shop.jar
    • Orders module
    • Payments module
    • Inventory module
    • Users module
    • Notifications module
    • One shared database

Monoliths are not bad. They're simple to build, test, deploy and debug, and most successful products start as one. Problems appear as the codebase and team grow:

Growing painEffect
One huge codebaseSlow builds, hard to understand, tangled dependencies
One deploymentA one-line change redeploys everything; releases need coordination
One scaling unitYou must scale the whole app even if only search is busy
One technology stackHard to adopt a new framework or language for one part
Shared failure domainA memory leak in reports can crash checkout
Many teams, one repoMerge conflicts and release trains slow everyone down

#Microservices

Client
API gateway
Order, Payment, Inventory, User, Notification services
Each service with its own database
  • Shop platform
    • Order serviceorders DB
    • Payment servicepayments DB
    • Inventory serviceinventory DB
    • User serviceusers DB
    • Notification serviceno DB, consumes events

Characteristics

  • Organised around business capabilities — "payments", not "the database layer".
  • Independently deployable — release a service without touching the others.
  • Own their data — no other service reads or writes its database directly.
  • Communicate over the network — REST/gRPC calls or asynchronous events (Kafka).
  • Small enough for one team to own end to end ("you build it, you run it").
  • Decentralised — each service can choose the right tools for its job.
  • Designed for failure — any call can fail, so services use timeouts, retries and circuit breakers.

#Benefits

BenefitHow
Independent deploymentSmall, frequent, low-risk releases per service
Independent scalingRun 20 instances of search, 2 of user profile
Fault isolationA failing recommendation service doesn't stop checkout (if designed well)
Team autonomyTeams own services end to end and move at their own pace
Technology flexibilityUse the best tool per service (Java for payments, Python for ML)
Easier to understandEach codebase is small and focused

#Costs — the "Microservice Premium"

CostWhat it means
Distributed-system complexityNetwork latency, partial failures, timeouts, retries
Data consistencyNo cross-service transactions — sagas and eventual consistency instead
Operational overheadMany deployments, pipelines, configs, dashboards and alerts
Harder debuggingOne request spans many services — you need distributed tracing
Testing complexityIntegration and contract testing across services
Network costAn in-process call (nanoseconds) becomes an HTTP call (milliseconds)
DuplicationShared concerns (auth, logging) must be handled consistently everywhere

#When Microservices Are the Wrong Choice

  • A new product whose domain boundaries aren't clear yet — boundaries drawn too early are expensive to move.
  • A small team (one or two teams) — the operational overhead outweighs the benefits.
  • No automation — without CI/CD, containers, monitoring and tracing, microservices are painful.
  • Tightly coupled data that's constantly queried and updated together.

The Modular Monolith

A middle ground: one deployable application with strictly separated modules (own packages, clear interfaces, no shared tables between modules). It keeps deployment simple while preparing clean boundaries — modules can later be extracted into services. Spring Modulith supports this style in Spring Boot.

#Monolith vs Microservices

MonolithMicroservices
DeploymentOne unitMany independent units
ScalingWhole applicationPer service
DataOne shared databaseDatabase per service
TransactionsLocal ACID transactionsSagas, eventual consistency
CommunicationIn-process method callsNetwork calls and events
FailureCan take down everythingIsolated, if designed for it
ComplexityIn the codeIn the infrastructure and interactions
Best forSmall teams, early productsLarge organisations, independent teams, varied scaling needs

#The Spring Cloud Toolbox

ConcernTypical Spring / cloud solutionChapter
Calling other servicesRestClient, WebClient, OpenFeign, gRPCInter-Service Communication
Finding servicesEureka, Spring Cloud LoadBalancer, Kubernetes DNSService Discovery
Single entry pointSpring Cloud GatewayAPI Gateway
Central configurationSpring Cloud Config, Kubernetes ConfigMapsConfig Server
ResilienceResilience4j (circuit breaker, retry, bulkhead)Resilience Patterns
Async messagingKafka, RabbitMQ (Spring Kafka, Spring Cloud Stream)Kafka Masterclass
SecurityOAuth2 / OIDC, JWT, Spring Security resource serversSecurity
ObservabilityMicrometer, Prometheus, OpenTelemetry, ZipkinObservability
DeploymentDocker, KubernetesDeployment

#Migrating from a Monolith: the Strangler Fig

Rewriting a monolith from scratch is risky. The strangler fig pattern replaces it gradually:

Put a gateway or proxy in front of the monolith
Build one new service for one capability — e.g. notifications
Route that capability's traffic to the new service
Repeat, capability by capability
Retire the monolith when nothing is left

#Interview Questions

Q1What are microservices?

An architectural style that structures an application as small, independently deployable services, each owning a business capability and its data, communicating over the network.

Q2What are the advantages of microservices over a monolith?

Independent deployment and scaling, fault isolation, team autonomy, technology flexibility and smaller, more understandable codebases.

Q3What are the disadvantages?

Distributed-system complexity (latency, partial failures), no cross-service transactions, higher operational overhead, harder debugging and testing, and the risk of building a distributed monolith.

Q4When would you not use microservices?

For a new product with unclear boundaries, a small team, little automation or monitoring, or a domain where data is tightly coupled. A modular monolith is often a better starting point.

Q5What is a distributed monolith?

A system split into services that still have to be deployed together because of shared databases, tight synchronous coupling or shared release cycles — microservice complexity without microservice benefits.

Q6How would you migrate a monolith to microservices?

Incrementally, with the strangler fig pattern: route traffic through a gateway, extract one well-bounded capability at a time into a service with its own data, and retire the corresponding monolith code.

#Common Mistakes

  • Starting with microservices before the domain is understood.
  • Sharing one database between services.
  • Long chains of synchronous calls — latency and failures add up.
  • Splitting by technical layer ("controller service", "DAO service") instead of business capability.
  • No automation or observability — dozens of services you can't deploy or debug.

#Key Takeaways

  • Microservices are independently deployable services organised around business capabilities, each owning its data.
  • They trade code complexity for distributed-system complexity.
  • Benefits: independent deployment and scaling, fault isolation, team autonomy.
  • Costs: network failures, eventual consistency, operational overhead, harder debugging.
  • Start with a well-structured monolith when in doubt; extract services with the strangler fig.