What is a 'nanoservice' anti-pattern, and why is a service that's too small often worse than a monolith?
answer
- fixed cost per service
- distributed monolith
- SRP misapplied to deployment unit
- capability not verb
- operational tax > logic value
basics
~20 sA 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.
solid answer
~30 sNanoservicing is when a team decomposes past the point where the service still owns a meaningful piece of business capability - e.g., a 'GetUserEmail' service with a single endpoint and no real logic. Every service, regardless of size, carries fixed overhead: its own deployment pipeline, health checks, logging/monitoring setup, network hop with latency and failure modes, versioning, and on-call burden. When the unit of work inside the service is tiny, that overhead dominates the total cost, and you end up with a 'distributed monolith' that's harder to operate than the monolith it replaced, without any of the independent-scaling or fault-isolation benefits.
go deeper
Should recognize that 'more services = better' is false and give the basic intuition that each service has real operational cost, even without naming specific failure modes.
Should name concrete fixed costs (deploy pipeline, monitoring, network hop) and connect nanoservicing to chatty communication and the need for distributed transactions.
Should give a clear heuristic for right-sizing (bounded context / change-together test) and be able to spot nanoservicing in a real service diagram, proposing a concrete merge.
Should discuss how nanoservicing interacts with org design (Conway's Law), cloud cost, and propose a governance mechanism (architecture review, service creation checklist) to prevent it recurring across many teams.
## What nanoservicing is A microservice architecture decomposes a system into independently deployable units, each ideally owning one bounded, cohesive slice of business capability along with its own data store. **Nanoservicing** is what happens when a team pushes this decomposition too far, splitting services along technical lines (a single endpoint, a single database column, a single CRUD verb) rather than along capability lines. A textbook example is splitting a 'User' domain into separate services for `CreateUser`, `UpdateUserEmail`, `UpdateUserAddress`, and `DeleteUser` — each with its own repository, deployment pipeline, and a slice of the same underlying table — when in reality these operations are one cohesive 'manage user profile' capability that a single team owns and that almost always changes together. ## Where it comes from Nanoservicing usually emerges from good intentions taken past their useful range. - The **Single Responsibility Principle**, correctly applied at the class or module level, gets misapplied at the deployment-unit level as 'each service should do exactly one thing,' and 'one thing' gets interpreted as 'one function call' instead of 'one business capability.' - It's also a reaction to **monolith pain** (long build times, tangled ownership, fear of touching shared code) and to **conference-driven development** that equates 'more services' with 'more modern.' - Teams new to microservices often lack a felt sense of the **fixed operational cost** every service carries, so they don't see the tax they're signing up for. ## The fixed overhead every service pays Every service — no matter how small — pays a fixed overhead: - its own **CI/CD pipeline** - its own **container image** and base-image patching - its own **health checks**, dashboards and alerts - its own **on-call runbook** - its own **versioning** and backward-compatibility contract - at least one **network hop** to reach it (with associated latency, timeout tuning, retry policy and circuit breaker) When the unit of business logic inside the service is tiny — one field update — that fixed cost dwarfs the value delivered. You get more services to patch for CVEs, more pipelines to keep green, more dashboards nobody looks at, and a request that used to be one in-process function call becomes a network round trip with its own failure modes. The promised benefits of microservices — independent scaling, independent deployability, fault isolation — rarely materialize at this granularity because these tiny services are so tightly coupled in their data and lifecycle that they must be deployed and reasoned about together anyway; you've paid for distribution without buying the isolation it's supposed to buy. ## Production symptoms - **Chatty inter-service communication** is the most visible production symptom: a single user action (e.g., 'update my profile') now requires the caller (a BFF, gateway, or another service) to orchestrate calls to four or five nanoservices, and if any one call fails partway through, you need compensating logic to undo the ones that already succeeded — essentially hand-rolling a distributed transaction (a saga) for something that used to be one local ACID transaction. - **On-call load spikes because incidents multiply**: an outage in 'UpdateUserEmail' doesn't just break email updates, it breaks every workflow depending on the chain of calls leading to it, and diagnosing this requires distributed tracing across many hops instead of reading one stack trace. - **Deploy coordination gets worse, not better**: because these services are so entangled, changing 'user' behavior often requires touching several nanoservices in lockstep, so the 'independent deployability' that justified splitting them in the first place doesn't hold. ## The corrective heuristic This pattern is documented widely enough to have a name — 'nanoservices' or the 'distributed monolith' antipattern — and practitioner accounts (echoing Sam Newman's writing in 'Building Microservices,' which shaped much of the mainstream vocabulary around service granularity) describe teams merging a dozen single-purpose services back into two or three cohesive services once the operational tax became visible in cloud bills, on-call fatigue, and slowed feature delivery. The corrective heuristic is to size a service around a bounded context or business capability — something that: 1. a small team can own end-to-end 2. changes for one reason 3. is large enough to amortize its fixed operational cost against real business value delivered
- How would you decide whether two candidate services should actually be merged into one?Look at whether they change for the same reason and are usually deployed together - if 90% of changes to service A require a coordinated change to service B, they belong in one deployable unit. Also check data ownership: if they need each other's tables to do their job, that's a strong signal they're one bounded context artificially split. Finally, look at team ownership - if one team maintains both, splitting them buys no organizational independence, only operational cost.
- Does 'one team, one service' mean a team should never own more than one service?No - a single team commonly owns several services if those services represent genuinely separate bounded contexts with different data and change cadences, e.g., a platform team owning both 'notifications' and 'audit-logging.' The rule is about avoiding services so fine-grained that a single business capability is fragmented across owners or coupled at the data layer, not about capping services per team.
- Can nanoservicing ever be the right call?Rarely, but it can make sense for a capability with genuinely independent scaling needs and infrequent, isolated changes - e.g., a thumbnail-generation service invoked by many unrelated systems, which scales on a totally different curve and rarely changes in lockstep with its callers. The key test is whether the isolation buys real operational value that outweighs the fixed cost, not just conceptual purity.
Like splitting a restaurant kitchen into a 'salt station,' 'pepper station,' and 'plate-wiping station' - each hire is real overhead (scheduling, training, a doorway to walk through) for a task that takes two seconds, and now every dish needs five people to hand it down the line instead of one cook finishing the plate.
saying these in an interview costs you the question
- Treats 'small service' as an unconditional goal without weighing operational cost
- Can't explain why a service boundary exists in business terms, only technical ones
- Doesn't mention the fixed cost every service carries (pipeline, monitoring, on-call)
- Proposes a saga/distributed transaction as normal for what is really one aggregate's write
- No mention of chatty communication or cascading failure as a consequence