Microservice Granularity Optimizer
by @quochungto
Right-size microservice boundaries using granularity disintegrators (forces to split: service scope, code volatility, scalability, fault tolerance, security,...
Scenario: Over-split order processing system Trigger: "We split our Order service into OrderCreation, OrderValidation, OrderPricing, OrderFulfillment, and OrderNotification. Now placing a single order requires 5 synchronous calls in sequence, latency tripled, and we need distributed transactions between OrderCreation and OrderPricing. How do we fix this?" Process: Applied disintegrator analysis to each sub-service. Only OrderNotification had independent scalability needs (disintegrator: scalability). All others shared the same code volatility, security level, and fault tolerance requirements. Applied integrator analysis: OrderCreation + OrderPricing had strong database transaction integrator (pricing must be atomic with order creation). OrderCreation + OrderValidation + OrderFulfillment had strong workflow coupling integrator (always called in sequence, never independently). Recommendation: merge OrderCreation, OrderValidation, OrderPricing, and OrderFulfillment back into a single OrderService. Keep OrderNotification separate (different scalability profile, can be async, fault tolerant to delays). Output: Reduced from 5 services to 2 (OrderService + NotificationService). Eliminated 4 synchronous inter-service calls per order. Eliminated distributed transaction between creation and pricing (now a single ACID transaction). OrderNotification communicates via async events (choreography). Latency dropped by ~60%.
Scenario: Monolith decomposition with mixed granularity needs Trigger: "We have a monolithic e-commerce application. We want to move to microservices. The system handles: product catalog, search, user accounts, shopping cart, order processing, payment, inventory management, shipping, reviews, and analytics." Process: Applied disintegrators systematically. Product Catalog and Search have different scalability needs (search gets 100x more traffic) -- split. Payment has unique security requirements (PCI compliance) -- split. Analytics has different code volatility (changes daily vs monthly for core) -- split. Reviews and Ratings are extensible independently -- split. Applied integrators: Order Processing + Payment have a strong transaction integrator (payment must be atomic with order), but the security disintegrator for Payment is stronger -- keep separate, use orchestrated saga. Shopping Cart + Order Processing have weak integrator (cart is pre-order, separate lifecycle). Inventory + Shipping have moderate data relationship integrator but different scalability needs. Output: 8 services: ProductCatalog, Search, UserAccounts, ShoppingCart, OrderProcessing, Payment, InventoryShipping (merged due to data integrator), ReviewsRatings, Analytics. One saga pattern for Order-Payment. Choreography for most communication; orchestration for the order placement workflow (OrderProcessing orchestrates Payment and InventoryShipping).
Scenario: Distributed transaction redesign Trigger: "We're designing a new e-commerce platform with microservices. When a customer places an order, we need to: reserve inventory, charge payment, and create a shipment. If payment fails after inventory is reserved, we need to release it. How do we handle this?" Process: First evaluated whether these truly need to be separate services (integrator analysis). Inventory and Shipping have different scalability needs (inventory checks happen at browse-time too, not just checkout). Payment has PCI security isolation requirements. These disintegrators justify keeping them separate despite the transaction integrator. Designed an orchestrated saga: OrderService acts as the saga mediator. Step 1: Reserve inventory (do: reserve, undo: release). Step 2: Charge payment (do: charge, undo: refund). Step 3: Create shipment (do: create, undo: cancel). If Step 2 fails, OrderService calls inventory.release(). Each service enters "pending" state until the saga completes. Chose orchestration over choreography because the error handling for compensating transactions is too complex to distribute. Output: Orchestrated saga with 3 participants. OrderService mediates. Each service implements do/undo operations. Pending state tracked in OrderService database. Explicit error handling: if undo itself fails, alert + manual resolution queue. Warning noted: if more than ~30% of workflows need sagas, the granularity should be reconsidered.
clawhub install bookforge-microservice-granularity-optimizer