Microservices: Definition

ModernLift · ·6 min read
Part 7 of 14

Microservices are an architectural style in which an application is built as a collection of small, independently deployable services, each responsible for one business capability and communicating with the others over a network. They are the common counterpart to a monolith, where the whole application is built and deployed as a single unit.

Microservices describe a way of structuring an application: instead of one large program that does everything, the system is composed of many small services, each owning a single business capability and talking to the others across a network. It is most easily understood as the opposite of a monolith, where the entire application is built, deployed, and scaled as one unit.

What it is

Each microservice is independently deployable. It can be released, scaled, and even rewritten without redeploying the rest of the system. A service typically owns its own data, its own database or schema, and exposes a well-defined interface. Other services reach it through that interface rather than reaching into its internals or its data store directly. That ownership is what makes independent deployment safe: if two services shared one database, deploying one could silently break the other.

How services talk to each other

StyleHow it worksTrade-off
Synchronous (API call)Caller sends a request and waits for a responseSimple to reason about, but couples the caller’s success to the callee’s availability
Asynchronous (events, queues)A service publishes an event and moves on, others react when they get to itKeeps services decoupled and resilient to each other’s downtime, at the cost of eventual consistency and harder-to-trace failures

Most real systems use both: synchronous calls for a read a user is actively waiting on, events for work that can safely happen a moment later.

What it looks like in practice

An order service accepts a checkout request and publishes an “order placed” event. A pricing service, which has no idea the order service exists beyond that event, calculates the total and returns it. A notification service, listening for the same event, sends the confirmation email. Each is built, deployed, and scaled by a different team on its own schedule. If the notification service has a bug, an email is delayed. It does not stop anyone from checking out, because the checkout path never depended on it directly.

Why it matters

The appeal is autonomy. Independent teams can ship on their own schedules, individual services can be scaled to their own load, and a failure can be contained to one service rather than taking down the whole application. For large systems with many teams, that independence is the difference between shipping weekly and shipping quarterly.

Signs microservices might be the right target

  • Independent teams are blocked shipping on the same release train, and splitting ownership would remove the blockage.
  • Parts of the system have genuinely different load or scaling profiles, a checkout path that spikes on sale days versus a catalog that stays flat, that would benefit from scaling separately.
  • A failure in a non-critical capability is currently able to take down a critical one, because they run in the same process.
  • Different parts of the system would benefit from different technology choices or release cadences that a shared deployment currently forces to move together.

If none of these are true, microservices add operational cost, a distributed system to run, monitor, and debug, without buying anything back. That cost is real and ongoing, not a one-time migration expense.

How it relates to modernization

Microservices are a common target for modernization, but the path matters more than the destination. Rewriting a monolith into microservices in one move concentrates risk on a single cutover, the failure pattern that sinks most large rebuilds. The lower-risk route is to extract services incrementally: pull one capability out behind a strangler facade, prove it behaves identically to the code it replaces, shift traffic, and repeat. This is re-architecting done slice by slice, with the system running the entire time.

Common confusion

Microservices are frequently treated as the “modern” architecture every system should have. They are not a default. They are a trade: you exchange the simplicity of one deployable unit for the operational complexity of a distributed system, network latency, partial failure, and data spread across many stores. For plenty of systems a well-structured monolith is the better engineering choice. A related trap is over-splitting: cutting services smaller than any real ownership boundary, which multiplies the complexity without adding real autonomy. The right question is not “monolith or microservices?” but “what does this system actually need to do that its current shape prevents?”

Frequently asked questions

What is the difference between microservices and a monolith?
A monolith is one deployable unit — all the code ships together. Microservices split the application into many small services that deploy independently. The microservices trade-off is autonomy and independent scaling in exchange for the operational complexity of running a distributed system.
Are microservices always better than a monolith?
No. Microservices add real complexity — network calls, distributed data, more moving parts to operate. For many systems a well-structured monolith is the better choice. Microservices pay off when independent teams need to deploy and scale parts of the system independently, not as a default.
Do you have to rewrite a monolith to get microservices?
No. The lower-risk path is to extract services incrementally, pulling one capability at a time out of the monolith behind a facade, rather than rewriting the whole thing at once. That is the strangler approach, and it lets the system keep running throughout.
How do microservices communicate with each other?
Two main ways. Synchronously, one service calls another's API and waits for a response, simple to reason about but it couples the caller's availability to the callee's. Or asynchronously, a service publishes an event to a queue and moves on, with other services reacting whenever they get to it, which keeps services decoupled at the cost of eventual consistency and harder debugging. Most real systems use both, synchronous calls for reads a user is waiting on, events for work that can happen after the fact.
What is the right size for a microservice?
There is no line-of-code target. The right boundary is a business capability that one team can own end to end, order management, pricing, notifications, not an arbitrary size. Splitting services smaller than a real ownership boundary just multiplies network calls and operational overhead without buying any additional autonomy, a failure mode sometimes called "nanoservices."
All 14 parts of Modernization Glossary & Definitions →