The architectural culture war is finally exhausting itself. After a decade of conference stages screaming “microservices or death”, senior engineers are quietly converging on what one .NET architect calls a “Golden Stack” of pragmatism. The new consensus? Start with a modular monolith, extract services only when the evidence demands it, and admit that microservices are primarily an organizational tool, not a technical panacea.
This isn’t just another pendulum swing. The data suggests something more fundamental: we’ve reached what some call “Peak Backend Architecture”, where the core principles might actually stabilize for the next decade.
The Distribution Tax Nobody Talks About
The most compelling argument against premature microservice extraction comes from engineers who’ve paid the “Distribution Tax” in production. One architect who migrated a Frankenstein AWS serverless app back to a monolith described it as “months just to understand what the heck was going on. Lambdas calling lambdas, Rube Goldberg would be proud.”
The tax breakdown is brutal:
– Outbox Pattern for eventual consistency
– Circuit breakers, retries, and strict idempotency across network boundaries
– Observability infrastructure that becomes a full-time job
– Contract testing (Pact or similar) to prevent integration surprises
– Anti-corruption layers to translate between evolving models
Contrast this with the modular monolith approach: refactoring a boundary inside a single process is an IDE shortcut. Refactoring across services is a cross-team nightmare involving versioning, deployment coordination, and rollback strategies. As one commenter put it, “The moment you extract, you must implement the Outbox Pattern to maintain consistency, alongside resiliency patterns and strict idempotency.”
The Vertical Scaling Ceiling Has Skyrocketed
Here’s the hardware reality that’s making monoliths viable again: modern compute instances can be outfitted with four top-end EPYC CPUs and 2TB of ECC memory, running 1,536 concurrent threads that theoretically share the same process address space. That’s no context switching overhead, no TLB thrashing, no network latency between services.
One engineer who bought into the serverless hype now runs a Go API on a single beefy machine: “My implementation stays simple because it’s a single process, yet it scales to incredible levels with threading and a massively multi-core machine. You don’t start with the max provisioned machine, you start cheap and scale up.”
This isn’t theoretical. NVIDIA is now telling us a whole row in a datacenter “behaves like a single GPU.” The vertical scaling ceiling is so high that many applications can serve millions of users before hitting hardware limits. And when you do need to scale horizontally? Load balance replicas of the same monolith. It’s dramatically simpler than distributed tracing across 50 microservices.
The Pragmatic Migration Path: Monolith → Modular Monolith → Selective Extraction
The DEV Community article that went viral last week outlines the only migration pattern that actually works in practice:
src/
Catalog/
Domain/
Application/
Infrastructure/
UI/
Orders/
Domain/
Application/
Infrastructure/
UI/
Shared/
This structure enforces boundaries in process first. Each module’s Domain cannot directly import another module’s Domain objects. Cross-module calls go through small, well-documented interfaces. Integration tests prove the API at compile-time, not at 3am in production.
The timeline is deliberately slow:
– Months 0-2: Map domains and identify high-velocity modules
– Months 2-6: Reorganize code, add interfaces, write module tests
– Months 6-8: Extract one small, well-bounded module (auth is common)
– Months 9-12: Tackle additional extractions only where data/scale justify it
– Month 13+: Most modules stay in the monolith
This is a marathon, not a sprint. The work you do while still in a monolith saves enormous refactoring cost later.
When Microservices Actually Make Sense
The Reddit discussion crystallized a truth many were hesitant to admit: Microservices are primarily a social fix for Conway’s Law. They solve the “too many cooks in the kitchen” problem, allowing teams to work independently. They’re a solution to human scaling, not necessarily technical performance.
Extraction makes sense when:
– Team size exceeds ~30 engineers and coordination costs explode
– You need different scaling profiles (CPU-intensive ML models vs. I/O-bound APIs)
– Compliance mandates data isolation
– A module requires a fundamentally different tech stack
Amazon’s payments API remains a monolith because it doesn’t hit these triggers. Meanwhile, teams are rethinking architectural patterns and modular design philosophy as they realize most of their 2,000-pattern architecture catalogs are just five shapes in a trench coat.
The 10-Year Cycle and Why This Time Might Be Different
One veteran engineer noted that architecture trends ebb and flow every decade: “Currently monolith is on top, in a few years microservices will come back rebranded as something else (see SOA). The worst part of this industry is that no one studies the past.”
But this cycle feels different. The convergence on a “Golden Stack”, PostgreSQL for data, Redis for caching, OpenTelemetry for observability, Hexagonal/Clean Architecture for structure, suggests genuine maturation rather than fashion.
We’re seeing similar pragmatism in adjacent fields. The shift from parameter wars to dream cycles in AI architecture shows the same pattern: move past hype cycles to engineering fundamentals. Even universities are questioning monolithic vendor ecosystems in favor of modular sovereignty.
The Internal Structure That Makes It Work
The “Hexagonal” (Ports & Adapters) approach has emerged as the clear winner for keeping modular monoliths maintainable. For complex domains, Clean Architecture and DDD provide the necessary discipline:
// src/Catalog/Domain/ProductRepository.php
interface ProductRepository
{
public function findById(ProductId $id): ?Product;
public function save(Product $product): void;
}
// src/Catalog/Domain/Product.php
class Product
{
public function reserve(int $quantity): void
{
if ($this->stock < $quantity) {
throw new
DomainException('Insufficient stock');
}
$this->stock -= $quantity;
}
}
The rules are strict: one module’s Domain never uses another module’s Domain objects directly. This creates honest modules where the coupling cost is visible and cheap to fix.
When to Stop: Modular Monolith as Destination
The most controversial idea is that the modular monolith is a valid destination, not a stepping stone. If your team is under ~30 engineers, can deploy frequently, and doesn’t have wildly different scaling requirements, stay modular.
This challenges the entire microservices industrial complex. Cloud providers have been incentivized to sell you on complexity, serverless, managed Kubernetes, service meshes, because that’s their revenue model. But teams are building better data stacks on Kubernetes after escaping monolithic platforms, and dbt’s platform ambitions are rewriting the data stack with modular alternatives.
The math is stark: extraction costs you network latency, operational overhead, and cognitive load. For most applications, that cost exceeds any theoretical benefit until you hit organizational scaling limits.
The Backend Architecture Maturity Checklist
Before you extract a single service, verify:
– [ ] Clear domain boundaries agreed with product/SEs
– [ ] Public interface documented and covered with contract tests
– [ ] Metric coverage for consumer and provider
– [ ] Feature flags and shadow traffic in place
– [ ] Runbooks and escalation paths for the new service
– [ ] Data ownership plan (migration/dual-write/cutover)
– [ ] Rollback and retry strategies defined
If any item is missing, postpone extraction and invest in the monolith refactor. This is the opposite of the “move fast and break things” mentality that created microservice disasters.
Peak Architecture or Just Another Cycle?
The question remains: is this genuine maturity or just another turn of the wheel? The evidence suggests something deeper. When even Meta is running servers on Steam Deck scheduler code for pragmatic efficiency, and when SOLID principles are being re-examined for microservices betrayal, we’re seeing a systemic shift toward engineering fundamentals over hype.
The “modern standard” is less about technological superiority and more about admitting the true costs of distribution. We’ve finally quantified the Distribution Tax, and for most teams, it’s not worth paying until they have organizational scaling problems that code can’t solve.
This doesn’t mean microservices are dead. It means they’re a specialized tool for a specific problem, team autonomy at scale, not a default architecture for every new project. The modular monolith is back, and this time it’s armed with better patterns, better hardware, and a healthy skepticism of complexity for its own sake.
The backend architecture wars aren’t over. But the terms of engagement have permanently changed.





