Rohit Kumar
← System design

Stage 01 · Foundations

N-Tier Architecture

5 min read Core 1 diagram Rohit Kumar

The oldest structural idea in this whole list, and the one most likely to be dismissed as obvious. It’s worth ten minutes because three genuinely different concepts get called “layers” and people conflate them constantly.


Start with everything in one place

You’re building an internal tool. The first version is a single PHP file: it reads the form post, queries MySQL directly, and prints HTML. Database credentials sit next to markup.

This works. Plenty of valuable software looks like this.

It stops working for specific reasons. You want to add a mobile client, and the HTML generation is tangled into the query logic, so there’s nothing to call. A junior developer writes a query in a template and it goes to production. You want to scale the web front end without buying more database capacity, and you can’t, because they’re the same process.

Each of those is the same underlying problem: there’s no seam. Nothing can be changed, tested, reused or scaled independently, because there are no independent parts.


Drawing the lines

The classic three-tier split:

Presentation — rendering and user interaction. Knows nothing about SQL.

Application — the business logic. Knows nothing about HTML or about which database you use.

Data — persistence. Knows nothing about business rules.

The discipline that makes it worth anything is that each layer may only talk to the one below it. Presentation calls application, application calls data. Presentation never touches the database directly, even when it would be quicker.

That rule is the whole value. Break it once and the seam stops existing.


The tiers real systems actually run

The three-tier diagram is a teaching aid. Here’s what a production system usually looks like:

Diagram: N-Tier Architecture

Read down that stack and notice each line exists for a different reason. The CDN exists because latency and origin load are real (CDN). The load balancer exists so the application tier can be replaced without anyone noticing (Load Balancing). The cache exists to protect the tier below it (Caching Strategies). The data tier is the only place truth lives.

That’s why the application tier can be stateless — every piece of state has somewhere else to live. And statelessness is what makes horizontal scaling work at all. → Scalability


The three things people conflate

This is the part actually worth carrying.

Layering is about how code is organised. Packages, modules, dependency direction. It’s a source-tree concern.

Tiers are about what runs on separate machines. It’s a deployment topology concern.

Microservices are about deployment units — what ships and scales independently. → Monoliths and Microservices

These are independent. A single monolithic deployable can be beautifully layered internally and run across five physical tiers. A pile of microservices can be an unlayered mess inside each one.

So “we’re moving to microservices to get better separation of concerns” is a category error. If your layering is bad, distributing it makes it bad and slow. Layering is free. Tiers cost network hops. Microservices cost an entire operational practice.


What each line costs

Every boundary you draw buys independence and charges you for it.

A layer boundary costs indirection — more files, more interfaces, and a change that touches all three layers instead of one. Over-layered code where every trivial field addition means edits in six places is a real and common failure.

A tier boundary costs a network hop, which means latency, serialization, and a new failure mode where the thing you’re calling is simply not there.

So don’t add a layer because a diagram in a book had one. Add it when you have two implementations, two clients, or two scaling profiles.


Where it went next

Strict top-down layering has a known weakness: the business logic ends up depending on the data layer, so your domain code imports your ORM and your rules are coupled to your storage choice.

Hexagonal architecture — also called ports and adapters, or clean architecture — inverts that. The domain sits in the middle and defines interfaces for what it needs. The database and the HTTP layer are adapters that plug into those interfaces from outside. Dependencies point inward, toward the domain, rather than downward toward the database.

The practical payoff is that your core logic becomes testable without a database and your storage becomes swappable. The practical cost is more indirection, and it’s over-engineering for a CRUD service.


Where this shows up

  • Effectively every web application ever built, whether or not anyone drew the diagram.
  • Cloud reference architectures — every “well-architected” diagram from AWS or Azure is this picture with vendor logos.
  • MVC and its descendants, which are the presentation layer’s internal structure.
  • The Uber design in Uber · High Level Design: clients, stateless gateways, and three distinct storage tiers — the same shape.

In an interview

You won’t be asked about this directly. It shows up in whether your high-level diagram has sensible boundaries, and you’ll draw it without naming it.

Where it earns something is if someone asks why your application servers are stateless. The answer — every piece of state lives in a tier built for it, which is what lets you add and remove app servers freely — is a good one.

And if a discussion about microservices comes up, the layering-versus-deployment distinction is worth making. It’s a cheap way to show you won’t reach for distribution to solve a code organisation problem.


Monoliths and Microservices · Load Balancing · CDN · Caching Strategies · Scalability · API Gateway · Proxies

Sources

© Rohit Kumar 2026