mcpbeat Sign in

Service Decomposition Agent Skill

This skill should be used when the user asks "monolith vs microservices", how to "split into services", set "service boundaries", find the right "service granularity", design an "API gateway / BFF", do "service discovery" or add a "service mesh", or worries that services are "too chatty" / "too fine-grained" — including when a team is pushed to adopt microservices or Kafka between services "to be ready to scale" and the right answer may be a modular monolith. It gives the recipe for carving a system into services (or deciding not to) and wiring how they find and call each other. Use it whenever a design has more than one service — or someone is tempted to add more — even if the user doesn't say "microservices".

2.8k tokens
context cost
SKILL.md, read when the skill is used
6
files
plus reference files
0
copies elsewhere
how many repositories repackaged it
109
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/proyecto26/system-design-skills --skill service-decomposition

What comes with it

9 991 bytes besides the instruction
references/deep-dive.md
references/providers/aws.md
references/providers/azure.md
references/providers/gcp.md
references/providers/generic.md

The instruction itself

15 sections, as written by the author

Service Decomposition

Decide how to carve a system into deployable services — or whether to — and how

those services find and call each other. This is the "application layer" of a

design: it sits between the edge (dns/load-balancing/content-delivery) and

the data tier. Getting the *granularity* wrong is one of the most expensive

mistakes in distributed systems, in both directions.

> The trap cuts both ways. One giant service can't scale teams or components

> independently; a swarm of tiny ones drowns you in network hops, partial

> failures, and undebuggable cross-service traces. The skill is finding the

> sweet spot for *this* system at *this* size — not maximizing service count.

When to reach for this

A second service is on the table; teams need to deploy independently; one part has

a wildly different scaling profile than the rest; or an existing system is "too

chatty" / hard to change. Also when someone proposes "microservices" by default.

When NOT to

A new product / small team / unproven domain — start with a monolith (or a

modular monolith) and split later when a real seam and a real reason appear.

Splitting prematurely buys distributed-systems cost (network failure, eventual

consistency, ops) to solve a problem you don't have yet (YAGNI, GUIDE #7). Don't

add a gateway/mesh/discovery layer before you have services that need them.

Clarify first

  • Team & deploy independence — must parts ship on separate cadences/owners?
  • Differential scale — does one component need 100× the others' resources?
  • Coupling — which parts change together (belong together) vs evolve apart?
  • Latency budget — how many in-process calls would become network hops?
  • Consistency across the seam — can the split tolerate eventual consistency

between services? (→ consistency-coordination)

The options

  • Monolith — one deployable. Use when: new/small, fast iteration, strong

cross-module transactions, one team.

  • Modular monolith — one deployable, enforced internal module boundaries.

Use when: you want clean seams *without* network cost yet — the best default

for "we might split later."

  • Microservices — many small deployables split by business capability /

bounded context. Use when: independent deploy/scale/ownership genuinely pays

for the distributed-systems tax.

  • Comms style — decide only whether a given seam is synchronous (REST/gRPC,

request/response, simple but couples availability) or asynchronous (decoupled

but eventually consistent). This block decides *sync-or-async per seam*; it does

not own the async mechanics — once a seam is async, **invoke

messaging-streaming** for the delivery guarantees, ordering, backpressure, and

DLQ semantics that make it safe. Don't pick async from the one-line "no immediate

answer needed" rule without opening those failure modes. Most systems are a mix.

  • Edge of the service tier — an API gateway / BFF (one front door:

auth, routing, rate limiting, aggregation) vs direct exposure.

  • Finding each other — service discovery (registry: DNS-based, or

etcd/Consul/ZooKeeper) and optionally a service mesh (sidecars for mTLS,

retries, traffic shaping) vs library-level clients.

Trade-offs

| Option | What it solves | What it worsens | Change it when |

|---|---|---|---|

| Monolith | Simplicity; in-process calls; easy transactions/debugging | Couples deploy/scale; one team bottleneck; blast radius | Teams/scale profiles diverge → modular monolith → split a seam |

| Modular monolith | Clean boundaries, no network cost, split-later optionality | Still one deploy; discipline required to keep modules clean | A module needs independent deploy/scale → extract it to a service |

| Microservices | Independent deploy/scale/ownership per capability | Network failure, eventual consistency, distributed debugging, ops | Coordination/latency cost exceeds the independence benefit → merge |

| Sync comms | Simple mental model, immediate result | Availability couples (caller fails if callee does); latency stacks | A call doesn't need an immediate answer → async (messaging-streaming) |

| API gateway / BFF | One front door for auth/routing/rate-limit/aggregation | A new tier + potential SPOF/bottleneck; can become a mini-monolith | It accretes business logic → push logic back into services |

| Service mesh | Uniform mTLS/retries/observability without app changes | Real operational + latency overhead (sidecars) | A handful of services → a library/gateway is enough |

Behavior under stress

  • Chatty services / fan-out: one user request becomes N synchronous internal

calls; tail latency compounds and a single slow dependency stalls the chain.

*Mitigate:* coarser boundaries, batching, async where an answer isn't needed

now, and circuit breakers (→ resilience-failure).

  • Distributed-transaction pain: a write spanning services can't be one ACID

transaction. *Mitigate:* saga / outbox, or keep the data in one service so

the transaction stays local (→ consistency-coordination).

  • Retry storms across the mesh: naive retries amplify an overload into a

cascade. *Mitigate:* backoff+jitter, budgets, circuit breakers (→ resilience-failure).

  • Debuggability collapse: with no correlation IDs/tracing, a failure that

crosses 6 services is invisible. *Mitigate:* distributed tracing + correlation

IDs from day one (→ observability, distributed-logging).

  • Gateway/discovery as SPOF: if the front door or registry dies, everything

does. *Mitigate:* redundancy, client-side caching of discovery, health checks.

How to apply

  • Clarify the drivers — independent deploy? differential scale? team

ownership? If none are real yet, stop: a (modular) monolith wins.

  • Default to the simplest that fits — monolith → modular monolith →

extract the one seam that has a real reason — not "everything is a service".

  • Cut boundaries by business capability / bounded context, so data and the

logic that owns it stay together (minimizes cross-service transactions).

  • Choose comms per call — sync only when the caller needs an immediate

answer; async otherwise (→ messaging-streaming).

  • Add the front door + discovery only when warranted — gateway/BFF for

auth/routing/aggregation; discovery/mesh when service count makes static

wiring painful.

  • Stress-test the seams — walk chattiness, cross-service transactions, retry

cascades, and tracing before committing.

  • Show the trade-off in the answer — give a `Decision | Solves | Worsens |

Change it when…` table with one row per choice you made here (e.g. the

option, its store, its failure policy); the last column is a concrete trigger

(a number or observable signal). Then name what breaks first.

Dos and don'ts

Do

  • Start with a monolith / modular monolith; split a seam only when a real driver appears.
  • Split by business capability so a service owns its data (keeps transactions local).
  • Give every cross-service call a correlation ID + tracing from the start.
  • Right-size: fewer, well-bounded services beat many tiny chatty ones.

Don't

  • Don't choose microservices by default or for résumé reasons (GUIDE #7).
  • Don't create a service whose write needs another service's data in the same transaction.
  • Don't let the API gateway accrete business logic into a hidden monolith.
  • Don't add a service mesh for a handful of services — the overhead outweighs it.

Numbers that matter

Each sync hop adds a same-datacenter round trip (~0.5 ms) **plus the callee's own

work**. 10 serial hops is only ~5 ms of *network* — the real cost is the compounded

p99/serialization/queueing/retry tail: each hop multiplies the chance of

hitting a slow dependency, so end-to-end p99 degrades far faster than the mean.

Size the call-graph depth and the per-hop p99 (not just the network) before

splitting, with explicit p99 budgets. → back-of-the-envelope.

Interface sketch

A service boundary is a contract: the owned data (which service is the source

of truth for each entity), the API it exposes (→ api-design), and the

events it emits (→ messaging-streaming). Write down "who owns user records,

who owns orders" before drawing service boxes — shared mutable data across a

boundary is the #1 decomposition smell.

Choosing a provider

Default to the generic recipe above. If the user names a cloud, read

references/providers/<provider>.md for the managed gateway / discovery / mesh

mapping, limits, and trade-offs. If no file exists for that provider, the generic

recipe is the answer.

Diagram

To visualize the service tier (gateway → services → their data, with sync vs async

edges and trust boundaries), use the in-plugin architecture-diagram skill.

  • api-design — *pairs with* this: decomposition sets the boundaries, api-design defines each service's contract.
  • messaging-streaming — *pairs with* this for async/event-driven comms between services (the alternative to sync coupling).
  • consistency-coordination — *owns* the cross-service consistency story (saga/2PC) and the coordination theory behind service discovery (leader election, etcd/Consul/ZooKeeper); link there, don't re-teach.
  • resilience-failure — *depends on* this: circuit breakers, timeouts, bulkheads keep a chatty mesh from cascading.
  • observability + distributed-logging — *feed into* this: tracing + correlation IDs are what make a multi-service request debuggable.
  • scaling-evolution — *feeds into* this: extracting a service is a scaling move on the "split a seam" rung.
  • system-design — the orchestrator.

References

  • references/deep-dive.md — bounded contexts & how to find seams, the strangler-fig migration from monolith, gateway vs BFF vs mesh, sync-vs-async decision detail, saga/outbox for cross-service writes, and the granularity anti-patterns (nano-services, distributed monolith, shared database).
  • references/providers/{generic,aws,azure,gcp}.md — gateway / service-discovery / mesh service mappings, limits, and pitfalls per environment.

Other skills for the same job

different authors, same section of the catalogue
Executing Plans
by ZhanlinCui
×5

Use when you have a written implementation plan to execute in a separate session with review checkpoints

542 tokens
Protocolsio Integration
by christophacham
×4

Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.

3.9k tokens
Tailored Resume Generator
by frostant
×4

Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances

3.1k tokens
Excalidraw Diagram Generator
by github
vendor ×3

Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.

5.9k tokens scripts
Expo Dev Client
by openai
vendor ×3

Build and distribute Expo development clients locally or via TestFlight

878 tokens
Anndata
by christophacham
×3

Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.

2.8k tokens
Benchling Integration
by christophacham
×3

Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.

3.5k tokens
Biopython
by christophacham
×3

Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.

3.7k tokens

How to use it

Copy the folder

Take proyecto26/service-decomposition from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.