HomeToolsAbout a20k

System Design Template in MermaidJS

Notice: when this page renders without a diagram, please refresh for it to properly load

Api Structure

graph LR
  A1[app/client] --> A2["HTTP Methods (get/put/post/delete)"]
  A2 --> A3[CDN]
  A3 --> A4[Load Balancer]
  A4 --> A5[Services 
  • Search
  • payment
  • order
  • success
] A5 --> A6[Servers
  • storages
  • payment
  • mySQL
] A6 --> A1

Caching

flowchart-elk LR
  A1[client]
  subgraph clients[future clients]
    A2[client]
    A3[client]
    A4[client]
  end
  B1[server]
  B3[cache]
  C1[DB]
  B1 <--(fetch fresh data)--> C1
  B3 <--> A2
  B3 <--> A3
  B3 <--> A4
  B1 --registers--> B3
  A1 <--(first req/res)--> B1

Client Server

flowchart TB
  subgraph client
    A1["browser"]
  end
  subgraph server
    B1[DNS]
    C1[Server]
  end
  A1 --(1. DNS Query)--> B1
  B1 --(2. IP Address)--> A1
  B1 ==(3. knows each other)=== C1
  A1 --(5. HTTP request (IP address + data))--> C1
  C1 --(4. Data to origin IP)--> A1

Load Balancer

graph LR
  subgraph clients
    A1[client]
    A2[client]
    A3[client]
    A4[client]
    A5[client]
  end

  subgraph LBs
    B1["load-balancer with increased power \n(vertical scaling)"]
    B2[load-balancer]
  end

  subgraph server
    C1[server]
  end

  A1 --> B1
  A2 --> B1
  A3 --> B1

  B1 <==works in parallel \n (horizontal scaling)==> B2

  A4 --> B2
  A5 --> B2 

  B1 --> C1
  B2 --> C1

MERN Stack Example

Tech Stack

flowchart-elk LR
  A1["Client (Browser)"] 
  A2["React Frontend Deployment"]
  A3["Backend Node/Express"] 
  A4["DB/SQL"]
  A1 <--> A2
  A2 <--> A3
  A3 <--> A4

Backend Flow

flowchart LR
  subgraph client
    A1[client]
  end
  subgraph server
    A2[server.js]
    A3["router (api.js)"]
    A4["controller/middlewares \n (CRUD and other lower level functionality)"]
  end
  subgraph database
    A5[DB]
  end
  A1 --1. fetch api--> A2
  A2 --2 (require router in server)--> A3
  A3 --3. .next()--> A4
  A4 <--4. data req--> A5
  A4 --5. data res--> A3
  A3 --6--> A2
  A2 --"7. res.locals(json)"--> A1

Network Protocol

IP Packet

Max size per packet:

  • 2^16 bytes = 0.065MB
[IP Header][IP Data]

TCP Layer

Size: multiple packets coordinated

[ [IP Header][TCP Header][IP Data] [IP Header][TCP Header][IP Data] ]

HTTP

[get /users][TCP/IP][TCP/IP][TCP/IP] [post /users][TCP/IP][TCP/IP][TCP/IP][TCP/IP]

Polling/Streaming

Polling

graph LR
  A1[client] --calls every x seconds--> A2[server]
  A2 --data received--> A1

Streaming

graph LR
  A1[client] <--continuous--> A2[server]

Proxy

Forward Proxy

graph LR
  A1[client]
  A2[proxy]
  A3[server]

  A1 --"client sends request to proxy"--> A2
  A2 --"proxy masks and server doesn't know the IP of client"--> A3
  A3 --"server sends response to proxy"--> A2
  A2 --"proxy forwards the result"--> A1

Reverse Proxy

graph LR
  A1[client]
  A2[reverse proxy]
  A3[server]
  
  A1 --"client sends req to DNS and receives IP of reverse proxy"--> A2
  A2 --"Reverse proxy filters, measures user data, caches, load balances"--> A3
  A3 --"server sends res to proxy"--> A2
  A2 --"client doesn't know IP of server"--> A1

Pub/Sub

graph LR
  subgraph publisher
    A1[publisher]
  end

  subgraph topics
    B1[Topics]
    B2[Topics]
    B3[Topics]
  end

  subgraph subscribers
    C1[Subscriber]
    C2[Subscriber]
    C3[Subscriber]
  end

  A1 --> B1
  A1 --> B2
  A1 --> B3

  B1 --"stream"--> C1
  C1 --"subscription"--> B1
  B2 --"stream"--> C1
  C1 --"subscription"--> B2

  B3 --"stream"--> C2
  C2 --"subscription"-->B3
  B3 --"stream"--> C3
  C3 --"subscription"-->B3

Rate Limit

Rate limit server

graph LR
  A1[client]
  A2[server]
  A3[DB]

  A1--"1. req"-->A2
  A2--"2. accepted"-->A3
  A3--"3. success"-->A2
  A2--"4a. success"-->A1
  A2--"4b. reject"-->A1

Rate limit 3rd party

graph LR
  subgraph clients
    A1[client]
    A2[client]
    A3[client]
  end

  subgraph loadbalancer
    B1["3pty (e.g. redis)"]
  end

  subgraph servers
    C1[server]
    C2[server]
  end

  subgraph database
    D1[DB]
  end

  A1 --req--> B1
  B1 --accept-->A1
  A2 <--> B1
  A3 --req-->B1
  B1 --reject-->A3

  B1 --> C1
  B1 --> C2

  C1 --> D1
  C2 --> D1

Replication

graph LR
  subgraph databases
    A1[US DB]
    A2[India DB]
  end

  A1 <--"updates each other"--> A2

  B1["faster US read of India data"]
  B2["faster India read of US data vs direct read of US DB (low latency)"]

  A1 --> B1
  A2 --> B2

Services Domain Calling Libraries

How to keep Controller skinny

graph LR
  AA01["Backend controller"] --(move to)--> AA03
  AA03["lib"] --> AA02["services domain"]
  AA02--(call as service)-->AA01

Storage

Disk

persists

Memory

does not persist

Webhook

graph LR
  A1[System A]
  A2[System B]

  B1[Event]
  
  C1["HTTP body (json or XML)"]
  C2["HTTP body (json or XML)"]

  D1[Post Received]
  D2["processing webhook request"]
  D3["Process complete"]
  
  E1[POST response]

  A1 --triggers--> B1
  B1 --req--> C1
  C1 --> A2
  A2 --> D1
  D1 --> D2
  D2 --> D3
  D3 --> C2
  C2 --> E1

© VincentVanKoh