
Study software development long enough and the buzzwords never stop coming. Monolith, Microservices, Hexagonal, DDD, CQRS, Event Sourcing, Serverless, Service Mesh… One person tells you "everything is microservices now," and the next tells you "I heard Amazon went back to a monolith."
Here's the short answer: there is no right pattern. Every pattern is an answer to a specific problem of its era, and each new one is born on top of the limits of the one before it. So what you should be looking at isn't what's newest — it's why it exists.
Four Pressures That Drive Patterns Forward#
New patterns don't appear because they look cooler. Four pressures are always at work at the same time.
Hardware and Infrastructure Change#
Back when servers were expensive, you had no choice but to cram everything onto a single machine. Then the cloud arrived and servers became disposable. Containers and Kubernetes became the norm, and the cost of deploying dropped to nearly zero.
What becomes possible soon becomes expected. Whatever the infrastructure makes feasible, somebody eventually tries — and that's how a pattern is born.
Organizational Scale (Conway's Law)#
In 1968, Melvin Conway wrote this:
"Organizations design systems that mirror their own communication structure."
A system built by a team of 5 can never look like a system built by a company of 500. Five people can work in one codebase without stepping on each other. Five hundred can't. Microservices is an organizational decision before it's a technical one.
The Previous Pattern's Weak Spots Surface#
New patterns are always born at the exact point where the previous one breaks under scale.
Monolith
→ (deploys become terrifying)
→ Microservices
→ (inter-service communication hell)
→ Service Mesh, Event-Driven
→ (distributed transaction problems)
→ Saga, Eventual ConsistencyEvery cure produces a new side effect, and that side effect becomes the starting point for the next pattern.
Business Requirements Change#
Work that used to be fine "as long as it's processed by tomorrow" now has to send a notification "within one second." A product sold only in one country goes global. When the speed and reach of the business change, the system follows.
Walking Through the History, Era by Era#
Look at what problem each era faced and how it solved it, and the whole arc starts to make sense.
1970s–80s: The Procedural Era#
Memory was measured in kilobytes, CPUs in megahertz, and one person wrote the whole program. The question was "how do I build something that works while sparing every resource I can?" The answer was procedural and structured programming.
Code in this era was essentially a list of functions. C is the archetype. "Stop using GOTO and split things into functions" was a major leap forward at the time (Dijkstra's famous "GOTO Considered Harmful," 1968).
1990s: Object Orientation and MVC#
PCs spread, GUIs arrived, and programs kept growing. Once a codebase passes ten thousand lines, functions alone stop being manageable — and adding a UI makes it worse.
The answer was object-oriented programming (OOP) and MVC (Model-View-Controller). OOP is the idea of bundling data together with the behavior that operates on it and calling the result an "object." Smalltalk started it, but Java (1995) took it mainstream. MVC was proposed by Trygve Reenskaug back in 1979, but it only saw real use once GUIs and the web became ubiquitous in the '90s and 2000s.
Early 2000s: Enterprise and Layered Architecture#
After the dot-com bubble, banks, insurers, and large corporations started building web-based systems in earnest. Business logic ballooned, and dozens of developers were touching the same system.
The answer was Layered Architecture (N-tier). Controller → Service → Repository → DB. That structure is still overwhelmingly common today, and Java EE and Spring became the standard.
The other big event of this era was the arrival of DDD (Domain-Driven Design). Eric Evans formalized it with his 2003 book, and the core idea is "put the business domain at the center of your code structure." Concepts like Aggregate and Bounded Context came from here.
DDD gets combined with Layered/Clean Architecture. If Layered is "the shape of the bowl," DDD is the answer to "how do we shape the objects that go inside it."
Mid-to-Late 2000s: The SOA Experiment#
Companies ended up with too many systems. Payments, membership, and product catalogs each ran separately but had to exchange data. The answer was SOA (Service-Oriented Architecture).
SOA is the ancestor of microservices. The difference is that back then, communication went through a heavyweight middleware called an ESB (Enterprise Service Bus). It was so heavy and complex that SOA ended up being remembered as "great in theory, failed in practice." Its spirit survived, though, and came back in a different form in the 2010s.
Early 2010s: Cloud and Microservices#
AWS took hold (EC2 launched in 2006, but it went mainstream in the 2010s), containers showed up (Docker, 2013), and smartphones exploded, multiplying traffic by thousands.
That's when the monolith stopped working. Change one line and you deploy everything. One part dies and the whole thing dies. Teams grew to 100, then 1,000 people, all sharing one codebase — pure misery.
Netflix is the poster child of this shift. After a 2008 datacenter failure took the service down for days, they abandoned the monolith and moved to microservices on AWS. The tools they built along the way (Eureka, Hystrix, Zuul) were open sourced and became industry standards. Amazon got there earlier: Jeff Bezos's famous 2002 "API Mandate" forced every internal system to communicate over APIs, and that eventually led to the birth of AWS.
A few patterns came out of this era as byproducts.
- API Gateway — clients can't be expected to know dozens of microservices, so give them a single entrance
- BFF (Backend For Frontend) — mobile and web need different data, so give each client its own gateway. Netflix and SoundCloud led the way
- Circuit Breaker — when one service dies, cut it off so others don't wait forever. Netflix's Hystrix is the classic example
Mid-2010s: Async and Event-Driven#
As microservices multiplied, the limits of synchronous communication showed. Call A → B → C → D in sequence and the whole chain slows down whenever D is slow. The answer was Event-Driven Architecture, and Kafka.
Kafka (2011), which started at LinkedIn, is the single most important piece of infrastructure from this era. The simple idea of "store events as a log and let anyone subscribe" changed how distributed systems talk to each other.
Several patterns rose alongside it.
- CQRS (Command Query Responsibility Segregation) — separate reads and writes into different models. Useful for systems where read traffic dominates (a Twitter timeline, for example)
- Event Sourcing — store the stream of events instead of the state. Since every change is traceable, it fits domains where auditing matters (banking, insurance)
- Saga Pattern — handle distributed transactions with compensating transactions. If an order fails, cancelling the payment gets triggered automatically
Late 2010s: Containers, Kubernetes, Service Mesh#
Once you have 100 or 1,000 microservices, operational complexity explodes. The answer was Kubernetes (2014, open sourced by Google) and Service Mesh (Istio in 2017, Linkerd, and others).
Kubernetes became the standard for "container orchestration," automatically placing, recovering, and scaling containers scattered across many machines.
Service Mesh goes a step further and handles inter-service communication at the infrastructure level. Retries, authentication, and traffic splitting move out of application code and into a sidecar proxy (Envoy).
Late 2010s–2020s: Serverless#
AWS Lambda (2014) introduced the idea that you don't have to manage servers at all. Keeping a server up 24/7 for spiky workloads — or for a batch job that runs a few times a month — was pure waste.
With Serverless/FaaS (Function as a Service), you deploy at the function level and pay only when it's invoked. It fits event-driven workloads especially well: generate a thumbnail when an image is uploaded, send a notification when a payment comes in. AWS Lambda, Vercel, and Cloudflare Workers are the usual names.
2020s: Reversal and Reappraisal#
This is where it gets interesting. The pendulum is swinging back.
- The return of the Modular Monolith — "before you go microservices, modularize your monolith properly." Shopify is the standout example
- Amazon Prime Video's reversal (2023) — a post about consolidating a microservices-based video monitoring system back into a monolith and cutting costs by 90% made the rounds
- DHH's "Majestic Monolith" (Basecamp/Hey founder) — for a small team, the monolith is the answer
Here's the point: microservices weren't wrong. Applying microservices everywhere was.
The Whole Arc on One Page#
[1970s] Procedural
↓ (programs get bigger)
[1990s] OOP, MVC
↓ (enterprise systems get huge)
[2000s] Layered, DDD, SOA
↓ (cloud and mobile explode)
[2010s] Microservices, Event-Driven, Kubernetes
↓ (operational complexity explodes)
[2020s] Modular Monolith, Serverless, "only as much as you need"Look at each arrow and it's clear. A new pattern shows up not because the old one was inadequate, but because the environment changed. And when the environment changes again, an old pattern comes back wearing new clothes.
Why Companies Choose Differently#
Even within the same era, different companies pick different patterns — because their problems are different.
| Company | Main patterns | Why |
|---|---|---|
| Netflix | Microservices, BFF, Circuit Breaker | Global streaming; resilience is everything |
| Amazon | Microservices (API Mandate), Event-Driven | Enormous org; independent deploys are mandatory |
| Uber | Event-Driven, DDD | Real-time matching, complex domain |
| Kafka-based event streaming | Large-scale data pipelines | |
| Shopify | Modular Monolith | Fast development, clear domain separation |
| Basecamp/Hey | Majestic Monolith | Small team, fast decisions |
| Stack Overflow | Monolith (still!) | Simple domain, cost efficiency |
| Discord | Elixir-based, some Rust microservices | Concurrency, performance hotspots |
Stack Overflow is the one that sticks with me. It's a global top-50 site and it's still a monolith. Not because they've never heard of microservices, but because they judged a monolith to be the better fit for their problem.
How to Approach Patterns#
Ask "Why," Not "What's Newest"#
Don't chase a pattern just because it's new. Ask first what problem it was built to solve. If your system doesn't have that problem, adopting the pattern is over-engineering.
Patterns Are Bundles of Trade-offs#
Every pattern gains you something and costs you something.
- Microservices — independent deploys ↔ distributed-system complexity
- Event-Driven — loose coupling ↔ hard debugging, consistency issues
- CQRS — read performance ↔ code complexity, consistency lag
- Serverless — less operational burden ↔ cold starts, vendor lock-in
There's no free lunch. What you give up to get what you want is always the crux.
Look at the Organization and the Business#
Choosing a technical pattern is always a function of your organization and your business. Pick one without answering these questions and you'll regret it.
- Is your team 5 people or 500?
- Is traffic steady or spiky?
- Is the domain simple CRUD or complex business rules?
- Are you cost-sensitive, or is performance the priority?
Go Incrementally#
Every global company started as a monolith. Amazon, Netflix, Uber — all of them. They moved to microservices only after the pain was real. Of the startups that begin with microservices from day one, 80% get bogged down in infrastructure complexity.
Start with a monolith. Extract services when the pain is real.
So What Should You Study Right Now?#
If you're a backend developer picking a learning order, here's the path I'd suggest.
- Actually build a Layered Architecture — Spring Boot, Django, Express, whatever you like
- Refactor that code into Hexagonal — until dependency inversion clicks in your gut
- Apply a few basic DDD concepts — Aggregate and Value Object are enough to start
- Try event-based communication once — Kafka or RabbitMQ, either works
- Then look at Microservices, CQRS, and Event Sourcing — by then, you'll probably see why they're needed
Everything else can wait until the moment you actually need that pattern. Try to learn it all up front and you'll just accumulate shallow knowledge.
Wrapping Up#
The history of architecture patterns is really the history of one pressure: "we have to build bigger systems, with bigger organizations, faster." Patterns are the answer to that pressure, and when the pressure changes, so does the answer.
So be wary of anyone who tells you "this is the right answer." The right answer only ever exists behind the question "an answer to what?"
Next time you hear a new pattern name, try asking this:
"What problem was this pattern built to solve? Do I have that problem?"
That question is what keeps you from getting lost in the waves of tech trends.
Further Reading#
- Domain-Driven Design — Eric Evans (2003)
- Building Microservices — Sam Newman
- Designing Data-Intensive Applications — Martin Kleppmann
- Martin Fowler's blog — definitions of patterns and their trade-offs
- Software Architecture: The Hard Parts — Neal Ford et al.
- Amazon Prime Video's post on returning to a monolith (2023)
- DHH's "The Majestic Monolith" blog post
It isn't what happens to us that causes us to suffer; it's what we say to ourselves about what happens.
— Pema Chodron


