Back to Microservices Fundamentals
Q2Question 2 of 12

What are the common microservices anti-patterns and their fixes?

Key Concepts
  • Over-splitting: too many tiny services before boundaries are clear; fix by starting with a modular monolith.
  • Chatty services: one request triggers many fine-grained network calls; fix with a BFF or aggregation layer.
  • God gateway: business logic stuffed into the API gateway; fix by keeping the gateway limited to cross-cutting concerns.
  • Retry storms: naive retries amplify an outage; fix with exponential backoff, jitter, circuit breakers, and retry budgets.
  • Shared-library coupling: domain code in a common library forces lockstep deploys; fix by sharing contracts not code.
  • No service ownership: no team is accountable; fix with clear single-team ownership (you build it, you run it).
  • Most anti-patterns come from adopting microservices prematurely or partially.

Definition

The common microservices anti-patterns -- over-splitting, chatty services, god gateway, retry storms, shared-library coupling, and no ownership -- each reintroduce the pain microservices should remove, and each has a standard fix.
  • Over-splitting – too many tiny services before boundaries are understood; fix: start with a modular monolith.
  • Chatty services – one request triggers many fine-grained calls; fix: BFF or aggregation layer.
  • God gateway – business logic in the API gateway; fix: keep the gateway thin (auth, rate limiting, routing only).
  • Retry storms – naive retries amplify outages; fix: backoff + jitter + circuit breakers + retry budgets.
  • Shared-library coupling – domain code in a shared library forces lockstep deploys; fix: share contracts, not code.
  • No ownership – nobody maintains the service; fix: you-build-it-you-run-it with service catalog.

National Bank of India trips over the same mistakes repeatedly. Over-splitting is giving every clerk their own office building. Chatty services is the loan desk phoning five other desks instead of getting one combined report. A god gateway is the security guard trying to approve loans himself. Retry storms are a hundred anxious customers all redialing the same busy number. Shared-library coupling is every department re-issuing its entire rulebook for one rule change. No ownership is a department everyone uses but nobody fixes.

Understanding the Concepts

What is over-splitting?

Creating many tiny services before you understand the domain boundaries. Each service adds deployment pipelines, monitoring, and distributed debugging cost.

JAVA
// WRONG: 3 services for what one module could handle
// customer-name-service, customer-email-service, customer-phone-service
// Every feature requires coordinating all three

// CORRECT: start with a modular monolith, extract only when needed
package com.bank.customer; // one module with clear interface
public interface CustomerModule {
    Customer get(String id);
}

What are chatty services?

One user request triggers many fine-grained calls, ballooning latency.

JAVA
// WRONG: mobile app makes 4 separate calls
GET /api/accounts/SAV2001
GET /api/cards/SAV2001
GET /api/rewards/SAV2001
GET /api/offers/SAV2001
// 4 round trips, 4× failure surface

// CORRECT: BFF aggregates into one call
GET /api/dashboard/SAV2001
// BFF calls all 4 services server-side in parallel, returns one payload

What is the god gateway?

Stuffing business logic into the API gateway until it becomes a shared bottleneck.

JAVA
// WRONG: gateway calculates interest, applies loan rules
// → every team must coordinate changes, single point of failure

// CORRECT: gateway handles ONLY cross-cutting concerns
// Auth, rate limiting, routing, TLS → thin and stable

What are retry storms?

Naive retries pile load onto a struggling service, keeping it down.

JAVA
// WRONG: immediate unbounded retries
while (true) { try { call(); break; } catch (Exception e) { /* retry immediately */ } }

// CORRECT: backoff + jitter + circuit breaker + retry budget
long delay = (long)(Math.pow(2, attempt) * 100 + rng.nextInt(100));
Thread.sleep(delay);
if (!circuitBreaker.allowRequest()) throw new CircuitOpenException();
if (!retryBudget.allowRetry()) throw new BudgetExhaustedException();
call();

What is shared-library coupling?

Domain code in a common library forces lockstep deploys.

XML
<!-- WRONG: shared domain model --syn-kw">>
syn-kw"><dependencysyn-kw">>
    syn-kw"><groupIdsyn-kw">>com.banksyn-kw"></groupIdsyn-kw">>
    syn-kw"><artifactIdsyn-kw">>common-domainsyn-kw"></artifactIdsyn-kw">>
syn-kw"></dependencysyn-kw">>

<!-- CORRECT: share only API schemas and event schemas --syn-kw">>
<!-- Each service has its OWN domain model --syn-kw">>

What is no service ownership?

A service nobody maintains rots. Fix: every service is owned by exactly one team (you-build-it-you-run-it).

What ties these together?

  • Most anti-patterns come from adopting microservices prematurely or partially. The disciplined approach:
  • Start simple (modular monolith).
  • Split along real business boundaries only when needed.
  • Keep the gateway thin.
  • Make every remote call resilient.
  • Share contracts, not code.
  • Assign one accountable team per service.
  • Invest in observability to catch chatty paths and retry storms early.

What should a senior engineer know?

  • Microservices are an organizational and operational commitment, not just a technical one.
  • Observability (tracing, metrics) is what lets you detect chatty paths and retry storms early.
  • The mark of seniority is recognizing anti-patterns and fixing them, not just building more services.

Visual Overview

DIAGRAM
  Microservices Anti-Patterns and Fixes

  Over-splitting          → Modular Monolith first
  ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐     ┌──────────────┐
  │ │ │ │ │ │ │ │ │ │  →  │ Monolith     │
  └─┘ └─┘ └─┘ └─┘ └─┘     │ with modules │
  too many services         └──────────────┘

  Chatty Services          → BFF Aggregation
  Client ─→ A              Client ─→ BFF ─→ A,B,C,D
         ─→ B                        (1 call, parallel)
         ─→ C
         ─→ D
  4 round trips             1 round trip

  Retry Storm              → Backoff + Budget
  100 clients × 3 retries  100 clients × budget cap
  = 300 calls (amplify!)   = 110 calls (bounded)

Key Takeaway

The common microservices anti-patterns each reintroduce the very pain microservices should remove. Over-splitting creates too many services before boundaries are clear, so a feature becomes a cross-service coordination project. Chatty services make one request trigger many fine-grained calls, ballooning latency. The god gateway stuffs business logic into the API gateway, making it a shared bottleneck. Retry storms pile naive retries onto a struggling service, amplifying the outage. Shared-library coupling forces lockstep deploys. No ownership lets services rot.

The fixes are standard. Start with a modular monolith and extract only when needed. Aggregate with a BFF so one client call fans out server-side. Keep the gateway thin. Use backoff with jitter, circuit breakers, and retry budgets. Share contracts not code. Assign one accountable team per service.

At National Bank of India, Pankaj fixed a chatty mobile dashboard with a BFF that aggregated account, card, and rewards into one call, and tamed a retry storm with backoff, jitter, a circuit breaker, and a retry budget so a slow rewards service no longer collapsed the dashboard path.

Remember one sentence: the microservices anti-patterns are over-splitting, chatty services, god gateway, retry storms, shared-library coupling, and no ownership, and the fixes are modular monolith first, BFF aggregation, thin gateway, backoff with budgets, contracts not code, and one team per service.

---

Share
Use ← → arrow keys to navigate