Distributed Systems – Setting the Scene


One click, many systems


What happens when you click “Buy now” in an online shop?

  • Your browser sends a request to the shop.
  • The shop checks who you are, whether the product is in stock, creates an order, asks a bank to charge you, books a parcel service and sends you an e-mail.
  • These parts run on different machines, often in different data centers and even at different companies.

You see one website — behind it work dozens of independent systems.


Definition

A distributed system is a collection of independent computers that appears to its users as a single coherent system. — Andrew S. Tanenbaum


Three key words:

KeywordMeaning
independentevery node has its own CPU, memory, OS — and can fail on its own
networknodes only communicate by sending messages (no shared memory)
single systemthe user should not notice that many computers are involved

Monolith vs. distributed system


MonolithDistributed system
Deploymentone big unitmany small units
Communication between partsfunction call (nanoseconds)network message (milliseconds)
Failureeverything or nothingparts can fail independently
Scalingscale the whole thingscale only the part that needs it
Complexityin the codein the communication between parts

A monolith is not bad — it is often the right choice for small projects. Distribution is a trade-off.


Why distribute at all?

  • Scalability – one machine is not enough for millions of users.
  • Availability – if one machine fails, others take over.
  • Geography – servers close to the users (lower latency), data must stay in a certain country (GDPR).
  • Organisation – different teams own different parts and deploy independently.
  • Reuse / integration – use services of others (payment, maps, weather, login with Google …).
  • Resources – some things only exist in one place (a sensor, a printer, a special database).

Everyday examples

SystemWhy is it distributed?
WhatsApp / Signalbillions of users, messages must arrive even if the receiver is offline
Netflix / YouTubevideo is delivered from servers close to you (CDN)
Online bankingbank, card network, other banks — different organisations
Online gamesgame servers worldwide, low latency required
Smart home / IoTsensors, hubs, cloud and app all talk to each other
WebUntisbrowser, app and server, shared by many schools

Part 1: Architectures

How are the parts of a distributed system arranged and who talks to whom?


Client-Server


  • Server: offers a service, waits for requests.
  • Client: uses the service, starts the communication.
  • Roles are fixed. The server does not know the clients in advance.

Examples: web (browser ↔ web server), e-mail (client ↔ mail server), database access.

✅ Pros❌ Cons
simple, easy to understandserver is a single point of failure
central control over data & securityserver can become a bottleneck

Multi-Tier (e.g. 3-Tier) Architecture


An extension of client-server: the server side is split into layers (tiers):

  1. Presentation tier – user interface (browser, app)
  2. Logic tier – business rules (“a student may only borrow 3 books”)
  3. Data tier – persistent storage (database)

Each tier only talks to its neighbour. This is the classic architecture of most web applications.


Peer-to-Peer (P2P)


  • All nodes (peers) are equal — each one is client and server.
  • No central server (or only a small one to find other peers).
✅ Pros❌ Cons
no single point of failurehard to control / secure
scales with the number of usersfinding data is complex
peers come and go at any time

Microservices


The application is split into many small, independent services:

  • each service does one thing (users, orders, payment …)
  • each has its own database — nobody else accesses it directly
  • each can be developed, deployed and scaled independently (often by its own team)
  • they communicate only via APIs (or messages)
  • an API Gateway is the single entry point for clients

Microservices are the opposite of a monolith. They solve organisational and scaling problems — and create many new communication problems.


Event-driven / Publish-Subscribe


  • A publisher sends a message (event) to a topic on a message broker.
  • All subscribers of that topic receive the message.
  • Publisher and subscribers do not know each other.

Example: “Order created” → the e-mail service sends a confirmation, analytics updates the statistics, the warehouse starts packing. The order service does not need to know any of them.

Technologies: MQTT (IoT), AMQP / RabbitMQ, Apache Kafka.


Architectures – overview

ArchitectureWho talks to whom?Typical use
Client-Servermany clients → one serverweb, e-mail, databases
Multi-Tierpresentation → logic → dataweb applications
Peer-to-Peereveryone ↔ everyonefile sharing, blockchain
Microservicesservices ↔ services via APIslarge web platforms
Event-drivenpublisher → broker → subscribersIoT, decoupled workflows

Real systems usually combine several of these.


Part 2: Requirements

What makes a distributed system good? And why is it hard?


Functional vs. non-functional requirements

  • Functional requirements – what the system does
    • “A user can place an order.”
    • “A teacher can enter grades.”
  • Non-functional requirements (quality attributes) – how well it does it
    • “The page loads in under 1 second.”
    • “The system is available 99.9 % of the time.”

For distributed systems the non-functional requirements are the hard part.


Transparency

The user should not notice that the system is distributed. The system hides:

TransparencyHides …Example
Accesshow a resource is accesseda network drive looks like a local folder
Locationwhere a resource iswww.google.com – you don’t know which server answers
Replicationthat copies existyour Instagram photo is stored many times
Failurethat a part has faileda server crashes, another one answers
Concurrencythat others use it at the same timethousands buy concert tickets at once

Scalability

The system can handle more load by adding resources.

  • Vertical scaling (scale up): a bigger machine.
  • Horizontal scaling (scale out): more machines + a load balancer.

Horizontal scaling only works if the software is built for it — e.g. a server must not keep user data only in its own memory (→ stateless services).


Availability

What percentage of the time is the system usable?

AvailabilityDowntime per year
99 %≈ 3.65 days”two nines”
99.9 %≈ 8.8 hours”three nines”
99.99 %≈ 53 minutes”four nines”
99.999 %≈ 5 minutes”five nines”

⚠️ Dependencies multiply: if a request needs service A (99.9 %) and service B (99.9 %), the total availability is only 0.999 × 0.999 ≈ 99.8 %.

→ more parts = more things that can break → redundancy (several copies) is needed.


Fault tolerance

In a distributed system something is always broken somewhere.

  • Partial failure: one part fails, the rest keeps running — but you may not even know which part failed.
  • A missing answer can mean: the request got lost, the server crashed, the server is slow, or the answer got lost.

Typical techniques:

  • Timeouts – don’t wait forever
  • Retries – try again (but careful: don’t order the pizza twice! → idempotency)
  • Redundancy / replication – several copies of data and services
  • Graceful degradation – if recommendations fail, still show the shop

Consistency & the CAP theorem

If data is stored on several nodes: does everybody see the same data at the same time?


CAP theorem (Eric Brewer, 2000): when the network is split (Partition), a system can either stay Consistent or Available — not both.

  • Strong consistency: every read returns the latest write (banking).
  • Eventual consistency: copies become equal after a short time (likes, view counters, DNS).

Performance & latency

Every network message costs time.

ActionApprox. time
read from RAM~0.0001 ms
read from SSD~0.1 ms
round trip within a data center~0.5 ms
round trip Vienna ↔ New York~100 ms

A function call in a monolith is ~1 million times faster than a network call. Design consequence: don’t send 100 small requests if one bigger request does the job.


Security

The network is not a trusted place:

  • Confidentiality – nobody else can read the data → encryption (TLS / HTTPS)
  • Integrity – nobody can change the data on the way
  • Authentication – who are you? (login, API keys, tokens)
  • Authorization – what are you allowed to do?

Every interface that is reachable over the network is a potential attack surface.


The 8 Fallacies of Distributed Computing

False assumptions that developers new to distributed systems typically make (L. Peter Deutsch & others, Sun Microsystems):

  1. The network is reliable.
  2. Latency is zero.
  3. Bandwidth is infinite.
  4. The network is secure.
  5. Topology doesn’t change.
  6. There is one administrator.
  7. Transport cost is zero.
  8. The network is homogeneous.

👉 All eight are wrong. Good distributed systems are designed with this in mind.


Requirements – overview

RequirementQuestion
TransparencyDoes the user notice the distribution?
ScalabilityCan it handle 10× more users?
AvailabilityIs it reachable when needed?
Fault toleranceWhat happens if a part fails?
ConsistencyDoes everyone see the same data?
PerformanceHow fast are the answers?
SecurityWho can read / change what?
MaintainabilityCan parts be changed without breaking others?

Many of these conflict with each other (e.g. consistency vs. availability, security vs. performance). Designing distributed systems means making trade-offs.


Part 3: Interfaces

The parts of a distributed system must talk to each other. How do they agree on how to talk?


Communication: synchronous vs. asynchronous


SynchronousAsynchronous
Senderwaits for the answercontinues immediately
Coupling in timeboth must be onlinereceiver can be offline
ExampleHTTP request, phone callmessage queue, e-mail, SMS
Good for”I need the answer now""something happened, react to it”

What is an interface?

An interface is the boundary between two components: everything one side needs to know to use the other.


  • The interface is a contract between provider and consumer.
  • The provider is a black box: how it works internally is hidden (information hiding).
  • As long as the contract stays the same, the provider can change its implementation freely.

Interfaces exist everywhere: a power socket, USB, a C# interface, a REST API …


Kinds of interfaces

KindExampleWhere?
Hardware interfaceUSB, HDMI, Ethernet portbetween devices
Library interfaceList<T>.Add(), Math.Sqrt()in the same process
OS interfacesystem calls: open(), read()program ↔ operating system
Network / remote interfaceGET /api/students/42between processes over a network

In distributed systems we care about the last one. It is usually called an API (Application Programming Interface) — and it needs a protocol to travel over the network (→ next scriptum).


Coupling

How strongly do two components depend on each other?


  • Tight coupling: A knows internals of B (its database, its classes). Every change in B can break A.
  • Loose coupling: A only knows B’s interface. B can change everything behind it.

Goal: high cohesion inside a component, loose coupling between components.


Part 4: Interface Design

A good interface is hard to change later — so it is worth designing it carefully.


Principles of good interface design

  1. Design for the consumer – what does the user of the interface need? (not: what does my database look like?)
  2. Consistency – same naming, same structure, same error format everywhere.
  3. Clear, self-explaining names – getStudentById beats gsbi.
  4. Keep it minimal – every operation you publish, you have to support forever.
  5. Hide implementation details – never expose database IDs, table names or stack traces just because it is easy.
  6. Clear error handling – the consumer must be able to tell what went wrong and whose fault it was.
  7. Document it – an interface without documentation does not exist for others.
  8. Secure by default – authentication, validation of all input.

Granularity: chatty vs. chunky

Network calls are expensive (→ latency). How much should one call do?

Chatty (many small calls):

getStudentName(42)
getStudentClass(42)
getStudentBirthday(42)

Chunky (one call with everything needed):

getStudent(42) → { name, class, birthday }

Too fine = slow. Too coarse = consumers get lots of data they don’t need. → design along the use cases of the consumer.


Contract-first vs. code-first

Contract-first (design-first)Code-first
1. write the interface description1. write the code
2. agree on it with all teams2. generate the description from the code
3. implement both sides in parallel3. others use it
✅ well-thought-out, teams work in parallel✅ fast to start
❌ more work upfront❌ interface follows the implementation, not the needs

The interface description is written in a machine-readable format (e.g. OpenAPI) .


Changing interfaces: versioning & compatibility

Once others use your interface, you can’t just change it.

ChangeBreaking?
add a new optional field to the response✅ non-breaking
add a new operation✅ non-breaking
add a new required input field❌ breaking
rename or remove a field❌ breaking
change a data type ("42" → 42)❌ breaking
change the meaning of a value❌ breaking (and the worst kind!)

Breaking changes need a new version (e.g. /api/v2/...) — and the old version must keep running for a while.


Robustness principle (Postel’s law): “Be conservative in what you send, be liberal in what you accept.”


Idempotency

An operation is idempotent if executing it once or several times has the same effect.

OperationIdempotent?
“set the temperature to 21 °C”✅ yes
”delete order 17”✅ yes (after the first call it is gone)
“increase the temperature by 1 °C”❌ no
”create a new order”❌ no

Why does this matter? Because of the network: if you get no answer, you don’t know if the request arrived. With idempotent operations you can simply retry safely.


Summary

  • A distributed system = independent computers that communicate via messages and look like one system.
  • Architectures: client-server, multi-tier, peer-to-peer, microservices, event-driven.
  • Requirements: transparency, scalability, availability, fault tolerance, consistency, performance, security — often in conflict (CAP!).
  • The network is unreliable, slow and insecure (8 fallacies).
  • Components communicate via interfaces = contracts. Goal: loose coupling.
  • Good interfaces are consumer-oriented, consistent, minimal, documented, versioned and ideally idempotent.

Exercises

1 – Recognise the architecture

Which architecture(s) do the following systems use? Justify your answer.

  1. Minecraft multiplayer server
  2. BitTorrent
  3. WebUntis
  4. A smart-home system with temperature sensors and a dashboard app
  5. Netflix

2 – Fallacies in practice

Which of the 8 fallacies did the developer forget?

  1. The app shows a loading spinner forever when the train enters a tunnel.
  2. A mobile app downloads 50 MB of images on every start.
  3. Passwords are sent unencrypted because “it’s only our internal network”.
  4. A service stops working because the IP address of the database server changed.
  5. The app calls the server 200 times to build one page — works fine at home, terrible on mobile data.

3 – Availability

A web shop needs the following services for one order: Gateway (99.99 %), Order service (99.9 %), Payment service (99.9 %), Database (99.95 %).

  1. Calculate the total availability.
  2. How many hours per year is the shop not able to take orders?
  3. Suggest a measure to improve the availability.

4 – Design an interface

The school canteen wants to offer online ordering. Students should be able to see the menu of the week, order a meal for a specific day, and cancel an order up to 9:00 on that day.

  1. List the operations the interface needs (name, input, output).
  2. Which errors can occur? How should the consumer be informed?
  3. Which operations are idempotent?
  4. Half a year later, the canteen wants to add allergen information to the menu and make the class a required field when ordering. Which change is breaking, which isn’t?