What Is Microservices Architecture?
Microservices is an architecture where a large application is split into small, independently deployable services — each responsible for one domain and communicating over APIs.
Microservices is an architecture where one large application is split into small, independently deployable services. Each service owns a single domain (payments, notifications, users), has its own database and deploy cycle, and talks to the others over APIs.
What microservices actually are
The contrast is the monolith: one codebase, one deployment, one database that handles everything. In a microservices system, the payment service, the notification service, and the user service are separate running programs. Each can be written in a different language, scaled on its own hardware, and released without touching the rest.
The defining traits:
- Independent deployment — a team ships its service without coordinating a global release.
- One domain per service — a service maps to a business capability, not a technical layer.
- Private data — each service owns its database; others reach it through its API, never its tables.
- Communication over the network — typically REST or gRPC for synchronous calls, a message queue (Kafka, RabbitMQ, SQS) for asynchronous events.
How they work together
Because services live in separate processes, calls between them cross the network. That changes how you build:
- A service discovery layer or load balancer routes requests to the right instances.
- An API gateway sits in front, handling auth, rate limiting, and routing for outside clients.
- Distributed tracing (OpenTelemetry, Jaeger) stitches a single user request back together as it hops across services.
- Failures are expected, so you add retries, timeouts, and circuit breakers so one slow service does not stall the rest.
Data consistency is the hard part. With one database per service you lose simple transactions, so cross-service workflows use patterns like the saga (a sequence of local commits with compensating actions if a step fails) and eventual consistency instead of an instant global update.
When to use microservices vs a monolith
| Situation | Better fit |
|---|---|
| Early-stage product / MVP | Monolith |
| Small team (1-5 engineers) | Monolith or modular monolith |
| One part needs to scale very differently (e.g. video processing) | Extract that service |
| Many teams stepping on each other in one release | Microservices |
| Strict isolation or independent uptime per domain | Microservices |
Microservices solve an organizational problem more than a technical one: they let many teams ship in parallel. If you do not have that problem yet, the cost outweighs the benefit.
Common mistakes
- Starting with microservices. A two-person team running eight services spends more time on infrastructure — pipelines, networking, tracing — than on features.
- A shared database. If two services read and write the same tables, you have a distributed monolith: all the operational pain, none of the independence.
- Splitting by technical layer (a "controller service", a "database service") instead of by domain. Every feature then touches every service.
- Ignoring network failure. In a monolith a function call always returns; across the network it can time out, retry, or partially succeed.
The progression that usually works
- Monolith first — ship the MVP as one deployable unit.
- Modular monolith — split the codebase into clear domain modules with enforced boundaries, still one deployment. This captures most of the structure benefit with none of the network cost.
- Extract services — peel off a module into its own service only when a specific part needs independent scaling or its own team.
Serverless functions (Vercel, Cloudflare Workers, AWS Lambda) are a lighter middle ground: independent deployment per function without running and monitoring a full service mesh.
A concrete example
A booking platform might start as a single app. As it grows, the iCal sync engine — which polls external calendars on a schedule and bursts under load — becomes a clear candidate to extract: it scales on its own rhythm and can fail without taking checkout down. The user accounts and billing logic, which change together and rarely need separate scaling, stay in the core. That selective extraction is the practical face of microservices, not splitting everything on day one.
Key takeaways
- Microservices = small, independently deployable, domain-owned services talking over APIs.
- They trade simplicity for independent scaling and parallel team delivery — a worthwhile trade only once you have many teams or sharply different scaling needs.
- Default to a monolith, refactor to a modular monolith, and extract services one at a time when a real constraint appears.
- The most expensive mistake is adopting them too early; the second is sharing a database across services.
Weighing whether to split a service or keep it in the core for your own project? Contact for a quote — pricing depends on scope, and the honest answer for most early products is to stay a monolith longer than you think.