# Microservices architecture

> Microservices architecture splits an application into independently deployable services organized around business capabilities, such as orders, payments, and delivery. It helps teams change and scale those capabilities separately, but turns local calls and transactions into network communication and cross-service coordination.

Source: https://sysround.com/concepts/microservices
Updated: 2026-11-05


## How microservices architecture works

Choose boundaries around business responsibilities and the rules that must stay consistent together, not around individual database tables. For example, a booking service should own seat holds and reservations so preventing double booking does not require a transaction across several services.

Each service owns its data and exposes APIs or events rather than letting other services write its tables. Ownership does not require a separate physical database server for every service, but shared tables and cross-service SQL joins create coupling that makes independent changes harder.

Use synchronous calls when the caller needs an immediate answer, such as checking whether a seat hold succeeded. Use durable asynchronous messages when work can finish later, such as sending a confirmation email. Every synchronous dependency adds latency and another way the request can fail.

Model workflows across services as explicit state transitions. A booking might move from HELD to PAYMENT_PENDING to CONFIRMED. Local transactions protect each service's invariants; a saga coordinates cross-service steps and compensations, while an outbox reliably connects a committed state change to an outgoing event.

Design for partial failure: a payment request can time out even though the charge succeeded. Use stable idempotency keys, bounded retries, timeouts, and reconciliation rather than assuming a failed response means nothing happened. Circuit breakers, concurrency limits, and separate worker pools help prevent one slow dependency from exhausting the whole system.

Operate services independently with deployment automation, service discovery, access control, and observability. Propagate request and trace IDs across calls and messages so an order can be followed end to end. An API gateway can route external requests, but a gateway, Kubernetes, or a service mesh is not what defines microservices.

## Worked example: Separating booking, payments, and notifications

Suppose a ticketing system receives 2,000 booking attempts per second during a sale. The booking service owns seat holds and reservations, keeping seat allocation inside one database transaction. The payment service owns provider interactions and payment attempts, using the booking ID plus an attempt identifier as a stable idempotency key. Booking records a PAYMENT_PENDING state and an outbox event atomically. A payment result advances the booking to CONFIRMED only if its hold is still valid; a late successful charge triggers a refund workflow. Notifications consume confirmation events independently. If the email provider stalls, confirmations still commit, while a payment outage leaves bookings pending under an explicit expiration and reconciliation policy.

## Trade-offs

- **Independent scaling versus distributed overhead.** You can scale a busy location-ingestion service without scaling checkout, but network calls, serialization, and additional infrastructure consume resources.
- **Independent releases versus contract management.** Teams can deploy separately only when API and event changes remain compatible with consumers running older versions.
- **Local transactions versus cross-service consistency.** Service-owned data keeps local rules easier to enforce, but workflows spanning owners need explicit intermediate states, retries, and recovery.
- **Failure isolation versus cascading failures.** Separate processes provide a boundary, but shared databases, unbounded queues, and synchronous dependency chains can still spread an outage.
- **Team autonomy versus operational cost.** Clear ownership reduces coordination for routine changes, but each service adds deployment, security, monitoring, and on-call work.
- **Focused data models versus harder combined reads.** Each service can optimize its own storage, while cross-service screens and reports may require API aggregation or asynchronously maintained read models.

## When to use it in a system design interview

- Business capabilities have distinct owners and release schedules, and coordinated deployments are becoming a bottleneck.
- Workloads need substantially different scaling or isolation, such as high-volume location updates versus low-volume payment operations.
- A broad product includes separable domains, such as ordering, restaurant fulfillment, courier dispatch, and notifications.
- You can name a concrete benefit for each proposed boundary and explain how the resulting network and consistency costs will be handled.
- An existing application needs gradual extraction of a specific capability; otherwise, a modular monolith may be the simpler starting point.

## How to bring it up in the interview

- Start with requirements and invariants, not a diagram full of services. Explain which responsibilities can change independently and which operations should remain inside one transaction.
- Trace one important request through the proposed boundaries, naming the data owner, synchronous dependencies, durable writes, and asynchronous follow-up work.
- Defend each split with a scaling, ownership, release, or isolation need. Expect the interviewer to ask why the same design could not start as a modular monolith.
- Describe a timeout after a successful remote operation. Interviewers often probe idempotency scope, retry limits, compensation, and how reconciliation discovers unfinished work.
- Explain how independently deployed versions coexist and how you debug a failed workflow. Expect follow-ups on schema evolution, trace propagation, dependency latency, and behavior when a service is unavailable.

## Common mistakes

- Creating a service per entity or table, forcing simple business operations through long chains of calls.
- Calling the design independently deployable while services share writable tables or require synchronized releases.
- Assuming messages provide exactly-once business effects, or that a timeout proves a remote operation failed.
- Claiming microservices automatically improve availability without controlling dependency chains, resource exhaustion, and shared infrastructure failures.
- Choosing microservices solely because traffic is high; a replicated modular monolith can handle substantial load without cross-service coordination.

## Interview questions where it comes up

- [Design a food delivery app like DoorDash](https://sysround.com/questions/design-doordash): Order management, restaurant fulfillment, payments, and dispatch need clear ownership boundaries and a recoverable workflow across independently failing components.
- [Design a ticket booking system like Ticketmaster](https://sysround.com/questions/design-ticketmaster): Keeping inventory invariants local while coordinating payment outcomes makes service boundaries and cross-service failure handling central design decisions.
- [Design a notification system](https://sysround.com/questions/design-notification-system): Separating notification intake from channel delivery enables independent scaling and provider-failure isolation, with explicit contracts and durable handoffs.

## FAQ

### What is the difference between microservices and a monolith?

A monolith deploys its application modules together, while microservices allow services to be deployed independently. A modular monolith can still have clear domain boundaries and strong internal APIs. The main difference is the deployment and failure boundary, not whether the code is well organized.

### How do you choose microservice boundaries in system design?

Group responsibilities around business capabilities, data ownership, and invariants that need a local transaction. Then check whether separate scaling, ownership, or release schedules justify a network boundary. If two proposed services constantly call each other or must always deploy together, consider combining them.

### Does each microservice need its own database?

Each service should control its own data and prevent other services from depending directly on its internal schema. Separate schemas or databases on shared infrastructure can preserve that ownership, although they still share operational risks. Dedicated database infrastructure is useful when stronger performance, security, or failure isolation justifies its cost.

## Related concepts

- [Service discovery](https://sysround.com/concepts/service-discovery)
- [Saga pattern](https://sysround.com/concepts/saga-pattern)
- [Transactional outbox pattern](https://sysround.com/concepts/outbox-pattern)
- [Distributed tracing](https://sysround.com/concepts/distributed-tracing)


---
SysRound (https://sysround.com) is an AI practice tool for system design interviews: a voice or typed AI interviewer, a shared whiteboard, then feedback on every skill and a model answer. Its feedback is AI-generated and can be wrong.
