An architectural style is a high-level blueprint that defines how an application is structured, how its components communicate, and how it is deployed and scaled. The choice of style affects development speed, scalability, operational complexity, and team organization.
-
Monolith :
A monolith is an application built and deployed as a single unit. The UI, business logic, and data access all live in one codebase and run as one process. It is simple to develop, test, and deploy in the beginning, but as the codebase grows, deployments become riskier and scaling means replicating the entire application instead of just the busy part. Example: A classic Django or Laravel application where one deployable serves every feature of the product. Monoliths are best suited for small teams, early-stage products, and applications with tightly coupled domains.
-
Microservices :
Microservices architecture splits an application into small, independently deployable services. Each service owns a single business capability and ideally its own database, and services communicate over the network via APIs or messaging. This enables independent scaling, technology freedom per service, and isolated failures, but it adds operational complexity such as service discovery, distributed tracing, and eventual consistency. Example: An e-commerce platform with separate services for catalog, cart, payments, and shipping, each deployed and scaled on its own.
-
Serverless :
Serverless architecture delegates server management entirely to a cloud provider. Code runs in short-lived, event-triggered functions (FaaS) or managed services, and you pay only for actual execution time. There are no servers to provision or patch, and scaling is automatic, including scaling down to zero. The trade-offs are cold starts, execution time limits, and vendor lock-in. Example: An image upload triggering an AWS Lambda function that generates thumbnails and stores them in S3.
-
Event-Driven Architecture :
In event-driven architecture (EDA), components communicate by producing and consuming events instead of calling each other directly. An event is an immutable record that something happened, such as
OrderPlaced. Producers emit events to a broker, and consumers react asynchronously. This decouples services, since a producer does not know or care who consumes its events, and new consumers can be added without touching existing code. Example: When an order is placed, the inventory, billing, and notification services each react to the sameOrderPlacedevent independently. -
Layered / N-Tier Architecture :
Layered architecture organizes code into horizontal layers, each with a distinct responsibility, where a layer may only call the layer directly below it. The classic layers are presentation (UI), application or business logic, and data access, with the database at the bottom. "N-tier" refers to physically deploying these layers on separate machines, such as web server, application server, and database server. It is simple and widely understood, but changes that cut across layers can be tedious. Example: A typical Spring Boot application with
Controller → Service → Repository → Database. -
Hexagonal / Clean Architecture :
Hexagonal architecture (also called Ports and Adapters) and Clean architecture place the business logic at the center, completely independent of frameworks, databases, and UIs. The core defines ports (interfaces describing what it needs), and the outside world plugs in through adapters such as a REST controller, a Postgres repository, or a message consumer. Dependencies always point inward, so the domain never imports infrastructure code. This makes the core easy to unit-test and lets you swap infrastructure (for example, MySQL to DynamoDB) without touching business rules. Example: An
OrderServicethat depends on anOrderRepositoryinterface, implemented separately by a database adapter and an in-memory adapter for tests. -
Service Mesh :
A service mesh is a dedicated infrastructure layer that handles service-to-service communication in a microservices system. A lightweight proxy (sidecar) is deployed next to every service instance and transparently handles routing, load balancing, retries, mutual TLS encryption, and observability, so none of that logic has to live in application code. A control plane configures all the proxies centrally. Example: Istio or Linkerd on Kubernetes, providing automatic mTLS and per-service traffic metrics without changing any service's code.