Client-server architecture is the most influential distributed communication model in the history of software. From the first desktop applications that connected to a central database, through three-tier architectures, to the web you use every day: practically everything that communicates over a network follows, at its root, the client-server pattern. Unlike layered architecture (which organizes the code), client-server architecture organizes the physical distribution of the system across machines. In this lesson we will walk through the two- and three-tier models, the difference between thin and thick clients, and how all of this evolved toward modern web architecture.
Contents
- The client-server model
- Two-tier model (2-tier)
- Three-tier model (3-tier)
- Thin client vs thick client
- The evolution toward the web
- Advantages and drawbacks
- Common mistakes and tips
- Exercises
- Conclusion
- The client-server model
In the client-server model, responsibilities are split between two roles:
- Client: initiates the requests. It asks for data or services.
- Server: waits for requests, processes them, and returns responses. It centralizes shared resources (data, logic).
sequenceDiagram
participant C as Client
participant S as Server
C->>S: Request (e.g., "give me policy 42")
S->>S: Processes / queries resources
S-->>C: Response (policy data)Essential characteristics:
- Asymmetry of roles: the client asks, the server serves. They are not equals (unlike peer-to-peer networks).
- Centralization: the server concentrates the shared resources, which facilitates management, security, and consistency.
- Network communication: client and server are distinct tiers; between them there is latency, possible failures, and the need for a protocol.
- Two-tier model (2-tier)
The two-tier model was the first to become popular in the 1990s with corporate desktop applications. The typical split:
- Tier 1 — Client: the desktop application, which contains the interface and the business logic.
- Tier 2 — Database server: stores the data and, often, part of the logic in stored procedures.
-- In 2-tier it was common to put business logic in the DB itself
CREATE PROCEDURE contratar_poliza(IN cliente VARCHAR(120), IN riesgo VARCHAR(60))
BEGIN
-- Business rule embedded in the data server
IF riesgo = 'NO_ASEGURABLE' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Uninsurable risk';
END IF;
INSERT INTO polizas(cliente, riesgo) VALUES(cliente, riesgo);
END;Problems of 2-tier that led to its decline:
- A "fat" client that is hard to maintain: every logic change forced a reinstall of the application on each PC.
- Limited scalability: each client opened its own connection to the DB; with hundreds of users, the DB became saturated.
- Scattered logic: rules lived partly in the client and partly in stored procedures, which were hard to version and test.
- Three-tier model (3-tier)
The three-tier model introduces an intermediate level—the application server—that concentrates the business logic. It is the dominant model in enterprise applications.
- Tier 1 — Presentation (client): browser or thin client. It only presents.
- Tier 2 — Application (application server): contains the business logic.
- Tier 3 — Data (DB server): persists the information.
graph LR
C[Client\nBrowser] -->|HTTP/JSON| A[Application Server\nBusiness logic]
A -->|SQL| BD[(Database Server)]| Aspect | 2-tier | 3-tier |
|---|---|---|
| Where the logic lives | In the client and/or in the DB | In the application server |
| Client maintenance | Expensive (reinstall) | Simple (centralized on the server) |
| Scalability | Limited | Good (the intermediate tier scales) |
| DB connections | One per client | Shared (pool on the server) |
| Deploying changes | On each client machine | On the server |
Do not confuse the three physical tiers with the three logical layers from the previous lesson. They often coincide (presentation/business/data), but they are distinct concepts: layers organize code and tiers organize deployment. A 3-tier application server can internally have its own layers.
- Thin client vs thick client
The great question of client-server design: how much responsibility do I put on the client?
- Thin client: it barely presents; all the logic is on the server. Classic example: a web page served entirely from the server, a terminal.
- Thick / fat client: it contains significant logic and state. Example: a desktop app or a modern SPA with a lot of logic in the browser.
graph TD
subgraph Thin Client
T1[Client: rendering only] --> T2[Server: rendering + logic + data]
end
subgraph Thick Client
K1[Client: UI + logic + state] --> K2[Server: API + data]
end| Criterion | Thin client | Thick client |
|---|---|---|
| Logic on the client | Minimal | Significant |
| Offline operation | No | Possible |
| Deploying changes | Immediate (all on the server) | Requires updating the client |
| Load on the server | High | Lower (part is delegated) |
| Perceived latency | Depends on the round-trip | Good (reacts locally) |
| Security of the logic | High (hidden on the server) | Lower (the code travels to the client) |
// Thick client example (SPA): the client validates and stores state locally
function validarPrima(prima) {
// Logic run in the browser (thick): immediate response without the network
if (prima <= 0) return "The premium must be positive";
return null;
}
// The server MUST revalidate anyway: never trust the clientCritical security point: in a thick client, client-side validation improves the experience, but the server must always revalidate. The client code can be tampered with.
- The evolution toward the web
The web is, in essence, a three-tier client-server architecture that has swung between thin and thick over time:
timeline
title Evolution of the web client
Web 1.0 : Static HTML : Pure thin client
Server-side : JSP/PHP/Servlets : The server generates the HTML
AJAX : Partial dynamic pages : The client starts to fatten
SPA : Angular/React/Vue : Thick client in the browser
SSR / Hybrid : Next.js, etc. : Mixed client-server renderingKey stages:
- Web 1.0 (static HTML): purely thin. The server delivers documents.
- Server-side rendering (JSP, PHP, Servlets): the server generates dynamic HTML per request. Thin client.
- AJAX: the browser starts to request chunks of data without reloading the page. The client fattens.
- SPA (Single Page Application): Angular, React, Vue. The browser is a thick client that consumes a REST/GraphQL API.
- SSR / hybrid: part is rendered on the server again (performance, SEO), combining it with client-side interactivity.
# Typical HTTP request from a web client to a REST API (3-tier model)
curl -X GET https://api.fiatc.example/polizas/42 \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json"Explanation: the browser (tier 1) makes an HTTP request to the application server (tier 2), which in turn will query the DB (tier 3). The protocol is HTTP, the format JSON, and authentication travels in a header. This is the skeleton of practically all of the modern web.
- Advantages and drawbacks
| Advantages | Drawbacks |
|---|---|
| Centralization of resources and security | The server is a single point of failure (it must be replicated) |
| Centralized maintenance and updates (in 3-tier) | Dependence on the network: latency and possible failures |
| Scalability of the intermediate tier | Greater complexity than a local system |
| Physical separation of responsibilities | Infrastructure and operating cost |
| Reuse of the server by many clients | The protocol and contracts must be managed carefully |
- Common Mistakes and Tips
- Trusting client-side validation. In any thick client, validate on the server as well. The client is hostile territory.
- Confusing tier with layer. Three physical tiers do not force three logical layers, nor vice versa.
- Putting business logic in the database without control. Inherited from 2-tier; it makes testing and versioning difficult. Use it only with judgment.
- Forgetting that the network fails. Every client-server call can time out or error; design retries and error handling.
- Not replicating the server. A single server is a single point of failure; plan for high availability.
- Tip: decide consciously how much to put on the client. More logic on the client improves the offline experience but complicates deployment and security.
- Exercises
Exercise 1. A company has a desktop app that connects directly to the database with the business logic inside the executable. State the model, its two main problems, and which model you would migrate to.
Exercise 2. Classify as thin or thick: (a) a terminal that only displays what the server sends; (b) a React SPA that validates forms and caches data; (c) a PHP page that generates HTML on the server.
Exercise 3. Explain why validating a negative premium only in the browser is insufficient and what the server must do.
Solutions
Solution 1. It is a 2-tier model with a thick client. Problems: (1) expensive maintenance, every change requires reinstalling on each PC; (2) limited scalability, each client opens its own connection to the DB. Recommended migration: 3-tier, introducing an application server that concentrates the logic and exposes an API.
Solution 2. (a) Thin. (b) Thick. (c) Thin (the logic and rendering are on the server; the browser only displays HTML).
Solution 3. The browser's JavaScript code can be tampered with: a user can bypass the validation or send requests directly to the API. The server must always revalidate the premium before persisting it, because it is the only real trust boundary.
- Conclusion
Client-server architecture defines how a system is split across machines: clients that ask and servers that serve. We have seen the shift from the fragile 2-tier to the robust 3-tier, the tension between thin and thick clients, and how the web has swung between both extremes. This physical split complements the logical layered split from the previous lesson. Next we will take a qualitative leap in organizing the inside of the server: Hexagonal Architecture (Ports and Adapters), which protects the domain core from infrastructure details and inverts the dependency that, in classic layers, pointed dangerously toward the database.
Application Architecture Course
Module 1: Fundamentals of Application Architecture
- What Is Application Architecture?
- The Role of the Software Architect
- Quality Attributes and Non-Functional Requirements
- Architectural Decisions and Trade-offs
- Architecture Documentation: Views and the C4 Model
Module 2: Design Principles and Tactics
- Coupling, Cohesion and Separation of Concerns
- SOLID Principles Applied to Architecture
- DRY, KISS, YAGNI and Other Design Principles
- Architectural Tactics for Quality Attributes
- Managing Technical Debt
Module 3: Architectural Styles and Patterns
- Monolithic Architecture
- Layered Architecture (N-Tier)
- Client-Server Architecture
- Hexagonal Architecture (Ports and Adapters)
- Clean and Onion Architecture
Module 4: Distributed Architectures and Microservices
- Introduction to Distributed Systems
- Microservices Architecture
- Service Decomposition and Bounded Contexts
- API Gateway, Service Discovery and Inter-Service Communication
- Resilience Patterns: Circuit Breaker, Retry and Bulkhead
- The CAP Theorem and Data Consistency
Module 5: Event-Driven Architectures and Messaging
- Fundamentals of Event-Driven Architecture
- Asynchronous Messaging: Queues and Brokers
- Event Patterns: Event Sourcing and CQRS
- Managing Distributed Transactions: The Saga Pattern
- Real-Time Data Streaming
Module 6: Domain-Driven Design (DDD)
- Core DDD Concepts
- Strategic Design: Bounded Contexts and Ubiquitous Language
- Tactical Design: Entities, Aggregates and Repositories
- Context Mapping
Module 7: Data and Persistence
- Persistence Strategies: SQL vs NoSQL
- Data Access Patterns: Repository, Unit of Work and DAO
- Database per Service and Distributed Data Management
- Caching and Invalidation Strategies
Module 8: Cloud Architecture and Deployment
- Cloud Computing Fundamentals (IaaS, PaaS, SaaS)
- Containers and Orchestration with Docker and Kubernetes
- Serverless Architecture
- Cloud-Native Design Patterns
- Infrastructure as Code (IaC)
Module 9: Quality, Security and Observability
- Scalability: Horizontal vs Vertical and Load Balancing
- High Availability and Fault Tolerance
- Security by Design and Authentication/Authorization
- Observability: Logging, Metrics and Tracing
- Performance and Load Testing
