ReviseAlgo Logo

Architecture & Communication

Client-Server Architecture

The foundational model where clients request resources and servers respond.

In short

The foundational model where clients request resources and servers respond.

Last Updated: June 26, 2026 25 min read

In modern computing, resources and workloads must be distributed efficiently across networks. The foundational design pattern that orchestrates this distribution is the Client-Server Architecture. In this model, tasks are partitioned between service providers, called Servers, and service requesters, called Clients. The client initiates communication channels over a network to request resources, while the server waits passively, processes incoming requests, and returns responses.

1. Learning Objectives

  • Define the separate roles and responsibilities of clients and servers.
  • Understand the structural differences between 2-Tier, 3-Tier, and N-Tier client-server systems.
  • Differentiate between Thin Clients and Thick (Rich) Clients.
  • Trace the connection sequence of client-server communication channels.
  • Evaluate security threat vectors, scaling strategies, and failure points in server clusters.
  • Implement a fully functional client-server network simulator with session authentication and client retries in Java, Python, and C++.

2. Prerequisites

To get the most out of this lesson, you should review the following networking topics first:

  • OSI Model & IP: Network layers and address routing.
  • TCP/UDP: Connection-oriented transport protocols vs. connectionless packet streaming.
  • DNS Resolution: Translating hostnames to physical IP addresses.
  • HTTP / HTTPS: Application-level request-response lifecycles.

3. Why This Topic Matters

Virtually every internet application—from simple websites to massive SaaS portals like Salesforce or streaming backends like Netflix—relies on client-server architecture.

Designing client-server systems requires balancing several forces:

  • Centralized Logic: Storing data and business rules on the server protects intellectual property and simplifies application updates.
  • Scaling Limits: Centralized servers process requests from millions of clients, creating CPU, memory, and database bottlenecks.
  • Network Latency: Splitting UI presentation from data storage forces clients to wait for network roundtrips to load views.

Understanding how workloads are split, how connection pipes are managed, and how servers scale is the starting point for building robust distributed systems.

4. Real-world Analogy

Think of a diner visiting a Centralized Restaurant Kitchen:

The Client (Diner): Sits at a table, reviews the menu (UI layout), and decides what they want. They make a request to the kitchen via a waiter. The diner does not know how the ovens work, how the pantry is organized, or how to cook the steak.

The Server (Kitchen): Waits passively in the back. When a request (order ticket) arrives, the kitchen staff processes it, retrieves ingredients from the pantry (database), cooks the food (business logic), and returns the plate (response) to the waiter to deliver back to the diner.

If 1,000 diners show up at the same time, the kitchen gets backlogged (server bottleneck). To solve this, you need to open more kitchen stations and distribute the order tickets among them (load balancing).

5. Core Concepts

  • Client Role: Requesters of information. Clients trigger communication channels, handle presentation rendering, and manage local user states. Examples: Web Browsers, iOS/Android apps, CLI tools, IoT devices.
  • Server Role: Providers of services. Servers run continuously (listening on socket ports), process requests, validate credentials, query databases, and return structured payloads (JSON, HTML).
  • N-Tier Architecture:
    • 2-Tier: Client talks directly to the database (no intermediate application server). Simple, but insecure since the database credentials must reside on the client.
    • 3-Tier: Client $\rightarrow$ Application Server $\rightarrow$ Database Server. This is the industry standard for web applications.
  • Thin vs. Thick Client:
    • Thin Client: Does little to no processing locally; it merely displays UI painted by the server (e.g. old terminal screens, or websites where HTML is fully generated on the server).
    • Thick Client: Handles significant local processing, routing, and state management (e.g. React SPAs, native mobile applications, desktop game engines).
  • Decentralized Alternative (Peer-to-Peer / P2P): A model where there is no dedicated server. Instead, every node in the network acts as both a client and a server (servent), sharing bandwidth and data directly with other peers (e.g., BitTorrent).

6. Visualizations

Component Diagram

The logical layout of components in a 3-tier client-server architecture:

Deployment Diagram

The physical mapping of servers and load balancers inside cloud availability zones:

Connection Flow Sequence

7. How It Works Step-by-Step

  1. Addressing: The client initiates communication by resolving the server's domain name to an IP address using DNS.
  2. Handshake: The client opens a TCP socket connection at the target IP address and port (default 80 for HTTP, 443 for HTTPS). It performs the 3-way handshake (SYN, SYN-ACK, ACK).
  3. Encryption: If using HTTPS, a TLS handshake negotiates encryption keys, securing the socket channel.
  4. Request Execution: The client formats a request header and body (such as an HTTP POST query with JSON fields) and writes it to the socket.
  5. Request Processing: The server's socket listener detects the incoming bytes, delegates the stream to a worker thread, parses the HTTP headers, validates session authentication, and executes the business logic.
  6. Response Transmission: The server serializes the result into a payload (e.g. JSON or HTML), writes the HTTP response code (e.g. 200 OK) and headers to the socket, and closes or keeps the connection alive.
  7. Client Rendering: The client reads the socket bytes, parses the payload, updates its internal state, and renders the information on the UI.

8. Internal Architecture

A high-performance server application manages connection requests using one of two concurrency models:

  • Thread-per-Request Model: The server allocates a dedicated thread from a pre-allocated pool to handle each incoming connection socket. The thread handles reading, parsing, processing, and writing. This is simple to code but does not scale to millions of concurrent idle connections because thread context-switching consumes significant RAM.
  • Event-Driven / Non-Blocking Model (Epoll / Kqueue): A single event loop thread monitors thousands of sockets using OS primitives (like Linux epoll). When a socket has bytes ready to read, the loop alerts a worker thread to parse the data. This model (used by Node.js, Nginx, and Netty) allows a single machine to handle millions of concurrent connections (C10K/C10M problem).

9. Request Lifecycle

Let's trace the lifecycle of a secure user login request:

  1. Client UI Action: The user types their password and clicks "Login". The client app intercepts this action and serializes the username and password into a JSON object.
  2. Transport Pipe: The client sends an HTTPS POST request to /api/v1/login.
  3. Load Balancing: The load balancer intercepts the connection, decrypts the TLS layer, and routes the request to an available App Server node.
  4. Authentication Verification: The App Server extracts the credentials, hashes the password, and queries the database to verify the user.
  5. Session Generation: The App Server generates an encrypted JWT session token, saves the session state in a shared Redis cache, and sets a Set-Cookie header on the HTTP response.
  6. Client Session Cache: The client browser receives the 200 OK response, extracts the session token, stores it in LocalStorage or an HttpOnly cookie, and routes the user to the dashboard view.

10. Deep Dive

A. Thin Clients vs. Thick Clients

Metric Thin Client (Server-Rendered HTML) Thick Client (React SPA / Mobile App)
Workload Division Server computes HTML, client only renders pixels. Client computes UI components, fetches raw JSON.
Initial Page Load Very fast (minimal JS to parse). Slower (must download large JS bundles).
Subsequent Views Slower (requires full page refresh). Instant (page updates client-side using JSON APIs).
Offline Support None. Excellent (can cache state and sync later).

B. Stateful vs. Stateless Servers

In a Stateful Server, the server keeps track of active client sessions in local RAM:

This simplifies application logic. However, it presents a major scaling problem: if you add a second server, you must configure Session Stickiness (sticky sessions) at the load balancer level to ensure that Alice's requests always route to Server 1. If Server 1 crashes, Alice's session and shopping cart are lost.

In a Stateless Server, the server stores no session data in local memory. Instead, the session state is either passed in every request (as an encrypted JWT) or stored in a shared external database (like a Redis cluster). This allows the load balancer to route any request to any server node, making horizontal scaling simple and resilient.

C. Connection Handling & Keep-Alive

Under HTTP/1.0, connection handling was simple but inefficient: the client opened a TCP connection, made one request, read the response, and closed the connection.

HTTP/1.1 introduced the Connection: keep-alive header. This tells the server to keep the TCP socket open for subsequent requests, bypassing the overhead of repeated TCP 3-way handshakes and TLS negotiations. Modern HTTP/2 and HTTP/3 multiplexing take this further, letting clients stream multiple requests over a single shared connection concurrently.

D. Security Threat Vectors

  • DDoS (Distributed Denial of Service): Botnets flood the server's listening socket with incomplete connections (SYN floods), exhausting OS thread pools and connection queues.
    Mitigation: Configure SYN cookies at the OS kernel level, and place rate limiters/WAFs (like Cloudflare) in front of the load balancer.
  • Man-In-The-Middle (MITM): Attackers intercept the network connection between client and server, reading or modifying plain text payloads.
    Mitigation: Force strict SSL/TLS encryption (HTTPS) with HSTS headers to prevent protocol downgrade attacks.
  • Client-Side Tampering: Attackers modify thick client code (e.g. changing request variables inside React state or game memory) before sending requests.
    Mitigation: Zero-Trust model. Never trust client validation. The server must perform full validation, authentication, and authorization checks on every incoming request.

11. Production Examples

  • Web Applications (SaaS): React or Vue.js SPAs running in browser engines (Clients) fetching profile data and updates from Go/Python microservices (Servers) via REST API endpoints.
  • Mobile Apps: A native iOS Swift application (Client) making gRPC calls to backend microservices (Servers) to fetch feed updates.
  • BitTorrent (P2P Comparison): Unlike client-server, BitTorrent clients download blocks of a file from other active peers while simultaneously uploading blocks to others, distributing the bandwidth load across the network.

12. Advantages

  • Centralized Data Security: Data resides in secure database engines behind application server firewalls rather than on vulnerable client devices.
  • Ease of Application Management: Updating the server code updates the application for all users instantly, bypassing client-side app store review delays.
  • Modular Separation of Concerns: Frontend teams focus on UI design and user interaction, while backend teams focus on database performance and business logic.

13. Limitations

  • Server Scaling Bottleneck: A single server has physical limits. Under high traffic, it can experience resource exhaustion.
  • Single Point of Failure (SPOF): If the backend servers crash, the clients cannot function, even if they have perfect network connectivity.
  • Network Latency Dependency: Every action requiring server-side validation incurs a round-trip network delay, which degrades performance for users with slow connections.

14. Trade-offs

  • Stateful vs. Stateless Session Storage: Stateful sessions make coding easy because the server tracks history locally, but it makes horizontal scaling difficult and risks data loss on crashes. Stateless architectures scale horizontally and handle crashes easily, but they require storing states in external caches (like Redis) or passing larger encrypted tokens (JWT) in every request, increasing network payload size.
  • Thick Client vs. Thin Client: Thick clients provide a responsive, native user experience by managing routing and UI states locally, but they require parsing heavy JS bundles and pose security risks if they contain sensitive business rules. Thin clients are secure and fast to load initially, but they require server round-trips for every UI interaction, leading to a clunky user experience.

15. Performance Considerations

  • TLS Session Resumption: The TLS handshake takes multiple network roundtrips. Use TLS session resumption to reuse keys from previous connections, reducing connection setup times.
  • TCP Connection Pools: Opening and closing sockets repeatedly is expensive. Keep connection pools active between client proxies and app nodes to minimize socket creation overhead.

16. Failure Scenarios

  • Server Resource Exhaustion: The server runs out of worker threads or connection handles, causing it to reject new requests with 503 Service Unavailable or hang indefinitely.
    Mitigation: Configure auto-scaling groups to add server nodes based on CPU usage, and set rate limiters to drop excessive traffic.
  • Transient Network Failures: Temporary routing updates or packet drops cut the connection between client and server.
    Mitigation: Implement client-side retries using exponential backoff and random jitter. This prevents clients from flooding the server when it recovers.
  • Cache/Database Lockup: The server is healthy, but the database behind it is locked or slow. The server threads block while waiting for DB responses, eventually exhausting the connection pool.
    Mitigation: Implement circuit breakers. If database calls timeout repeatedly, trip the circuit breaker and return a cached response or an error instantly, protecting the server threads from blocking.

17. Best Practices

  • Keep application servers stateless to allow horizontal scaling.
  • Always validate, sanitize, and authorize requests on the server, even if the client has already performed these checks.
  • Implement client-side retry budgets to limit the total number of retries during outages.
  • Use CDNs to cache static resources (like HTML, JS, images) close to the user, reducing load on the application servers.

18. Common Mistakes

  • Storing session state in the server's local memory, which prevents horizontal scaling.
  • Trusting client validation, allowing attackers to bypass inputs using tools like curl.
  • Failing to set socket timeout values, causing thread leaks if a client or backend connection hangs.

19. Implementation (Client-Server Simulator)

Below is a complete, production-grade Client-Server network simulation. It simulates a client making requests to a multi-threaded server with connection pooling, authentication, session tokens, and mock DB calls. It also models transient network drops and demonstrates how clients can use retry policies with exponential backoff to handle them.

20. Interview Questions & Answers

Q1. How does a stateless client-server model scale differently compared to a stateful one?

Answer:

  • In a Stateful Model, session state is bound to the server's local memory. The load balancer must use session stickiness to route requests from a client to the same server node. Adding/removing nodes changes the hash ring coordinates, destroying sessions on target servers.
  • In a Stateless Model, session data is not bound to any local server node. Requests contain all necessary authorization metadata (such as JWTs) or query a shared cache cluster (Redis). This allows the load balancer to route requests to any server node, making horizontal scaling and failovers simple.

Q2. What is the C10K problem, and how do modern server architectures solve it?

Answer: The C10K problem refers to the challenge of managing 10,000 concurrent client connections on a single server node.

Traditional servers assigned a dedicated OS thread to each client socket. Context-switching between thousands of threads consumes significant RAM and CPU, causing performance degradation.

Modern servers solve this using an event-driven, non-blocking I/O model (like epoll or kqueue). Instead of using a thread per socket, a single event loop thread monitors thousands of sockets. When a socket receives data, the event loop triggers a worker thread from a small pool to process the query, allowing a single server to handle millions of connections efficiently.

Q3. Why is client-side validation alone insufficient for securing client-server architectures?

Answer: The client application runs on physical hardware that is controlled by the user. An attacker can inspect, modify, and bypass client-side code using debuggers, proxy tools (like Charles or Burp Suite), or direct console commands (like curl or Postman).

Client-side validation is useful for providing instant user feedback (improving UX), but the server must treat all incoming requests as untrusted. The server must validate and authorize every input before execution.

21. Practice Exercises

  • Exercise 1 (Easy): Trace and document the sequence of steps that occur when a client browser issues a request to load a webpage, starting from the DNS lookup down to parsing the HTML.
  • Exercise 2 (Medium): Modify the provided Python simulation to add a Session Expiry check. If a session token is older than 5 seconds, the server should deny the request with status code 401 Unauthorized and require the client to re-login.
  • Exercise 3 (Hard): Implement a Python script simulating Connection Limiting on the server. The server should track the count of active socket handlers, and if it exceeds a limit (e.g. 3 active requests), it must return 429 Too Many Requests (Rate Limiting) to subsequent clients.

22. Challenge Problem

The Thundering Herd Recovery Challenge: You operate a stateless client-server cluster of 5 servers behind a load balancer, processing 50,000 requests per second. The shared session Redis database goes down for 30 seconds.

All 50,000 client queries fail during this period. When the Redis database recovers:

  • If all clients retry immediately, they will overwhelm the database, causing another crash. This is known as a Thundering Herd or Retry Storm.
  • Design an architecture explaining how to implement client-side Exponential Backoff with Full Jitter and Circuit Breakers on the server nodes to ensure the cluster can recover smoothly.
  • Write a math-based pseudocode routine illustrating the delay calculation for a client on its $k$-th failed attempt.

23. Summary

Client-Server Architecture is the foundation of modern networked computing. It isolates presentation logic on the client from business rules and databases on the server. Keeping servers stateless enables horizontal scaling behind load balancers, while implementing robust client-side retry budgets and server-side validation is critical to building a secure, resilient system.

24. Cheat Sheet

Feature Client-Server Model Peer-to-Peer (P2P) Model
Node Roles Strict division: clients request, servers respond. Symmetrical: every node acts as client and server.
Control Axis Centralized database and security catalog. Decentralized token validation or local storage.
Scaling Vector Requires adding servers behind a load balancer. Scales organically as more peers join the swarm.
Single Point of Failure Yes: Server node crash disables client access. No: System continues if individual peers leave.

25. Quiz

1. Which concurrency model is best suited to handle millions of concurrent idle connection sockets on a single server machine?

  • A. Thread-per-request model.
  • B. Multi-process database locking.
  • C. Event-driven, non-blocking I/O event loops (epoll).
  • D. Stateful sticky session routing.

Answer: C. Event-driven architectures monitor multiple sockets on a single thread using OS event alerts, bypassing the thread context-switching overhead.

2. What is the security risk of storing user session state inside an application server's local memory?

  • A. Sessions are exposed to standard SQL injection.
  • B. Session data is lost if the server node crashes, and load balancers must enforce sticky routing.
  • C. Sockets are forced to close after every HTTP request.
  • D. Clients must decode JWT tokens locally.

Answer: B. Local memory storage prevents stateless horizontal scaling and causes session loss if a server node crashes.

3. What does a "Zero-Trust" model imply for server-side validation?

  • A. The server does not validate database connections.
  • B. The client does not trust HTTP response headers.
  • C. The server must validate and authorize every request, ignoring any client-side validation.
  • D. Sessions must expire every 60 seconds.

Answer: C. Since client code runs on user hardware, it can be bypassed. The server must validate all inputs before execution.

4. Why is keep-alive connection handling preferred in HTTP/1.1 over HTTP/1.0?

  • A. It encrypts the payload body using TLS.
  • B. It keeps the TCP socket open for subsequent requests, reducing connection handshake latency.
  • C. It automatically replicates queries to read databases.
  • D. It converts HTTP queries to UDP packets.

Answer: B. Reusing TCP connections bypasses the overhead of repeated TCP 3-way handshakes.

5. Which of the following is a primary characteristic of a Thin Client?

  • A. It handles significant local state caching and API routing.
  • B. It runs business logic rules locally when offline.
  • C. It does no processing locally, displaying only UI painted by the server.
  • D. It runs without an operating system.

Answer: C. Thin clients act as basic rendering terminals, offloading processing to the server.

6. What is a "SYN flood" attack?

  • A. Flooding the database with duplicate primary keys.
  • B. Flooding the server with TCP SYN packets without completing the handshake, exhausting connection queues.
  • C. Intercepting session cookies using cross-site scripting.
  • D. Rapidly restarting the application server process.

Answer: B. Incomplete TCP handshakes exhaust connection backlogs on the server, blocking legitimate traffic.

7. Why are client-side retries with exponential backoff and jitter implemented?

  • A. To make database query joins run faster in-memory.
  • B. To encrypt session tokens.
  • C. To prevent retrying clients from overwhelming a recovering server (Retry Storms).
  • D. To enforce sticky session routing at the proxy.

Answer: C. Adding backoff delay and random jitter spreads out client retries, allowing a recovering server to process them without crashing.

8. What separates a 3-Tier architecture from a 2-Tier architecture?

  • A. The inclusion of a CDN server.
  • B. The inclusion of a database read replica.
  • C. An application server tier that isolates the client from direct database access.
  • D. The use of UDP instead of TCP.

Answer: C. An intermediate application server handles business logic and security, preventing direct database access from untrusted clients.

9. Which protocol is connection-oriented and ensures guaranteed delivery in client-server networks?

  • A. DNS.
  • B. UDP.
  • C. TCP.
  • D. IP.

Answer: C. TCP is connection-oriented, managing packet ordering, retransmission, and flow control.

10. What is a key mitigation to protect API servers from brute-force authentication requests?

  • A. Adding more read replicas to the database.
  • B. Rate limiting client IPs at the load balancer or API Gateway level.
  • C. Transitioning to stateful session tracking.
  • D. Disabling DNS resolution.

Answer: B. Rate limiters drop excessive requests before they reach the backend application servers, preventing resource exhaustion.

26. Further Reading

  • Computer Networking: A Top-Down Approach — James Kurose and Keith Ross.
  • RFC 7230: Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing.
  • AWS Architecture Center: Designing high-availability web app hosting tiers.

27. Next Lesson Preview

Now that we understand the core Client-Server model, we see that modern systems split the server role into multiple micro-tiers (Web server, App server, Cache server, Database cluster). In the next lesson, we will explore N-tier Architecture—the structural pattern that divides server logic into multiple physical and logical layers to maximize scalability and maintainability.

Key takeaways

  • Clients request; servers centralize data and logic.
  • Servers can be a bottleneck — scale with load balancing and replication.
  • P2P is the decentralized alternative where every node is both roles.