A monolith is a single application containing all of a system's functionality, deployed as one unit. It's often maligned, but for most teams and most products, it's the right starting point: one codebase to understand, one thing to deploy, no network calls between internal components, and refactoring across the whole system is a single, simple change.
A microservices architecture splits a system into small, independently deployable services, each owning a specific piece of business functionality (an orders service, a payments service, a notifications service), communicating over the network.
Order Service --HTTP--> Payment Service
|
+--------HTTP--> Notification Service
The appeal is real: teams can deploy independently, scale only the service that needs it, and use different tech per service if warranted. The cost is also real: network calls replace function calls (slower, and can fail in new ways), debugging a request across five services is harder than reading one stack trace, and you now need infrastructure — service discovery, distributed tracing — that a monolith never required.
They tend to make sense once a single team can no longer own the whole codebase, once different parts of the system have genuinely different scaling needs, or once independent deployability is worth more to the organization than the added operational complexity. Adopting microservices before you have that pain is one of the most common architecture mistakes — it front-loads real complexity for a problem you don't have yet.
OrderPlaced event
├── Inventory service decrements stock
├── Email service sends confirmation
└── Analytics service logs the sale
Instead of one service directly calling three others, it publishes an event, and any interested service reacts independently. This decouples the publisher from needing to know who's listening — you can add a new subscriber (a new analytics pipeline, say) without touching the code that publishes the event at all.
Architecture decisions should follow from actual organizational and scaling constraints, not from what's currently fashionable. The best architecture is the simplest one that solves the problem you actually have — added complexity should be a deliberate trade for a specific, real benefit, not a default.
Comments