AlgoInsight

System Design

9 Software Architecture Patterns Every Developer Should Know

Before you design a system, you choose its shape. These nine architectural patterns are the proven shapes - each solving a different problem. Knowing them gives you a vocabulary for every design decision.

By Admin2026-06-1815 min readarchitecture-patternssystem-designmicroservicesevent-drivensoftware-architecturefundamentals

Every software system has a shape - a fundamental way its components are organized and interact. Choosing that shape is one of the earliest and most consequential decisions in building a system, and you don't have to invent it from scratch. Over decades, the industry has converged on a set of proven architectural patterns, each a tried-and-tested way of organizing a system to solve a particular kind of problem.

Knowing these patterns gives you two things: a vocabulary for discussing designs ("this is event-driven," "that's a layered architecture"), and a toolkit of starting points so you're not reinventing structure every time. This guide covers nine architectural patterns every developer should recognize - what each is, how it works, its strengths, and when to reach for it.

graph TD
    AP[Architecture Patterns] --> A[Organize by layers<br/>Layered]
    AP --> B[Split into services<br/>Microservices]
    AP --> C[React to events<br/>Event-Driven]
    AP --> D[Separate UI/logic/data<br/>MVC]
    AP --> E[Core + plugins<br/>Microkernel]
This diagram previews several of the architectural patterns covered: layered architecture organizes a system by layers, microservices split it into independent services, event-driven architecture has components react to events, MVC separates the user interface from logic and data, and the microkernel pattern builds a core with plugins. Each is a different way of organizing a system's shape.

1. Layered (N-Tier) Architecture

The most common and familiar pattern. The system is organized into horizontal layers, each with a specific responsibility, where each layer only talks to the layer directly below it. A typical web application has four layers: presentation (the UI), business logic (the rules), persistence (data access), and database (storage).

How it works: a request flows down through the layers - the UI calls the business logic, which calls the data access layer, which reads from the database - and the response flows back up. Each layer is a clean abstraction over the one below.

Strengths: simple to understand, easy to organize, and the separation of concerns makes the code maintainable. Each layer can be developed and tested somewhat independently.

When to use it: standard business applications, especially when you're starting out. It's the sensible default for many systems and the foundation most developers learn first.

Watch out for: layers can become tightly coupled if not disciplined, and a request passing through every layer can add overhead. It can also become a monolith that's hard to scale piece by piece.


2. Client-Server Architecture

A foundational pattern where the system is split into two roles: clients that request services and servers that provide them. The client handles presentation and user interaction; the server holds the shared data and logic. They communicate over a network.

How it works: clients send requests to a server; the server processes them (often querying a database) and returns responses. One server typically serves many clients.

Strengths: centralizes data and logic (one source of truth), keeps clients lightweight, and allows client and server to be scaled and updated independently.

When to use it: virtually all web and mobile applications use this pattern - it's the backbone of networked software. (We cover it in depth in a dedicated guide on client-server architecture.)

Watch out for: the server can become a bottleneck and a single point of failure, which is why so much of system design focuses on scaling and protecting the server side.


3. Microservices Architecture

The system is broken into many small, independent services, each owning one capability and deployed separately. Instead of one large application, you have a collection of focused services that communicate over the network.

How it works: each service (users, orders, payments) runs independently with its own data and deploy pipeline, and they coordinate via APIs or messaging. An API gateway often sits in front as a unified entry point.

Strengths: services scale and deploy independently, teams work autonomously, failures can be isolated to individual services, and each service can use its own technology.

When to use it: large systems with many teams, where different parts have different scaling needs and you need independent deployment. It shines at scale.

Watch out for: significant complexity - network calls that fail, data consistency across services, and heavy operational overhead. For smaller systems, it's usually over-engineering; a monolith or modular monolith is simpler. (We cover this trade-off in depth in a dedicated guide.)


4. Event-Driven Architecture

Components communicate by producing and reacting to events rather than calling each other directly. When something happens (an event), interested components are notified and respond - without the producer knowing or caring who's listening.

How it works: an event producer emits an event ("order placed") to an event channel (often a message queue or event bus). Event consumers subscribed to that channel receive it and act - one updates inventory, another sends a confirmation, another triggers shipping - all decoupled from the producer.

Strengths: highly decoupled (producers and consumers don't know about each other), scalable, and responsive. Components can be added or removed without changing others, and the system handles bursts gracefully by buffering events.

When to use it: systems with many asynchronous workflows, real-time processing, or where many components need to react to the same events. Common in large, complex systems and increasingly in microservices.

Watch out for: the flow of logic is harder to trace (it's spread across event handlers), and debugging and ensuring consistency across asynchronous events takes care.


5. Model-View-Controller (MVC)

A pattern for organizing applications - especially those with user interfaces - by separating concerns into three parts. The Model holds the data and business logic, the View presents it to the user, and the Controller handles input and coordinates between the two.

How it works: the user interacts with the View, the Controller interprets the input and updates the Model, and the View reflects the Model's state. Each part has a clear, single responsibility.

Strengths: clean separation of data, presentation, and control logic makes applications easier to maintain and test. The View can change without touching the Model, and vice versa.

When to use it: applications with user interfaces, especially web applications - MVC is the basis of countless web frameworks.

Watch out for: for very simple applications, the three-way split can add unnecessary structure, and the boundaries between the parts can blur without discipline.


6. Microkernel (Plugin) Architecture

The system is built as a minimal core that provides essential functionality, with additional features added as plugins that extend the core. The core knows nothing about the specific plugins; it just provides the framework for them to plug into.

How it works: the core handles the fundamental, stable operations, and plugins add specialized or optional features through well-defined extension points. New capabilities are added by writing new plugins, not by modifying the core.

Strengths: highly extensible - you can add features without touching the core - and flexible, since plugins can be developed, added, and removed independently. The core stays small and stable.

When to use it: applications that need to be extensible by design - development tools (IDEs and editors with plugin ecosystems), browsers with extensions, and products that support third-party add-ons.

Watch out for: designing good extension points is hard, and managing many plugins (and their interactions and versions) adds complexity.


7. Pipe-and-Filter Architecture

Data flows through a sequence of processing steps, where each step (a filter) transforms the data and passes it along the pipe to the next. Think of an assembly line: each station does one transformation, then hands the result to the next.

How it works: data enters the pipeline, passes through a series of filters each performing one operation (parse, validate, transform, enrich, store), and emerges processed at the end. Each filter is independent and only knows about its input and output.

Strengths: each filter is simple, reusable, and independently testable. Filters can be rearranged or replaced easily, and the pipeline can often be parallelized.

When to use it: data processing pipelines, compilers, stream processing, ETL (extract-transform-load) workflows - anywhere data flows through a series of transformations.

Watch out for: it's a poor fit for interactive or highly stateful workflows, and passing data between many filters can add overhead.


8. Leader-Follower (Master-Slave) Architecture

One node (the leader) coordinates and makes decisions while other nodes (followers) execute work or hold copies of data. A common pattern in distributed systems, especially for databases.

How it works: the leader handles writes and coordination; followers replicate the leader's data and can serve reads, taking load off the leader. If the leader fails, a follower is promoted to take its place (failover).

Strengths: spreads read load across followers (improving scalability and availability), provides a clear coordination point, and supports failover for resilience.

When to use it: database replication, distributed coordination, and systems where one authoritative node must coordinate others while distributing the workload.

Watch out for: the leader can be a bottleneck and a single point of failure (mitigated by failover), and keeping followers in sync raises consistency questions - followers may lag behind the leader.


9. Serverless Architecture

The application is built from functions that run on demand, with the cloud provider managing all the servers and infrastructure. You write the logic; the provider handles when and where it runs, scaling it automatically and charging only for actual execution.

How it works: small functions are triggered by events (an HTTP request, a file upload, a queue message), spin up to handle the work, and shut down when done. There are no servers for you to provision or manage - the infrastructure is abstracted away entirely.

Strengths: no server management, automatic scaling (including to zero when idle), and you pay only for what you use. Excellent for variable or unpredictable workloads.

When to use it: event-driven workloads, APIs with variable traffic, scheduled tasks, and applications where you'd rather not manage infrastructure. Great for startups and for spiky workloads.

Watch out for: "cold starts" (a delay when a function spins up after being idle), less control over the environment, potential vendor lock-in, and challenges with long-running or stateful operations.


Architecture patterns vs design patterns

A point of clarity worth making: architecture patterns are different from design patterns, though the terms sound similar. Architecture patterns (the ones in this guide) describe the high-level structure of an entire system - how its major components are organized. Design patterns (like Singleton, Factory, Observer) operate at a much smaller scale - reusable solutions to common problems within the code, at the level of classes and objects. A useful way to hold the difference: architecture patterns shape the building; design patterns shape the rooms inside it. Both are valuable, but they operate at different levels - "architecture" means the system's overall shape; "design pattern" means a code-level technique.

How architecture evolves as systems grow

Architecture isn't chosen once and frozen - it evolves. A common trajectory: a system starts as a simple layered monolith because that's fast to build and easy to understand. As it grows and the team expands, parts are extracted into microservices to allow independent scaling and deployment. Event-driven messaging is introduced to decouple those services. Specific workloads might move to serverless functions. The architecture shifts as the system's needs change, often combining several patterns at once.

This is why understanding multiple patterns matters: you're not picking one for life, you're choosing the right shape for where the system is now, and evolving it as requirements change. Reaching for microservices on day one (before you need them) is as much a mistake as clinging to a monolith long after it's strangling a large team. The skill is matching the architecture to the current reality and knowing how to evolve it.

Common pattern mistakes

A few traps worth avoiding when working with these patterns:

The throughline is that patterns are tools with trade-offs, not silver bullets. The right one depends on the problem, the scale, and the team - and the best architectures are deliberate combinations, evolved over time.


How to choose

These patterns aren't mutually exclusive - real systems often combine several. A system might use microservices (overall structure), with each service internally layered (organization), communicating through event-driven messaging (coordination), with some parts running serverless (specific workloads). The patterns are tools, and mature architectures mix them deliberately.

A rough guide to matching pattern to problem:

If you need... Consider
A simple, well-organized application Layered
Independent scaling and team autonomy at scale Microservices
Loose coupling and async reactions Event-Driven
Clean UI/logic/data separation MVC
An extensible product with add-ons Microkernel
Sequential data transformation Pipe-and-Filter
Coordinated distributed nodes / replication Leader-Follower
Auto-scaling, pay-per-use, no servers Serverless

Interview: Recognizing and naming patterns is a sign of architectural literacy. In a design discussion, framing your approach in pattern terms - "I'd structure this as microservices coordinated through event-driven messaging" - communicates your design clearly and shows you think in established structures rather than ad-hoc ones. Knowing the trade-offs of each (microservices add complexity, serverless has cold starts) is what turns recognition into real judgment.


The bottom line

Architectural patterns are the proven shapes systems take, each solving a different organizational problem. Layered architecture organizes by responsibility; client-server splits requesters from providers; microservices break a system into independent services; event-driven decouples through events; MVC separates UI from logic and data; microkernel builds a core with plugins; pipe-and-filter chains transformations; leader-follower coordinates distributed nodes; and serverless runs functions on managed infrastructure. They're not mutually exclusive - real systems combine them.

Knowing these patterns gives you both a vocabulary and a toolkit, so you start every design from a proven shape rather than a blank page. We work through choosing and combining them across System Design Fundamentals.


Go deeper

More articles