Microservice Boundaries, Sagas and Resilience Design
Service boundaries scored by coupling, sync vs async per call, saga designs with compensations, and resilience budgets for each hop.
Before & after
Same prompt, same agent — the only difference is the skill.
Decomposing a monolith into microservices is complex and there are many considerations. You'd want to identify service boundaries—natural seams in your business logic. Database strategy is important too—whether each service gets its own database or if they share. Communication between services could be synchronous or asynchronous depending on your needs. You'll need to think about deployment, monitoring, and how services discover each other. Event sourcing or saga patterns might help with consistency. There are definitely trade-offs between independence and operational complexity. What parts of the payment system feel most independent right now?
MONOLITH TO MICROSERVICES: PAYMENT SYSTEM DECOMPOSITION
DOMAIN-DRIVEN DESIGN (Bounded contexts)
Context 1: PAYMENT PROCESSING
→ Responsibility: Charge card, handle PCI compliance
→ API: POST /charges, GET /charges/{id}, POST /charges/{id}/refund
→ Database: payment_db (Stripe keys encrypted)
→ Dependencies: None (single source of truth)
→ Deployment: On-demand, 99.99% SLA
Context 2: BILLING & INVOICING
→ Responsibility: Calculate amounts, generate invoices, track payment history
→ API: POST /invoices, GET /invoices/{id}, PUT /invoices/{id}/status
→ Database: billing_db (separate DB, replicated daily from payment service)
→ Dependencies: Subscribes to payment-processed events
→ Deployment: Batch process, handles 10K invoices/day
Context 3: SUBSCRIPTION MANAGEMENT
→ Responsibility: Create plans, manage renewals, handle cancellations
→ API: POST /subscriptions, PUT /subscriptions/{id}, DELETE /subscriptions/{id}
→ Database: subscription_db
→ Dependencies: Publishes subscription.created, subscription.cancelled events
→ Deployment: On-demand, handles scaling during renewal cycles
COMMUNICATION STRATEGY
→ Synchronous (REST): Subscription → Billing (verify amount before charging)
→ Asynchronous (Event sourcing): Payment service publishes payment.succeeded event
→ Billing service subscribes, generates invoice, publishes invoice.created event
→ Audit trail: Every event stored in event-log table with timestamp + metadata
SAGA PATTERN: Subscription Renewal Flow
1. Subscription service triggers renewal (via cron)
2. Publishes: subscription.renewal-started event
3. Billing service: Calculates amount, publishes billing.amount-calculated
4. Payment service: Attempts charge, publishes payment.succeeded OR payment.failed
5. If failed: Subscription service publishes subscription.renewal-failed
6. If succeeded: Subscription service publishes subscription.renewed
→ Compensation: Refund endpoint in payment service (rollback on failure)
DATABASE STRATEGY
→ Payment DB: Postgres (ACID, PCI compliance, encrypted)
→ Billing DB: Read-replica from payment DB (eventual consistency)
→ Subscription DB: Separate Postgres (customer-scoped sharding)
→ Cross-service queries: Use event-log for auditing, not direct DB access
SERVICE MESH (observability)
→ Istio for traffic management
→ Distributed tracing: Every request tagged with correlation_id
→ Alert on: Circuit breaker opens (cascading failures), event lag > 30 seconds
PHASED ROLLOUT
Phase 1 (Weeks 1-2): Deploy payment service independently, dual-write to old + new DB
Phase 2 (Weeks 3-4): Route 20% traffic to new payment service, monitor errors
Phase 3 (Weeks 5-6): Cutover to 100%, keep old monolith running for 2-week rollback window
Phase 4 (Week 7+): Extract billing and subscription services (same pattern)
RISK MITIGATION
→ Cascade failure: Implement bulkheads (timeout 3sec, retry 2x, circuit breaker after 5 failures)
→ Data inconsistency: Ensure idempotency (unique request IDs prevent duplicate charges)
→ Monitoring: Alert if payment-processed lag > 5 minutesAbout this skill
Your monolith split turned into a distributed monolith: one request fans out to five services, a retry storm double-charged customers, and nobody can say which service owns the order status. This skill designs microservices the way experienced distributed-systems engineers do. Boundaries go around invariants and change cadence, not nouns. Every cross-service interaction gets a deliberate sync-or-async decision, a failure mode, and a budget.
What it does
- Checks whether microservices are warranted at all, given team count, deploy pain, and data coupling, and says so when a modular monolith is the better answer
- Draws a context map with one owner per invariant and table, and flags entity services, shared tables, and chatty boundaries
- Classifies each interaction as query, command, or event, picks sync or async, and checks call-chain depth and compound availability
- Specifies sagas step by step: compensations, the pivot transaction, pending states, and orchestration vs choreography
- Sets resilience per hop: deadline budgets, single-layer retries with jitter, idempotency keys, circuit breakers, bulkheads, and the outbox pattern
- Orders extractions strangler-style, including data migration and contract versioning
What you get
A design that fits the question: a single boundary call, a saga spec, or a full context map with an interaction table, saga definitions, resilience budgets, and an extraction order. Assumptions are stated, and risks are named.
Best for
Backend leads and architects splitting a monolith, teams fixing a distributed monolith, and engineers designing cross-service workflows such as checkout, booking, or provisioning.
SKILL.md preview
---
name: microservice-boundaries-sagas-resilience
… (sign up to view the full skill)More development skills
View all Development skills →Production Go: Concurrency, Services & Profiling
Production Go code with leak-free goroutines, context-correct services, wrapped errors, and pprof-driven performance fixes.
Backend Feature Build Plan
Builds one backend feature through gates: confirmed requirements, one-screen design, small tested slices, and a deploy/rollback handoff.
Consistent, Safe Application Logging
Adds structured, correlated logs with useful severity, safe fields, bounded volume, and targeted verification.
Reliable WebSocket Messaging and Scaling
Build WebSocket and Socket.IO systems with authorized rooms, reconnect recovery, bounded queues, and multi-node presence.