When Execution Exposed the Wrong Decisions
Fast execution revealed flawed architecture assumptions. Pivoting mid-project saved 6 months of wasted work.
[Overview] System Overview
A 12-engineer team planned to migrate from a Rails monolith to 8 microservices. The architecture seemed logical on paper: separate services for users, auth, orders, payments, inventory, shipping, notifications, and analytics.
Three months into execution, the problems became visible. Not strategic problems. Execution problems that revealed strategic mistakes.
[Context] Situation before
The monolith worked but velocity was declining. Features took longer to ship. The team believed microservices would solve coordination problems.
##### The Plan
Extract services one by one. Start with users and auth. Build infrastructure as needed.
[Diagnosis] The real problem
Microservices require operational maturity the team lacked. With 12 engineers managing 8 services, nobody owned anything fully. Engineers spent more time on infrastructure than features.
The real problem was not the monolith. It was unclear module boundaries within the monolith.
Understanding the root cause changed everything.
[Boundaries] Working constraints
Constraints are features, not obstacles. They guide design decisions.
[Decisions] Key tradeoffs
status="rejected" title="Continue microservices migration" description="Finish what was started" reasoning="Sunk cost fallacy. Continuing would make things worse." /> status="chosen" title="Return to modular monolith" description="Keep services as modules with clear boundaries" reasoning="Captured 80% of the benefit at 20% of the complexity." />
[Design] Architecture design
Consolidated back to a single deployable with clear module boundaries. Each module owned its tables and exposed explicit interfaces.
Team Size vs Architecture Decision
Why microservices were premature for a 12-engineer team
execution-exposed-wrong-decisions-architecture
[Approach] Execution model
##### Consolidation
Merged 3 extracted services back into monolith over 4 weeks. Kept module boundaries but removed network overhead.
[Results] Measurable outcomes
##### Velocity
Development velocity increased 3x. Engineers focused on features, not infrastructure.
##### Operations
On-call incidents dropped 70%. Debugging became straightforward.
title="Key improvements achieved:" items={[ "System handles 10x burst load without degradation", "Delivery latency reduced from seconds to milliseconds", "Zero message loss during traffic spikes", "Operational complexity reduced by 60%" ]} />
[Anti-patterns] What could have gone wrong
##### If Continued
18 months later: 8 services, each understaffed, none reliable. Team exhausted from firefighting.
variant="yellow" title="" items={[ "Over-engineering the initial solution", "Ignoring operational constraints during design", "Premature optimization without load testing", "Skipping failure mode analysis" ]} />
[Applicability] Where this pattern applies
##### Good Fit
Teams under 40 engineers. Monoliths where the problem is entanglement, not scale.
Every system is different. Context always matters.