CtrlK
BlogDocsLog inGet started
Tessl Logo

microservices-vs-monolith

Invalid
This skill can't be scored yet
Validation errors are blocking scoring. Review and fix them to unlock Quality, Impact and Security scores. See what needs fixing →
SKILL.md
Quality
Evals
Security

Microservices vs. Monolith Skill

Purpose

Make a rigorous, context-driven recommendation on system decomposition — preventing both premature microservices and monoliths that can't scale.


The Honest Default

Start with a monolith. Move to services only when you have a specific, demonstrated reason.

Most teams that start with microservices regret it. Most teams that start with a well-structured monolith and extract services when needed succeed. This is not a controversial opinion — it is the consensus of experienced architects.


Step 1 — Evaluate Against These 8 Signals

Score each signal: For microservices (+1) or For monolith (0)

SignalQuestionThreshold for microservices
Team sizeHow many engineers?>50 engineers, multiple autonomous teams
Deploy frequencyHow often do parts need independent releases?Different subsystems deploy >2x/day independently
Scale asymmetryDo different parts need radically different scaling?Yes — e.g., checkout 100x traffic vs. admin panel
Tech heterogeneityDo different parts need genuinely different tech?Yes — e.g., ML inference (Python) + OLTP (Go)
Fault isolationMust one part failing not affect others?Yes — e.g., payments must stay up if recommendations fail
Org structureDo teams already work independently on different domains?Yes — Conway's Law is real
Data isolationDo different domains have completely separate data?Yes — clean domain boundaries already exist
Current painIs the monolith actively causing problems?Build time >15min, deploys block teams, scaling is impossible

Score 0–3: Build a monolith
Score 4–5: Build a modular monolith
Score 6–8: Microservices are justified


Step 2 — Architectural Options

Option A: Monolith

A single deployable unit. Everything in one codebase.

When to choose:

  • Early-stage product (PMF not found)
  • Small team (<10 engineers)
  • Domain boundaries not yet clear
  • Speed of iteration is the primary constraint

Structure it well:

src/
├── modules/
│   ├── users/        (self-contained: routes, service, repo)
│   ├── orders/
│   └── payments/
├── shared/           (minimal — only truly shared utilities)
└── main.ts

Keep modules loosely coupled internally — this makes future extraction easy.


Option B: Modular Monolith ← Often the best choice

A single deployable unit with enforced module boundaries. No cross-module direct calls — modules communicate through defined interfaces.

Benefits over a pure monolith:

  • Can extract a module to a service later with minimal refactoring
  • Teams can own modules independently
  • No distributed systems complexity

Benefits over microservices:

  • One deployment, one database, no network calls between modules
  • Much simpler to operate and debug
modules/
├── users/
│   ├── api/          (public interface — only this is callable from outside)
│   ├── internal/     (private — no other module touches this)
│   └── events/       (events this module emits)
├── orders/
└── payments/

Option C: Microservices

Independently deployable services, each with its own data store.

When justified: score ≥ 6 on the signal table above.

Service decomposition principles:

  • One service = one bounded context (Domain-Driven Design)
  • Services own their data — no shared databases
  • Services communicate via: REST/gRPC (sync) or events (async)
  • Each service should be deployable without coordinating with other teams

Avoid these decomposition mistakes:

  • Splitting by technical layer (don't make a "database service")
  • Too-small services (nanoservices) — if it's <500 LOC, it's probably too small
  • Shared databases between services — this defeats the purpose entirely

Step 3 — If Recommending Microservices: Define Service Boundaries

Use Domain-Driven Design to find boundaries:

  1. Identify bounded contexts: what are the core business domains?
  2. Find the seams: where do domains communicate minimally?
  3. Apply the rule: one service per bounded context

Example for e-commerce:

✅ Good boundaries:
  - Order Service (place, track, cancel orders)
  - Inventory Service (stock levels, reservations)  
  - Payment Service (charge, refund, dispute)
  - Notification Service (email, SMS, push)
  - User Service (auth, profile, preferences)

❌ Bad boundaries:
  - "CRUD Service" (technical, not domain)
  - "Database Service" (antipattern)
  - Order + Inventory combined (too coupled)

Step 4 — Communication Pattern

PatternUse forTechnology
Sync request/responseReal-time reads, user-facing queriesREST or gRPC
Async eventsState changes, cross-domain notificationsKafka, SQS, RabbitMQ
Saga patternDistributed transactions across servicesChoreography (events) or Orchestration

Avoid distributed transactions (2PC). Design for eventual consistency where possible.


Output Format

Always produce:

  1. Recommendation with score from the signal table
  2. Chosen pattern (monolith / modular monolith / microservices)
  3. If microservices: service boundary diagram in Mermaid
  4. Migration path if starting from an existing system
  5. When to revisit this decision

Warning Signs You've Made the Wrong Choice

Wrong to use microservices if:

  • You're sharing a database between services
  • Services are constantly calling each other synchronously (distributed monolith)
  • You have one small team managing all services
  • Debugging requires tracing across 5+ services for simple bugs

Wrong to stay monolith if:

  • Deploys block multiple teams daily
  • One slow service degrades the entire system under load
  • The codebase takes >20 minutes to build/test
  • Teams are stepping on each other constantly
Repository
achreftlili/deep-dev-skills
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.