In a client-server design, what's the difference between a thin client and a fat (thick) client, and what trade-offs push a team toward one or the other?
answer
- spectrum, not binary
- thin = server renders/decides, client displays
- fat = client has local logic/state
- central update vs per-device duplication
- client logic never fully trusted
basics
~20 sA thin client does almost no work itself — it just displays what the server sends and forwards user input back. A fat (thick) client does a lot locally — business logic, validation, rendering — and only talks to the server for shared data or authoritative operations.
solid answer
~40 sThin clients minimize local logic: a classic terminal, or a server-rendered web page, does little beyond input capture and display, so nearly all business logic and state lives on the server. Fat/thick clients push significant logic into the client — a native desktop app, or a modern JS single-page app — handling UI state, validation, and sometimes local storage, calling the server mainly for shared data and authoritative operations. Thin clients are easy to update centrally and work on low-power devices, but need constant connectivity and put more load/latency on the server for every interaction. Fat clients feel more responsive and can work partially offline, but duplicate logic across client platforms, are harder to update in a coordinated way, and expose more logic to an untrusted environment.
go deeper
Should describe the basic difference: thin client shows what the server tells it, fat client does more work locally.
Should place SPAs and native apps correctly on the spectrum and name at least one trade-off each way.
Should explain why client-side logic can never fully replace server-side enforcement, and discuss update/versioning implications of fat clients.
Should reason about offline/sync complexity introduced by fat clients and make an architecture call for a given product's connectivity and update constraints.
## A spectrum, not a binary The thin-client/fat-client distinction describes how much of an application's logic, state, and rendering responsibility lives on the client versus the server, and it's a spectrum rather than a binary. - **At the thin extreme**, a client is little more than an I/O terminal: a 1970s mainframe terminal displayed characters sent by the mainframe and forwarded keystrokes back, with zero local logic. A classic server-rendered web app (a Rails or PHP app returning full HTML pages) is a modern near-equivalent: the browser renders whatever HTML the server computed, and nearly every click causes a full round trip back to the server. - **At the fat extreme**, a native desktop application does the vast majority of its work locally — UI logic, business rules, sometimes its own local data store — and only calls out to a server for data that must be shared or operations that must be centrally controlled, like final payment processing. ## What crosses the wire Mechanically, the difference shows up in what crosses the wire and where computation happens. | Client | What it sends and gets back | |---|---| | **Thin** | A thin client sends raw user actions and receives fully-formed presentation output; business logic runs entirely server-side, and the client doesn't even have that logic available to run. | | **Fat** | A fat client sends structured data (an API call with parameters) and receives raw data, and the client itself contains code to validate input, decide what to render, and manage local UI state, only calling the server for the shared resource. | ## The tension being traded This exists because there's a genuine tension between two goods: **central control** and **local responsiveness**. - **Centralizing logic on the server (thin client)** means you can fix a bug or ship a new feature by deploying once, server-side, and every user gets it immediately without an app-store update — critical for products where you don't control the update cadence of a million browsers. It also means the server is the sole enforcement point for anything security- or correctness-critical. - **Pushing logic to the client (fat client)** buys responsiveness — the UI can react instantly to input without waiting on a network round trip — and can enable offline or intermittent-connectivity use, since the client can keep working on locally-held logic and data even when the server is unreachable. ## What each one costs The costs mirror the benefits. - **Thin clients are latency-bound.** Every interaction, even a trivial one like validating an email format, can require a server round trip, which is unusable on poor networks and burns server capacity on work that's cheap to do locally. They also can't function at all without connectivity. - **Fat clients duplicate logic.** If you have a web app, a native iOS app, and a native Android app all with local business logic, a rule change has to be implemented and shipped three times, with a real risk of the three drifting out of sync. - **Fat clients are also inherently a less trustworthy execution environment.** Logic embedded there can be reverse-engineered or bypassed, so any rule that matters for security or money has to be re-validated server-side regardless of what the fat client already checked. ## Where the middle sits today The modern trend — single-page apps built with React/Vue talking to a JSON API — sits deliberately in the middle: "fat enough" to give an app-like, responsive UI (routing, form validation, optimistic updates happen client-side) while keeping authoritative logic, persistence, and security enforcement server-side, and often shipping the client itself over the network on every load, which restores some of the thin client's centralized-update property. A concrete failure mode of going too fat: an early-2010s SPA that duplicated its pricing-calculation logic in JavaScript for a snappy UI, but a bug meant the client-computed total sometimes disagreed with the server-computed total at checkout — exactly the class of bug thin architectures don't have, because there's only one place the logic runs.
- Why can't a fat client's local validation logic replace server-side validation, even if it's identical?The client runs on hardware and code the end user (or an attacker) fully controls, so any check implemented only there can be skipped by calling the API directly with crafted input. Server-side validation is the only copy that's actually enforced; client-side validation is purely a UX optimization to avoid a round trip.
- What pushed the industry from server-rendered thin-client web apps toward fat single-page apps in the 2010s?Rising expectations for app-like responsiveness combined with browsers becoming powerful enough to run substantial JavaScript made client-side rendering and state management practical, and frameworks like Angular/React made managing that local complexity tractable.
- In a fat client architecture with local offline storage, what new problem appears that a thin client never has to solve?Conflict resolution and sync: if the client can create or modify data while disconnected, the server later has to reconcile that with anything else that changed in the meantime, deciding whose version wins or how to merge — a thin client never accumulates local unsynced state because it never operates disconnected.
A thin client is like calling a travel agent for every decision on your trip — they do the thinking, you just relay requests; a fat client is like planning the whole trip yourself with a guidebook, only calling the agent to actually book the flight.
saying these in an interview costs you the question
- Says thin vs fat client is a strict binary with no middle ground
- Believes client-side validation alone is sufficient security
- Doesn't recognize a browser running a heavy SPA as a fat client
- Thinks fat clients never need a server at all
- Can't name a cost of duplicating logic across client platforms