skip to content

A platform team has split a product catalog capability into 12 tiny services (ProductName, ProductPrice, ProductImages, ProductReviews-summary, and so on), each with its own repo, pipeline, and on-call rotation. What's this anti-pattern usually called, what does it cost in practice, and how would you decide the right granularity instead?

level: principalimportance: should knowfreq 45%

answer

  1. nanoservices = split past the value point
  2. granularity test: team-ownable, one reason to change
  3. cost: N pipelines, N on-calls, N network hops
  4. chatty inter-service calls add latency and failure surface
  5. merge back when a split adds no autonomy

basics

~20 s

This is over-decomposition, or 'nanoservices' — splitting so finely that running each piece (deploys, monitoring, network calls) costs more than the benefit. Right size is roughly 'one team, one business capability,' not 'one service per field.'

solid answer

~50 s

This is the nanoservices anti-pattern: decomposition taken past the point where the operational cost of each additional service (its own pipeline, monitoring, on-call, network hop, versioning surface) exceeds the benefit of splitting it out. Twelve services for one product-catalog capability means most 'business changes' — like updating how a product page renders — now require coordinating calls across several of them, plus twelve times the deployment and observability overhead of one right-sized service. The right granularity test isn't a target service count; it's whether a boundary reduces coupling and lets a team ship independently, versus whether it just adds a network hop with no autonomy gained. A good heuristic: a service should be ownable end-to-end by one small team, should change for one clear business reason, and splitting it further should trade off against the real cost of an extra deployable, not be pursued as an end in itself.

go deeper

for a junior

Should be able to recognize that having many tiny services isn't automatically good and give one cost, such as more things to deploy and monitor.

for a middle

Should list two or three concrete costs of over-decomposition, such as network hops, pipeline overhead, or on-call burden, when shown an example.

for a senior

Should apply a granularity heuristic to a real scenario and recommend which services to merge, with reasoning tied to coupling and change frequency.

for a principal

Should set org-wide granularity guardrails, such as a lightweight review gate before creating a new service, weigh team cognitive-load limits against technical decomposition purity, and plan a safe consolidation path for an already over-decomposed system.

## What nanoservices means **Nanoservices** is the name commonly given to the failure mode where decomposition is carried past the point of diminishing, or negative, returns: services are split so finely — sometimes down to a single field, a single CRUD operation, or a single narrow calculation — that the fixed operational cost of running each one as an independent deployable exceeds whatever coupling-reduction benefit the split was supposed to buy. The twelve-service product catalog in the scenario is a textbook case: these pieces of data almost certainly change for the same business reasons, at the same time, are read together on nearly every request, and don't represent independent business capabilities in any meaningful sense — they're fields of one entity that have been mistaken for services. ## What it costs The mechanism by which this becomes expensive is straightforward to enumerate, and the cost is not abstract. Each of the twelve services needs: - its own `CI/CD` pipeline; - its own set of dashboards and alerts; - its own dependency-upgrade cadence; - its own versioned API contract; - and typically its own on-call rotation slot even if it's folded into a shared one — none of which is free even when heavily automated with templates. Beyond fixed cost per service, there's a multiplicative cost in how they interact: rendering a single product page now requires the caller, or an aggregation layer built specifically to work around this, to fan out to several of these services and stitch the results together, adding network round trips, more places for partial failure, and more surface for distributed-tracing complexity when something goes wrong. None of this exists because splitting inherently helps; it exists because the team applied **'single responsibility' at the wrong altitude** — to individual fields rather than to a business capability. ## The trade-off runs the other way The trade-off runs the opposite direction from most decomposition discussions, which usually warn against services being too coarse. Here, the risk is applying decomposition as an unconditional good — believing that smaller is always more modular, more testable, more scalable — without weighing that against the very real fixed and marginal costs above. The correct heuristic isn't a target service count or line-of-code threshold; it's asking, for each candidate boundary, whether the split earns independent deployability and ownership for a genuinely distinct business reason to change. A useful practical test, echoing both **Conway's Law** and the **'two-pizza team'** heuristic popularized in service-oriented architecture at scale, is whether one small team could own the proposed service end-to-end, on its own release cadence, without needing sign-off or coordination from whoever owns its neighbors — if the honest answer is that it would always be deployed and reasoned about alongside its neighbor anyway, the split isn't earning its cost and the pieces should be merged. ## The organizational dimension There's also an organizational dimension distinct from the purely technical coupling argument: every additional independently-evolving service adds to what's sometimes called a team's **cognitive load** — the number of distinct failure modes, deployment pipelines, dependency trees, and monitoring dashboards a small group of engineers has to keep a working mental model of. Even services that are technically decoupled from each other can collectively overload the team responsible for all of them, which argues for consolidating ownership, and often the deployables themselves, well before any single pairwise coupling analysis would flag a problem. ## Recovering from an over-decomposed system Recovering from an already over-decomposed system is itself a migration project, not a single merge commit, and the safest approach mirrors the strangler fig pattern in reverse: 1. pick the two or three most tightly-coupled, most chatty services first, often the ones causing the most on-call pain; 2. build a single consolidated replacement behind the same facade the callers already use; 3. migrate their data and traffic incrementally while both old and new versions run side by side; 4. and only then retire the old services — rather than attempting to merge all twelve into one deployable in a single risky release. A widely reported lesson from companies that adopted microservices early and aggressively is consolidating dozens of very fine-grained services back into a smaller number of coarser ones once the operational overhead of running, and paging for, that many independent deployables was found to outweigh the flexibility gained, without abandoning service-oriented boundaries altogether — the takeaway being that **capability-sized services, not field-sized ones, is where the real benefit of microservices decomposition lives**.

  • What's a concrete heuristic for deciding whether to split a service further?
    Ask whether the split gives a team the ability to change and deploy that piece for a reason distinct from its neighbors, and whether one small team can own it end-to-end without needing another team's sign-off. If the answer is 'it would always change alongside its neighbor anyway' or 'no single team would want to own just this piece,' the split doesn't earn its operational cost and should be merged.
  • How does organizational cost, like on-call and cognitive load, factor into granularity decisions, separate from technical coupling?
    Every additional service is a unit someone has to be paged for, monitor, patch, and understand the failure modes of — often called a team's cognitive load budget. Even if two services are technically decoupled, if the same small team ends up owning both plus eight others, the sheer number of independently-evolving moving parts can exceed what that team can safely reason about, which argues for consolidating ownership even without merging the deployables outright.
  • If you inherit an over-decomposed system like the 12-service product catalog, how do you approach consolidating it without a risky big-bang merge?
    Apply the reverse of the strangler fig pattern: pick the two or three services with the tightest coupling and highest chattiness first, route their traffic through a single new consolidated service behind the same facade, migrate their data and logic incrementally with both versions running, then retire the old ones — validating at each step rather than merging all twelve into one deploy at once.

Like breaking a car's engine into a separate 'spark plug department,' 'piston department,' and 'valve department,' each with its own supply chain, inspector, and shipping schedule — technically more modular, but now assembling one engine requires coordinating a dozen supply chains for something that only ever changes and ships as a unit.

saying these in an interview costs you the question

  • Treats 'more services' as inherently better regardless of team size or coupling
  • Cannot name a concrete cost of extra services beyond vague 'complexity'
  • Recommends splitting further as a default response to any perceived coupling, without weighing operational overhead
  • No mention of team ownership or cognitive load as a factor in granularity, only technical factors

context