skip to content

Microservices architecture

11 roadmaps116 questionsupdated

Splitting a system into independently deployable services and dealing with everything that follows: where the boundaries go, how services talk, who owns which data, and how you run dozens of them. Interviews probe this hard because the costs are as important as the benefits.

on this pageshow

guide

overview

~1 min

Microservices is the architecture style of splitting one system into services that each own a business capability, keep their own data and ship on their own schedule. Interviewers rarely want the definition. They want to hear what the split costs: every in-process call that turns into a network call may be slow, fail halfway or never return, and data that used to sit behind one transaction is now spread across several owners. A strong answer names the benefit, the price paid for it and the conditions under which the trade is worth making. At senior levels the question is often whether to split at all. The subject splits into four sections. [Service decomposition and boundaries](/topics/found-microservices-design) is about where the lines go and how big a service should be. [Communication and data management](/topics/found-microservices-comm-data) covers how services talk, how their contracts evolve and how data stays consistent when no two services share a database. [Operations and deployment](/topics/found-microservices-operations) is the day-to-day cost of running many services: finding each other, surviving failure, being observed and being released safely. [Adoption and trade-offs](/topics/found-microservices-adoption) steps back to the decision itself, the migration path from a monolith and the team structure the architecture needs. Start with boundaries, because a bad split makes every later problem worse and tooling rarely repairs it. Then learn communication and data, where most design discussions end up. Operations comes next, and adoption last, once you can weigh the costs you have just studied. Questions run from a junior explaining why services keep separate databases to a principal judging whether an organisation is ready for the split, so return to each section as your level rises.

primer

A few ideas sit under nearly every question in this hub. Hold these and most answers become consequences rather than facts to memorise. - **Independent deployability is the point.** The defining property of a service is that its team can change and release it without coordinating with other teams. Smaller code bases, separate scaling and technology freedom are secondary. When a design forces services to ship together, it has lost the main benefit while keeping all the costs, and interviewers expect you to notice that. - **A boundary follows the business, not the code.** Good services are cut around a capability and the language that goes with it, so a change to one business rule touches one service. Cuts along technical layers or along individual tables tend to spread every feature across several services. Size follows from the boundary; it is not a target in itself. - **The network is not a function call.** Latency, partial failure, timeouts, duplicate delivery and version skew all arrive with the first remote call. Much of this hub is the machinery that contains them: timeouts, retries with limits, circuit breakers, idempotent handlers and asynchronous messaging where the caller does not need an immediate answer. - **Each piece of data has one owner.** A service's store is private; others reach its data through its interface or through events it publishes. That is what keeps schemas free to change, and it is also why cross-service consistency becomes eventual and why multi-step business operations need compensation instead of one atomic transaction. - **Contracts should be the only shared surface.** APIs and event schemas replace the compiler as the thing that keeps services compatible, so they must evolve without breaking existing consumers and be checked before release rather than discovered in production. - **Operations is where the bill arrives.** Discovery, observability, deployment pipelines and configuration multiply with the number of services. A team that cannot yet trace a request or roll back one service safely is not ready to run many of them. - **Architecture and organisation shape each other.** Systems tend to mirror the communication paths of the teams that build them, so service boundaries and team ownership have to be designed together.

Modular monolith
One deployable unit whose internal modules have enforced boundaries and private data, keeping in-process calls while preparing for a later split.
Distributed monolith
A set of separately deployed services so tightly coupled that they must change, release or fail together; the costs of distribution without its independence.
Bounded context
A Domain-Driven Design term for the part of a domain inside which each term has a single meaning and model; the usual starting point for a service boundary.
Aggregate
A cluster of domain objects that must stay consistent as a unit and is changed through one entry point; it belongs wholly to one service.
Anti-corruption layer
A translation boundary that converts another system's model into your own so its concepts and quirks do not leak into your domain.
Eventual consistency
A guarantee that replicas or copies converge if updates stop, accepting a window during which different services see different values.
Saga
A multi-service business operation run as a sequence of local transactions, each with a compensating action that semantically undoes it if a later step fails.
Transactional outbox
Recording an outgoing message in the same local transaction as the state change, then relaying it separately, so neither can happen without the other.
Idempotency
The property that processing the same request or message more than once has the same effect as processing it once; required wherever delivery can repeat.
API gateway
A single entry point in front of the services that handles routing and cross-cutting concerns such as authentication and rate limiting for external clients.
Backend for Frontend
A server-side layer dedicated to one client type that shapes and aggregates service data for that client's screens.
Service discovery
The mechanism by which a caller finds the current network locations of a service's healthy instances as they start, stop and move.
Circuit breaker
A guard around a remote call that stops calling a failing dependency for a period, failing fast instead of waiting, then probes before resuming.
Distributed tracing
Propagating a request identifier across service calls so each hop can be recorded and joined into one end-to-end timeline.
Conway's Law
The observation that a system's structure tends to copy the communication structure of the organisation that designs it.

The four sections form a chain: each one inherits the decisions of the one before. **Boundaries decide everything downstream.** A service cut around a coherent capability can keep its data private, talk to others through a small contract and be deployed alone. A service cut around a table, a layer or an arbitrary size ends up chatty, shares data under the table and has to be released in lockstep. Most of the symptoms discussed under [the distributed monolith](/topics/found-microservices-distributed-monolith) trace back to [decomposition](/topics/found-microservices-decomposition) and [granularity](/topics/found-microservices-service-granularity) choices, which is why interviewers so often answer an operations complaint with a boundary question. **Data ownership forces the communication style.** Once no two services share a store, three questions follow. How does one service learn about another's data: by asking at request time, or by keeping a local copy fed by events? How does a business operation span several owners: through a [saga](/topics/found-microservices-distributed-data-saga) and its compensations rather than one transaction? How do the messages themselves stay reliable when a write and a publish can fail independently? The [communication](/topics/found-microservices-communication) and [data ownership](/topics/found-microservices-data-ownership) sections are two views of the same decision. **Edges and contracts protect independence.** Gateways and BFFs keep external clients from coupling to internal service layout; [contracts and versioning](/topics/found-microservices-contracts-versioning) keep internal consumers from breaking when a provider changes; anti-corruption layers keep a foreign model from leaking in. Each is a boundary tool applied at a different edge. **Operations makes the design survivable.** Every remote call the earlier sections introduce needs a way to be found, a way to fail without spreading, and a way to be seen when it misbehaves; every service needs a release path that can be rolled back on its own. [Resilience and observability](/topics/found-microservices-resilience-observability) and [deployment strategies](/topics/found-microservices-deployment-strategies) are the core here; discovery, configuration, containers and meshes are the platform that supports them. **Adoption closes the loop.** The [monolith versus microservices](/topics/found-microservices-vs-monolith-tradeoffs) section weighs the whole bill above against the benefits, the migration section shows how to pay it incrementally, and [Conway's Law](/topics/found-microservices-organizational-conway) explains why the boundaries you drew in the first section only hold if teams are drawn the same way.

  1. Microservices vs Monolith Trade-offs →

    Start with what the split buys and what it costs, since every later section is part of that bill or a way to reduce it.

  2. Service Decomposition →

    Learn to draw boundaries around business capabilities, the decision every other section inherits and the hardest one to undo.

  3. Data Ownership →

    Private data per service is what makes independence real; it also explains eventual consistency and why cross-service transactions change shape.

  4. Inter-Service Communication →

    Synchronous versus asynchronous and request versus event: the coupling each style creates drives most design discussions.

  5. Distributed Transactions & Saga →

    With ownership and messaging in place, see how multi-step business operations stay consistent without a shared transaction.

  6. Resilience & Observability →

    Timeouts, retries, breakers and tracing are what keep one failing dependency from becoming an outage, and what lets you find it.

  • Leading with the benefits of microservices and never naming the costs; interviewers probe exactly the network, data and operational overhead you skipped.

  • Cutting services by technical layer or by database table, so every feature change spans several services and they must be released together.

  • Letting services share a database or read each other's tables, which turns the schema into an unversioned contract and ends independent deployment.

  • Proposing a distributed transaction across services without discussing why locking several owners together defeats the architecture; name the saga and its compensations instead.

  • Publishing an event and writing to the database as two separate steps, then assuming both happened; say how the outbox or an equivalent closes the gap.

  • Adding retries without timeouts, caps, backoff or idempotent handlers, which multiplies load on a struggling dependency and can duplicate side effects.

  • Building long chains of synchronous calls for one user request, so availability becomes the product of every hop and latency the sum.

  • Treating service size as the goal; nanoservices pay the full per-service cost for almost no behaviour, and granularity follows from cohesion.

  • Discussing architecture without teams: shared ownership of a service, or boundaries that cut across reporting lines, undo the autonomy the design assumes.

The same handful of choices recur across the sections, and naming the one you are making usually earns more credit than naming a pattern. - **Autonomy versus operational cost.** Each extra service buys a team the right to ship alone and costs a pipeline, monitoring, on-call and a network hop. The right number is the smallest one that removes the coordination actually hurting you. - **Freshness versus independence.** Asking the owner at request time gives fresh data and a runtime dependency; keeping a local copy fed by events gives independence and staleness. Decide per piece of data, based on how wrong it may briefly be. - **Synchronous versus asynchronous.** A direct call is simple to reason about and couples the caller to the callee's uptime; a message decouples them in time and adds a broker, ordering questions and harder debugging. - **Choreography versus orchestration.** Reacting to events spreads the workflow across services and avoids a central coordinator; a coordinator makes the flow visible and testable at the price of a component that knows every step. - **Monolith first versus split early.** Starting whole lets boundaries be discovered before they are frozen into networks and data stores; splitting early fits when the domain and the team boundaries are already well understood.

A small set of named shapes appears across many questions under different wording; recognising them is how you place a new scenario quickly. - **Isolate a foreign model.** Anti-corruption layers, adapters at the edge and BFFs all put a translation step between a model you do not control and the one you do. - **Make a write and a message atomic.** The transactional outbox and change-data capture both tie publishing to the local commit so downstream services never miss or invent a change. - **Undo instead of roll back.** Sagas, whether choreographed or orchestrated, replace one atomic transaction with local steps and compensations, and assume every step may run twice. - **Contain a failing dependency.** Timeouts, capped retries with jitter, circuit breakers and bulkheads each limit how far one slow service can spread. - **Separate deploy from release.** Canary and blue-green rollouts, feature flags and parallel runs let new code reach production before it reaches every user. - **Replace incrementally.** The strangler fig, branch by abstraction and seam-first extraction migrate a monolith one capability at a time, keeping a working system throughout.

explore

report an issue with this guide →

questions

116 · 4 sections

Your team's new 'Orders' microservice needs to read data from a 20-year-old legacy inventory system that uses cryptic status codes like 'S3' and denormalized flat records. Instead of letting the Orders service call the legacy API directly and pass those codes around internally, the team builds a small module that sits between them and converts everything into the Orders service's own clean model before anything else touches it. What is this module called, and what problem does it solve?

level: juniorimportance: must knowfreq 65%
basics
~20 s

It's an anti-corruption layer - a translator sitting at the boundary that converts a foreign or messy system's data/language into your own clean model, so ugliness on the other side never leaks into your code.

open as a page

When breaking a monolithic application into microservices, what does it mean to decompose 'by business capability' (e.g., Order Management, Inventory, Billing) rather than by technical layer (e.g., a separate UI service, a business-logic service, and a database-access service)? Why is the capability-based split generally preferred?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Group services around business functions like 'Orders', each owning its own logic and data end to end. Splitting by technical layer (UI service, logic service, DB service) instead forces every feature to touch several services at once.

open as a page

In a microservices architecture, what is a 'distributed monolith', and what's usually the first symptom a team notices?

level: juniorimportance: must knowfreq 75%
basics
~20 s

It's when you've split code into separate services but they're still so tightly tied together that you can't deploy or change one without touching the others - you get all the complexity of microservices with none of the independence.

open as a page

In microservices design, why do teams typically draw each service's boundary around a Domain-Driven Design 'bounded context' rather than around a database table or an org-chart team?

level: juniorimportance: must knowfreq 75%
basics
~20 s

A bounded context is the area of the business where a word like "Order" has exactly one meaning. Building a service per bounded context keeps each service's data model and vocabulary consistent, instead of forcing every team to agree on one giant shared meaning for every term.

open as a page

What is a 'nanoservice' anti-pattern, and why is a service that's too small often worse than a monolith?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A nanoservice is a service split so small (like one endpoint) that it does barely any real work but still pays the full cost of being a separate service - network calls, its own database, deployment pipeline, on-call rotation. That overhead usually costs more than it saves.

open as a page

What is an API Gateway in a microservices architecture, and what problem does it solve for client applications that need data from multiple backend services?

level: juniorimportance: must knowfreq 85%
basics
~20 s

It's a single door that all client requests pass through before reaching the actual services behind it. Instead of a client knowing about and calling ten different services, it talks to one address, and the gateway figures out where to send each request.

open as a page

What problem does the Backend for Frontend (BFF) pattern solve, and how does it typically sit between a client app and the backend services?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A BFF is a small backend built just for one type of app (like a mobile app or a website) so that app gets exactly the data it needs in one call, instead of talking to lots of different services itself and stitching the results together.

open as a page

In a microservices system, what's the basic difference between a synchronous call between services (like REST over HTTP) and an asynchronous message (like publishing to a queue), and when would you pick each?

level: juniorimportance: must knowfreq 85%
basics
~20 s

A synchronous call waits for an immediate answer before moving on, like a phone call. An asynchronous message is sent off while the sender keeps working, like leaving a voicemail; the other side handles it and replies whenever it's ready.

open as a page

In a microservices system, what does it mean for an API change to be 'backward compatible', and what is a concrete example of a change that breaks it?

level: juniorimportance: must knowfreq 80%
basics
~20 s

A backward-compatible change lets old clients keep working without updates, like adding a new optional field. A breaking change forces every client to update at once, like renaming or removing a field they depend on.

open as a page

In a microservices architecture, why does each service typically own and manage its own database rather than multiple services sharing one database?

level: juniorimportance: must knowfreq 85%
basics
~10 s

Each service gets its own database so only that service can change its data directly; others must ask through its API, which stops hidden dependencies and lets services evolve independently.

open as a page

Why should application configuration (like database URLs, timeouts, or feature flags) be kept outside the compiled application artifact instead of hardcoded, especially when the same service runs in dev, staging, and production?

level: juniorimportance: must knowfreq 75%
basics
~20 s

Because the same built package has to run in different places (laptop, test, live servers) that need different settings. If settings are baked into the code, you'd have to rebuild the whole app just to change a URL, and test settings could leak into production.

open as a page

Why do teams building a microservices system typically package each service as a container image rather than installing it directly onto a shared virtual machine?

level: juniorimportance: must knowfreq 75%
basics
~10 s

A container bundles a service with everything it needs to run, so it starts the same way everywhere and doesn't fight with other services sharing a machine over conflicting libraries or versions.

open as a page

In a blue-green deployment, two identical production environments (blue = live, green = idle) exist side by side. Explain how traffic cutover works and what happens if the new version needs to be rolled back.

level: juniorimportance: must knowfreq 75%
basics
~20 s

You run two copies of the app - one live, one idle with the new version. Once the idle one is tested and ready, you flip a switch (router/load balancer) so all traffic goes to it. If something breaks, you flip back instantly.

open as a page

In a microservice that calls a downstream payment service over HTTP, what problem does wrapping that call in a circuit breaker solve, and how does the breaker decide when to stop letting calls through?

level: juniorimportance: must knowfreq 85%
basics
~20 s

A circuit breaker watches for repeated failures calling another service and, once it sees too many, stops sending new requests for a while so the failing service isn't overloaded and your own service doesn't get stuck waiting.

open as a page

In a microservices architecture, what is service discovery and why can't services just call each other using hardcoded IP addresses?

level: juniorimportance: must knowfreq 85%
basics
~10 s

Service discovery lets services find each other's current network location automatically, instead of using fixed IP addresses that change when instances scale, restart, or move.

open as a page

In a monolith-to-microservices migration, what is the strangler fig pattern and why do teams use it instead of a full rewrite?

level: juniorimportance: must knowfreq 70%
basics
~10 s

You build new features/services alongside the old monolith and slowly route traffic to them, until the old system does nothing and can be deleted. It avoids one risky big-bang rewrite.

open as a page

What is Conway's Law, and why does it matter when a company splits a monolith into microservices?

level: juniorimportance: must knowfreq 75%
basics
~20 s

Conway's Law says the software you build ends up shaped like the teams that built it. If teams don't talk much, the code splits along those same lines. So when moving to microservices, you have to think about team structure, not just code structure.

open as a page

What do you gain and what do you give up when you split a single application into multiple independently deployable microservices, versus keeping it as one monolith?

level: juniorimportance: must knowfreq 85%
basics
~20 s

A monolith is one big program deployed as a single unit; microservices split it into many small programs that talk over the network. Microservices let teams work and scale independently, but add network calls, more infrastructure, and coordination overhead.

open as a page

What is branch-by-abstraction, and how does it let a team extract a module into a separate service without a long-lived feature branch or a risky flag-day cutover?

level: middleimportance: must knowfreq 65%
basics
~20 s

You put a stable interface in front of the old code, build the new implementation behind that same interface, switch callers over gradually, then delete the old code — all on the main branch, no long branches.

open as a page

What is the 'inverse Conway maneuver', and what concrete steps would a company take to apply it before a microservices migration?

level: middleimportance: must knowfreq 55%
basics
~20 s

It's deliberately reorganizing your teams to match the architecture you want, instead of letting the architecture accidentally end up looking like whatever teams you already have. You design the org chart on purpose so the software naturally comes out the way you planned.

open as a page