Before you write a line of cloud code, you pick a shape — an architecture style. This is Part 1 of the Design for the Cloud series, and it walks through the handful of styles that 95% of cloud systems are built from: N-tier, Web-Queue-Worker, Microservices, Event-Driven, Big Data, and Big Compute. For each: what it is in plain words, when it shines, when it hurts, and how to choose. Get this right and the rest of the series (best practices, antipatterns, design patterns) clicks into place.
An architecture style is a family of designs that share the same basic shape — the same way of splitting a system into parts and connecting them. It's not a specific technology or a diagram of your app. It's the template underneath: "this is an N-tier app," "this is event-driven." Styles are to systems what genres are to music — a starting set of conventions that tell you what to expect.
Why start a cloud series here? Because the style you choose constrains everything after it: how you scale, where failures happen, which antipatterns you're prone to, which design patterns you'll reach for. Pick the wrong style and you'll spend the project fighting it. Pick the right one and the cloud's strengths (elasticity, managed services, cheap horizontal scaling) line up behind you.
This part is deliberately beginner-friendly. No assumed background beyond "I've built a web app." By the end you'll be able to look at a problem and say "that's a Web-Queue-Worker job" or "that needs event-driven" — and know why.
The two questions every style answers
Underneath all the names, an architecture style is really answering two questions:
- How do I split the system into parts? One block? Layers? Many small services? A graph of producers and consumers?
- How do those parts talk? Direct in-process calls? Synchronous HTTP requests? Asynchronous messages on a queue or event bus?
The answers trade off the same handful of properties, and there's no free lunch — buying one usually costs another:
| Property | What it means |
|---|---|
| Simplicity | How easy it is to build, understand, deploy, and debug. |
| Scalability | How easily you can grow to handle more load — and scale parts independently. |
| Independence | Can teams build, deploy, and fail in isolation without coordinating? |
| Resilience | When one part breaks, does the rest survive? |
| Operational cost | How much infrastructure, tooling, and human attention it takes to run. |
Keep these five in mind. Every style below is just a different bet on which ones matter most for your problem.
1. N-tier — the classic layered app
In plain words. Split the app into horizontal tiers, each with one job, stacked on top of each other. The textbook three-tier: a presentation tier (web/UI), a business/logic tier (application code), and a data tier (database). Each tier only talks to the one below it. It's how most apps were built for decades, and it ports straight to the cloud.
Fig 1 — Three-tier: each layer talks only to the one beneath it.
When it shines. Traditional business apps, internal tools, anything where a team already knows this model. It's the simplest style to build and reason about. In the cloud you can scale each tier somewhat independently (add web servers behind a load balancer) and swap in managed databases.
When it hurts. Tiers are coupled — a change in the business tier often ripples up and down. The whole thing usually deploys as one unit, so one team's change waits on everyone's. Synchronous top-to-bottom calls mean a slow database makes the whole request slow. It doesn't scale parts independently the way the cloud rewards.
2. Web-Queue-Worker — the cloud's workhorse
In plain words. Split the app into two roles connected by a queue. The web front end handles user requests quickly and, for anything slow, drops a message on a queue and returns immediately. A separate pool of workers pulls messages off the queue and does the heavy lifting in the background. Front end and workers scale independently.
Fig 2 — The web tier stays responsive; the queue buffers work for independently-scaling workers.
When it shines. Apps with a mix of fast requests and slow background jobs — image/video processing, report generation, sending emails, order fulfillment. The queue acts as a shock absorber: a traffic spike fills the queue instead of crashing the app, and workers drain it at their own pace (this is the Queue-Based Load Leveling pattern, which we'll meet again in Part 5). It's arguably the most useful general-purpose cloud style.
When it hurts. It adds a queue and a second deployable to operate. Work becomes asynchronous, so you need a way to report results back to users ("your report is ready"). For purely synchronous, request-response apps with no heavy work, it's overkill.
3. Microservices — many small, independent services
In plain words. Instead of one app, build many small services, each owning one business capability (catalog, cart, payments, shipping), each with its own data and its own deployment. They talk over the network — usually HTTP/gRPC for synchronous calls, or messages for async. Each can be built by a different team, in a different language, scaled and deployed on its own.
When it shines. Large systems with many teams that need to move independently. The big win is organizational: team A ships payments without waiting for team B's catalog work. You also scale precisely — give the cart service 50 instances and the admin service 2. A failure can be contained to one service if you design for it.
When it hurts. This is the style people adopt too early and regret. You trade in-process function calls for network calls — now every interaction can fail, time out, or be slow (hello, Part 3's antipatterns: Chatty I/O, Retry Storm). Each service owning its own database turns a simple transaction into a distributed-consistency problem (you end up reaching for eventual consistency and sagas). You need service discovery, distributed tracing, API versioning, and a platform team to run it. The operational complexity is large and real — practitioners describe the downside in blunt terms: "excessive YAML, DevOps burnout, cloud bills that look like phone numbers, and systems so distributed nobody knows who owns what."
The missing middle: the modular monolith
There's a third option that the monolith-vs-microservices debate usually skips, and for most teams it's the right answer: the modular monolith. You keep one deployable (one process, one deploy, in-process calls — so no network failures, no distributed transactions, no service mesh) but you enforce strict internal module boundaries: each module owns its data and exposes a clear interface, and modules may not reach into each other's internals. You get most of the organizational clarity of microservices without the operational tax.
The practical guidance that's emerged: for roughly 10–50 developers, a modular monolith gives you structure without distribution complexity; past 50+ developers, the coordination cost starts to justify true microservices. The bonus: clean module boundaries are exactly the seams you'd later split along — so a good modular monolith is also the cheapest path to microservices if you ever genuinely need them.
4. Event-Driven — react to things as they happen
In plain words. Instead of services calling each other directly, components publish events ("order placed," "payment received," "inventory low") to a broker, and other components subscribe to the events they care about. Publishers don't know or care who's listening. It flips the flow of control: things happen, and interested parties react, independently and asynchronously.
Fig 3 — One event, many independent reactions. The producer doesn't know the consumers exist.
When it shines. Systems where many things need to react to the same occurrence, where you want extreme decoupling, or where you process high-volume streams (IoT telemetry, clicks, logs, financial ticks). Adding a new reaction is just adding a new subscriber — no change to the producer. It scales beautifully and absorbs spikes.
When it hurts. The flow is implicit and hard to follow — there's no single place that says "when an order is placed, these five things happen." Debugging "why didn't the email send?" means tracing across a broker. You get eventual consistency (reactions happen slightly later), which some domains can't tolerate. Ordering and exactly-once delivery are genuinely hard problems.
5. Big Data — divide the data, conquer in parallel
In plain words. When the dataset is too big for one machine, split the data into partitions and process them in parallel across many machines, then combine the results. This is the world of data lakes, batch pipelines, and stream processing — the style behind analytics, ETL, and training data prep.
When it shines. Datasets measured in terabytes or petabytes; analytical workloads (aggregations, transformations, ML feature pipelines) rather than per-user transactions. Two sub-flavours: batch (process a big bounded dataset on a schedule) and streaming (process an unbounded flow continuously, in near-real-time).
When it hurts. It's a specialised style for data, not for serving an app's requests. The tooling (Spark, data warehouses, stream processors) is its own discipline, and partition/skew problems (one partition far bigger than the rest — a cousin of Part 3's Noisy Neighbor) can wreck performance.
6. Big Compute (HPC) — divide the work, conquer in parallel
In plain words. The mirror image of Big Data: here the computation is huge, not the data. Split a massive calculation into many independent tasks, run them across a fleet (sometimes thousands) of machines, and gather the results. Think simulations, rendering, risk modeling, genomics, scientific computing.
When it shines. Embarrassingly-parallel problems — work that breaks cleanly into independent chunks with little need to talk to each other. The cloud is perfect for this: spin up a huge fleet for an hour, run the job, tear it down, pay only for what you used. No data center required.
When it hurts. If the tasks need to coordinate heavily (lots of inter-node communication), you need fast networking and the complexity climbs. It's a niche style — most teams never need it — but when you do, nothing else fits.
How to actually choose
You don't pick a style from a menu in the abstract — you pick it from the problem. A practical decision path:
| If your situation is… | Start with… |
|---|---|
| A standard app, one small team, moderate load | N-tier — simplest thing that works |
| Growing app, ~10–50 devs, want structure not distribution | Modular monolith — the missing middle |
| Mix of fast requests + slow background jobs | Web-Queue-Worker — the cloud default |
| Big system, 50+ devs, teams needing independence | Microservices (often + events) |
| Many things react to the same occurrences; high-volume streams | Event-Driven |
| Terabytes of data to analyze/transform | Big Data |
| Enormous parallel computation | Big Compute |
Three rules that save projects:
- Start simpler than you think you need. You can evolve N-tier → modular monolith → Web-Queue-Worker → microservices as real pressure appears. You cannot easily un-spend the complexity of premature microservices — and as the CNCF data shows, plenty of companies are now paying to undo it.
- If you do migrate, use the strangler fig. Don't rewrite a monolith into microservices in one big bang — that's how rewrites die. Wrap the old system, peel off one capability at a time into a new service, route traffic to it, and let the old code "strangle" away gradually. Low-risk, reversible, and you ship value the whole way.
- Styles mix. Real systems are usually a blend — a microservices system with an event-driven backbone and a Big Data pipeline hanging off the side. The "style" is just the dominant shape.
- Let the constraint pick the style. The hardest requirement — independent team velocity, a 10TB dataset, a spike-heavy workload — usually names the style for you. Optimize for your actual bottleneck, not a hypothetical one.
FAQ
Is a "monolith" an architecture style?
"Monolith" describes deployment (one deployable unit), not a style. An N-tier app is usually a monolith. The opposite of a monolith is microservices. A well-built monolith is a fine choice — the problem is only when one big codebase blocks many teams.
Should a startup just go straight to microservices?
Almost never. Early on you have one small team and a changing product — exactly the case where a monolith/N-tier or Web-Queue-Worker lets you move fastest. Microservices pay off when team count and system size make a single codebase the bottleneck. Adopt them when that pain is real, not before.
Can I combine styles?
Yes — almost everything real does. A common blend: microservices for the core, event-driven messaging between them, Web-Queue-Worker for heavy jobs, and a Big Data pipeline for analytics. Pick the dominant shape per part of the system.
What's the difference between Big Data and Big Compute?
Big Data = the data is too big, so you partition data and process in parallel (analytics, ETL). Big Compute = the computation is too big, so you partition work and run it in parallel (simulations, rendering). One divides data; the other divides work.
Takeaways
- A style is a shape, not a technology. It decides how you split the system and how the parts talk — and that constrains everything downstream.
- There's no best style, only fits. Each trades simplicity, scalability, independence, resilience, and cost differently.
- Web-Queue-Worker is the cloud workhorse. If you learn one style well, learn this — it solves the most common cloud problem (slow work on the request path).
- Microservices are an organizational tool with a technical cost. Adopt for team independence at scale, not for fashion. Beware the distributed monolith.
- Start simple and evolve. You can always add complexity when pressure appears. You can't easily remove it.
Next up — Part 2: Best practices in cloud applications. Now that you know the shapes, we cover the habits that make any of them reliable in the cloud: autoscaling, retries with backoff, transient-fault handling, partitioning, monitoring, and the twelve-factor mindset.
References
- Architecture styles · Azure Architecture Center — the canonical catalog
- Application architecture guide · choosing compute, data stores, and styles
- Microservices · Fowler & Lewis — the definitive intro
- The Microservice Premium · why simple-first is usually right
- CNCF Annual Survey 2025 · the 42% microservices-repatriation figure
- Strangler Fig Application · Fowler — the safe migration path
Extra reads
- Part 3 — Cloud performance antipatterns · the traps each style invites
- The Twelve-Factor App · the best-practices baseline (Part 2)