<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>System Design on Software Engineering Learning Paths</title><link>https://kyngo.github.io/learning-paths/paths/system-design/</link><description>Recent content in System Design on Software Engineering Learning Paths</description><generator>Hugo</generator><language>en</language><atom:link href="https://kyngo.github.io/learning-paths/paths/system-design/index.xml" rel="self" type="application/rss+xml"/><item><title>Fundamentals</title><link>https://kyngo.github.io/learning-paths/paths/system-design/01-fundamentals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/01-fundamentals/</guid><description>&lt;h2 id="why-system-design"&gt;Why System Design?&lt;a class="anchor" href="#why-system-design"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Writing code that works on your laptop is one skill. Designing systems that serve millions of users reliably is another. System design is about making &lt;strong&gt;tradeoffs&lt;/strong&gt; — every choice has consequences for scalability, reliability, cost, and complexity.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="core-metrics"&gt;Core Metrics&lt;a class="anchor" href="#core-metrics"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="latency"&gt;Latency&lt;a class="anchor" href="#latency"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Time from request to response. Measured in milliseconds (ms).&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Operation&lt;/th&gt;
					&lt;th&gt;Typical Latency&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;L1 cache reference&lt;/td&gt;
					&lt;td&gt;0.5 ns&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;RAM access&lt;/td&gt;
					&lt;td&gt;100 ns&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SSD random read&lt;/td&gt;
					&lt;td&gt;150 μs&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HDD seek&lt;/td&gt;
					&lt;td&gt;10 ms&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Same-datacenter roundtrip&lt;/td&gt;
					&lt;td&gt;0.5 ms&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;US coast-to-coast roundtrip&lt;/td&gt;
					&lt;td&gt;40 ms&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Europe to US roundtrip&lt;/td&gt;
					&lt;td&gt;80 ms&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;P50 vs P95 vs P99:&lt;/strong&gt; Don&amp;rsquo;t measure averages — measure percentiles. P99 latency (worst 1% of requests) is what users feel during peak load.&lt;/p&gt;</description></item><item><title>Networking &amp; Protocols</title><link>https://kyngo.github.io/learning-paths/paths/system-design/02-networking-protocols/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/02-networking-protocols/</guid><description>&lt;h1 id="networking--protocols"&gt;Networking &amp;amp; Protocols&lt;a class="anchor" href="#networking--protocols"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Understanding how data moves across the network is the foundation of system design. Every architectural decision — from API style to database placement — is constrained by networking realities.&lt;/p&gt;
&lt;h2 id="dns-resolution"&gt;DNS Resolution&lt;a class="anchor" href="#dns-resolution"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Domain Name System translates human-readable domain names into IP addresses. A single page load may trigger dozens of DNS lookups.&lt;/p&gt;
&lt;h3 id="resolution-flow"&gt;Resolution Flow&lt;a class="anchor" href="#resolution-flow"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant Client
 participant Resolver as Recursive Resolver
 participant Root as Root NS
 participant TLD as TLD NS (.com)
 participant Auth as Authoritative NS

 Client-&amp;gt;&amp;gt;Resolver: Who is api.example.com?
 Resolver-&amp;gt;&amp;gt;Root: Who handles .com?
 Root--&amp;gt;&amp;gt;Resolver: Try TLD NS at 192.5.6.30
 Resolver-&amp;gt;&amp;gt;TLD: Who handles example.com?
 TLD--&amp;gt;&amp;gt;Resolver: Try Auth NS at 205.251.195.35
 Resolver-&amp;gt;&amp;gt;Auth: What is api.example.com?
 Auth--&amp;gt;&amp;gt;Resolver: A record: 93.184.216.34 (TTL 300s)
 Resolver--&amp;gt;&amp;gt;Client: 93.184.216.34&lt;/pre&gt;&lt;h3 id="dns-record-types"&gt;DNS Record Types&lt;a class="anchor" href="#dns-record-types"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Record&lt;/th&gt;
					&lt;th&gt;Purpose&lt;/th&gt;
					&lt;th&gt;Example&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;A&lt;/td&gt;
					&lt;td&gt;Maps name to IPv4 address&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;api.example.com → 93.184.216.34&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AAAA&lt;/td&gt;
					&lt;td&gt;Maps name to IPv6 address&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;api.example.com → 2606:2800:220:1:...&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CNAME&lt;/td&gt;
					&lt;td&gt;Alias to another domain name&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;www.example.com → example.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MX&lt;/td&gt;
					&lt;td&gt;Mail server routing&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;example.com → mail.example.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;NS&lt;/td&gt;
					&lt;td&gt;Delegates a zone to nameservers&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;example.com → ns1.provider.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SRV&lt;/td&gt;
					&lt;td&gt;Service discovery (host + port)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;_http._tcp.example.com → 8080 web1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TXT&lt;/td&gt;
					&lt;td&gt;Arbitrary text (SPF, verification)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;v=spf1 include:_spf.google.com&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="dns-caching-layers"&gt;DNS Caching Layers&lt;a class="anchor" href="#dns-caching-layers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Browser cache&lt;/strong&gt; — respects TTL from response&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OS resolver cache&lt;/strong&gt; — shared across all applications&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Router/ISP cache&lt;/strong&gt; — intermediate caching resolver&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recursive resolver&lt;/strong&gt; — (e.g., 8.8.8.8, 1.1.1.1) caches per TTL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Design implication:&lt;/strong&gt; Low TTLs (30–60s) enable fast failover but increase lookup latency. High TTLs (3600s+) improve performance but slow propagation of changes.&lt;/p&gt;</description></item><item><title>Load Balancing</title><link>https://kyngo.github.io/learning-paths/paths/system-design/03-load-balancing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/03-load-balancing/</guid><description>&lt;h1 id="load-balancing"&gt;Load Balancing&lt;a class="anchor" href="#load-balancing"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Load balancers distribute incoming traffic across multiple servers to improve availability, reliability, and performance. They are one of the most fundamental building blocks in scalable system design.&lt;/p&gt;
&lt;h2 id="why-load-balancers"&gt;Why Load Balancers?&lt;a class="anchor" href="#why-load-balancers"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Problem&lt;/th&gt;
					&lt;th&gt;How Load Balancing Solves It&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Single point of failure&lt;/td&gt;
					&lt;td&gt;Traffic reroutes to healthy servers if one dies&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Capacity limits&lt;/td&gt;
					&lt;td&gt;Spread load across multiple machines&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Uneven load distribution&lt;/td&gt;
					&lt;td&gt;Algorithms ensure balanced utilization&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Maintenance downtime&lt;/td&gt;
					&lt;td&gt;Drain connections before taking servers offline&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Geographic latency&lt;/td&gt;
					&lt;td&gt;Route to the nearest healthy endpoint&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="layer-4-vs-layer-7-load-balancing"&gt;Layer 4 vs Layer 7 Load Balancing&lt;a class="anchor" href="#layer-4-vs-layer-7-load-balancing"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;graph TD
 subgraph &amp;#34;OSI Model&amp;#34;
 L7[Layer 7 — Application: HTTP, gRPC, WebSocket]
 L4[Layer 4 — Transport: TCP, UDP]
 L3[Layer 3 — Network: IP]
 end

 subgraph &amp;#34;L4 Load Balancer&amp;#34;
 L4LB[Routes based on IP + Port&amp;lt;br/&amp;gt;No payload inspection]
 end

 subgraph &amp;#34;L7 Load Balancer&amp;#34;
 L7LB[Routes based on headers, URL path,&amp;lt;br/&amp;gt;cookies, content type]
 end&lt;/pre&gt;&lt;h3 id="comparison-table"&gt;Comparison Table&lt;a class="anchor" href="#comparison-table"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Feature&lt;/th&gt;
					&lt;th&gt;L4 Load Balancer&lt;/th&gt;
					&lt;th&gt;L7 Load Balancer&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Decision basis&lt;/td&gt;
					&lt;td&gt;IP address + TCP/UDP port&lt;/td&gt;
					&lt;td&gt;HTTP headers, URL, cookies, payload&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Performance&lt;/td&gt;
					&lt;td&gt;Faster (no payload parsing)&lt;/td&gt;
					&lt;td&gt;Slightly slower (must parse application data)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SSL termination&lt;/td&gt;
					&lt;td&gt;Typically no (pass-through)&lt;/td&gt;
					&lt;td&gt;Yes (terminates TLS, re-encrypts optionally)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Content routing&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;Yes (path-based, host-based routing)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;WebSocket support&lt;/td&gt;
					&lt;td&gt;Pass-through (no awareness)&lt;/td&gt;
					&lt;td&gt;Upgrade-aware, can route by path&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Health checks&lt;/td&gt;
					&lt;td&gt;TCP connect / port check&lt;/td&gt;
					&lt;td&gt;HTTP status codes, response body checks&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Connection pooling&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;Yes (reduces backend connections)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Sticky sessions&lt;/td&gt;
					&lt;td&gt;IP-based only&lt;/td&gt;
					&lt;td&gt;Cookie-based, header-based&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Use case&lt;/td&gt;
					&lt;td&gt;High-throughput TCP (databases, gRPC)&lt;/td&gt;
					&lt;td&gt;Web applications, APIs, microservices&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AWS equivalent&lt;/td&gt;
					&lt;td&gt;Network Load Balancer (NLB)&lt;/td&gt;
					&lt;td&gt;Application Load Balancer (ALB)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="load-balancing-algorithms"&gt;Load Balancing Algorithms&lt;a class="anchor" href="#load-balancing-algorithms"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="round-robin"&gt;Round Robin&lt;a class="anchor" href="#round-robin"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Distributes requests sequentially across all servers.&lt;/p&gt;</description></item><item><title>Caching</title><link>https://kyngo.github.io/learning-paths/paths/system-design/04-caching/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/04-caching/</guid><description>&lt;h1 id="caching"&gt;Caching&lt;a class="anchor" href="#caching"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Caching stores copies of data in a faster storage layer so future requests can be served without hitting the slower origin. It is the single most impactful technique for reducing latency and database load in distributed systems.&lt;/p&gt;
&lt;h2 id="the-cache-hierarchy"&gt;The Cache Hierarchy&lt;a class="anchor" href="#the-cache-hierarchy"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every request traverses multiple caching layers. Each layer trades freshness for speed.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 Client[Client Request] --&amp;gt; Browser[Browser Cache]
 Browser --&amp;gt;|Miss| CDN[CDN Edge Cache]
 CDN --&amp;gt;|Miss| LB[Load Balancer]
 LB --&amp;gt; AppCache[Application Cache&amp;lt;br/&amp;gt;Redis / Memcached]
 AppCache --&amp;gt;|Miss| DB[Database Query Cache]
 DB --&amp;gt;|Miss| Disk[Disk / Storage]

 style Browser fill:#e8f5e1
 style CDN fill:#e8f5e1
 style AppCache fill:#e3f2fd
 style DB fill:#fff3e0&lt;/pre&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Layer&lt;/th&gt;
					&lt;th&gt;Latency&lt;/th&gt;
					&lt;th&gt;Scope&lt;/th&gt;
					&lt;th&gt;Controlled By&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CPU cache (L1/L2/L3)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1–10 ns&lt;/td&gt;
					&lt;td&gt;Single process&lt;/td&gt;
					&lt;td&gt;Hardware&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;In-process cache&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;10–100 ns&lt;/td&gt;
					&lt;td&gt;Single instance&lt;/td&gt;
					&lt;td&gt;Application code&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Browser cache&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;0 ms (local)&lt;/td&gt;
					&lt;td&gt;Single user&lt;/td&gt;
					&lt;td&gt;Cache-Control headers&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CDN&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;5–50 ms&lt;/td&gt;
					&lt;td&gt;Geographic region&lt;/td&gt;
					&lt;td&gt;CDN config + headers&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Application cache (Redis)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1–5 ms&lt;/td&gt;
					&lt;td&gt;Cluster-wide&lt;/td&gt;
					&lt;td&gt;Application code&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Database query cache&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1–10 ms&lt;/td&gt;
					&lt;td&gt;Database cluster&lt;/td&gt;
					&lt;td&gt;DB configuration&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Database buffer pool&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;0.1–1 ms&lt;/td&gt;
					&lt;td&gt;Database instance&lt;/td&gt;
					&lt;td&gt;DB engine&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="caching-strategies"&gt;Caching Strategies&lt;a class="anchor" href="#caching-strategies"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="cache-aside-lazy-loading"&gt;Cache-Aside (Lazy Loading)&lt;a class="anchor" href="#cache-aside-lazy-loading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The application manages the cache explicitly.&lt;/p&gt;</description></item><item><title>Databases at Scale</title><link>https://kyngo.github.io/learning-paths/paths/system-design/05-databases-at-scale/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/05-databases-at-scale/</guid><description>&lt;h1 id="databases-at-scale"&gt;Databases at Scale&lt;a class="anchor" href="#databases-at-scale"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A single database server eventually becomes a bottleneck — whether for read throughput, write throughput, storage capacity, or availability. Scaling databases requires understanding replication, sharding, and the trade-offs each introduces.&lt;/p&gt;
&lt;h2 id="replication"&gt;Replication&lt;a class="anchor" href="#replication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Replication maintains copies of data across multiple database nodes for availability, durability, and read scaling.&lt;/p&gt;
&lt;h3 id="synchronous-vs-asynchronous-replication"&gt;Synchronous vs Asynchronous Replication&lt;a class="anchor" href="#synchronous-vs-asynchronous-replication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant Client
 participant Primary
 participant Replica1
 participant Replica2

 Note over Client,Replica2: Synchronous Replication
 Client-&amp;gt;&amp;gt;Primary: INSERT INTO orders...
 Primary-&amp;gt;&amp;gt;Replica1: Replicate (wait for ACK)
 Replica1--&amp;gt;&amp;gt;Primary: ACK
 Primary--&amp;gt;&amp;gt;Client: Commit confirmed

 Note over Client,Replica2: Asynchronous Replication
 Client-&amp;gt;&amp;gt;Primary: INSERT INTO orders...
 Primary--&amp;gt;&amp;gt;Client: Commit confirmed (immediate)
 Primary-&amp;gt;&amp;gt;Replica2: Replicate (eventual)&lt;/pre&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Aspect&lt;/th&gt;
					&lt;th&gt;Synchronous&lt;/th&gt;
					&lt;th&gt;Asynchronous&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Write latency&lt;/td&gt;
					&lt;td&gt;Higher (wait for replica ACK)&lt;/td&gt;
					&lt;td&gt;Lower (immediate commit)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Data safety&lt;/td&gt;
					&lt;td&gt;Zero data loss on primary failure&lt;/td&gt;
					&lt;td&gt;Potential data loss (replication lag)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Availability&lt;/td&gt;
					&lt;td&gt;Slower (blocked if replica is down)&lt;/td&gt;
					&lt;td&gt;Higher (primary independent)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Consistency&lt;/td&gt;
					&lt;td&gt;Strong (replicas always current)&lt;/td&gt;
					&lt;td&gt;Eventual (replicas may lag)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Throughput&lt;/td&gt;
					&lt;td&gt;Lower (bounded by slowest replica)&lt;/td&gt;
					&lt;td&gt;Higher (primary writes freely)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Use case&lt;/td&gt;
					&lt;td&gt;Financial transactions, inventory&lt;/td&gt;
					&lt;td&gt;Analytics, read-heavy workloads&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="semi-synchronous"&gt;Semi-Synchronous&lt;a class="anchor" href="#semi-synchronous"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A hybrid: the primary waits for &lt;strong&gt;at least one&lt;/strong&gt; replica to acknowledge before confirming to the client. Other replicas receive updates asynchronously.&lt;/p&gt;</description></item><item><title>Message Queues &amp; Event-Driven Architecture</title><link>https://kyngo.github.io/learning-paths/paths/system-design/06-message-queues/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/06-message-queues/</guid><description>&lt;h1 id="message-queues--event-driven-architecture"&gt;Message Queues &amp;amp; Event-Driven Architecture&lt;a class="anchor" href="#message-queues--event-driven-architecture"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Asynchronous messaging is the backbone of scalable distributed systems. Instead of services waiting for each other synchronously, message queues decouple producers from consumers, enabling independent scaling, fault tolerance, and temporal decoupling.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="why-asynchronous-processing"&gt;Why Asynchronous Processing?&lt;a class="anchor" href="#why-asynchronous-processing"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Synchronous communication (request-response) creates tight coupling between services. If the downstream service is slow or down, the upstream service is directly impacted.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Concern&lt;/th&gt;
					&lt;th&gt;Synchronous&lt;/th&gt;
					&lt;th&gt;Asynchronous&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Coupling&lt;/td&gt;
					&lt;td&gt;Tight — caller waits for response&lt;/td&gt;
					&lt;td&gt;Loose — producer doesn&amp;rsquo;t know consumer&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Latency&lt;/td&gt;
					&lt;td&gt;Cumulative across call chain&lt;/td&gt;
					&lt;td&gt;Producer returns immediately&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Failure handling&lt;/td&gt;
					&lt;td&gt;Cascading failures&lt;/td&gt;
					&lt;td&gt;Failures isolated to consumer&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Scaling&lt;/td&gt;
					&lt;td&gt;Both sides must scale together&lt;/td&gt;
					&lt;td&gt;Producer and consumer scale independently&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ordering&lt;/td&gt;
					&lt;td&gt;Implicit (request-response)&lt;/td&gt;
					&lt;td&gt;Must be explicitly managed&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Complexity&lt;/td&gt;
					&lt;td&gt;Simpler mental model&lt;/td&gt;
					&lt;td&gt;Requires queue infrastructure&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="when-to-use-async"&gt;When to Use Async&lt;a class="anchor" href="#when-to-use-async"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Task takes &amp;gt; 500ms&lt;/strong&gt; — don&amp;rsquo;t make the user wait for email sends, PDF generation, or analytics processing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spiky traffic&lt;/strong&gt; — buffer requests during peaks and process at a steady rate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-service coordination&lt;/strong&gt; — notify multiple services without coupling them&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retry-heavy operations&lt;/strong&gt; — let the queue handle retries rather than the caller&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="message-queue-vs-event-stream"&gt;Message Queue vs Event Stream&lt;a class="anchor" href="#message-queue-vs-event-stream"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These are fundamentally different communication models despite superficial similarities.&lt;/p&gt;</description></item><item><title>Microservices Architecture</title><link>https://kyngo.github.io/learning-paths/paths/system-design/07-microservices/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/07-microservices/</guid><description>&lt;h1 id="microservices-architecture"&gt;Microservices Architecture&lt;a class="anchor" href="#microservices-architecture"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Microservices decompose a system into small, independently deployable services, each owning a specific business capability. This architectural style enables teams to move fast and scale independently — but introduces significant distributed systems complexity.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="monolith-vs-microservices"&gt;Monolith vs Microservices&lt;a class="anchor" href="#monolith-vs-microservices"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Aspect&lt;/th&gt;
					&lt;th&gt;Monolith&lt;/th&gt;
					&lt;th&gt;Microservices&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Deployment&lt;/td&gt;
					&lt;td&gt;Single deployable unit&lt;/td&gt;
					&lt;td&gt;Each service deployed independently&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Scaling&lt;/td&gt;
					&lt;td&gt;Scale entire application&lt;/td&gt;
					&lt;td&gt;Scale individual services&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Technology&lt;/td&gt;
					&lt;td&gt;Single tech stack&lt;/td&gt;
					&lt;td&gt;Polyglot (per-service choice)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Data&lt;/td&gt;
					&lt;td&gt;Shared database&lt;/td&gt;
					&lt;td&gt;Database per service&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Team structure&lt;/td&gt;
					&lt;td&gt;One team or many teams on one codebase&lt;/td&gt;
					&lt;td&gt;Small teams per service (2-pizza rule)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Complexity&lt;/td&gt;
					&lt;td&gt;In-process calls, simple&lt;/td&gt;
					&lt;td&gt;Network calls, distributed complexity&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Consistency&lt;/td&gt;
					&lt;td&gt;Strong (ACID transactions)&lt;/td&gt;
					&lt;td&gt;Eventual consistency (sagas)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Testing&lt;/td&gt;
					&lt;td&gt;End-to-end straightforward&lt;/td&gt;
					&lt;td&gt;Integration testing complex&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Latency&lt;/td&gt;
					&lt;td&gt;In-process (nanoseconds)&lt;/td&gt;
					&lt;td&gt;Network (milliseconds)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debugging&lt;/td&gt;
					&lt;td&gt;Single process, stack traces&lt;/td&gt;
					&lt;td&gt;Distributed tracing required&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Initial velocity&lt;/td&gt;
					&lt;td&gt;Faster to start&lt;/td&gt;
					&lt;td&gt;Slower to start (infrastructure overhead)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Long-term velocity&lt;/td&gt;
					&lt;td&gt;Slows as codebase grows&lt;/td&gt;
					&lt;td&gt;Maintains speed per service&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="the-monolith-is-not-the-enemy"&gt;The Monolith Is Not the Enemy&lt;a class="anchor" href="#the-monolith-is-not-the-enemy"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A well-structured monolith (modular monolith) is a valid architecture. Many successful systems start as monoliths and only decompose when specific scaling or team boundaries demand it.&lt;/p&gt;</description></item><item><title>Storage &amp; Content Delivery Networks</title><link>https://kyngo.github.io/learning-paths/paths/system-design/08-storage-cdns/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/08-storage-cdns/</guid><description>&lt;h1 id="storage--content-delivery-networks"&gt;Storage &amp;amp; Content Delivery Networks&lt;a class="anchor" href="#storage--content-delivery-networks"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Choosing the right storage type and delivery mechanism directly impacts performance, cost, and reliability. This section covers cloud storage models, CDN architecture, and patterns for serving content at global scale.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="storage-types-compared"&gt;Storage Types Compared&lt;a class="anchor" href="#storage-types-compared"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Property&lt;/th&gt;
					&lt;th&gt;Object Storage (S3)&lt;/th&gt;
					&lt;th&gt;Block Storage (EBS)&lt;/th&gt;
					&lt;th&gt;File Storage (EFS)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Abstraction&lt;/td&gt;
					&lt;td&gt;Flat key-value (objects)&lt;/td&gt;
					&lt;td&gt;Raw disk blocks&lt;/td&gt;
					&lt;td&gt;Hierarchical file system&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Access pattern&lt;/td&gt;
					&lt;td&gt;HTTP API (GET/PUT)&lt;/td&gt;
					&lt;td&gt;Attached to single instance&lt;/td&gt;
					&lt;td&gt;Mounted by multiple instances (NFS)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Scalability&lt;/td&gt;
					&lt;td&gt;Virtually unlimited&lt;/td&gt;
					&lt;td&gt;Fixed size (resizable)&lt;/td&gt;
					&lt;td&gt;Grows automatically&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Latency&lt;/td&gt;
					&lt;td&gt;Higher (network, HTTP)&lt;/td&gt;
					&lt;td&gt;Very low (attached disk)&lt;/td&gt;
					&lt;td&gt;Low-moderate (network)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Durability&lt;/td&gt;
					&lt;td&gt;99.999999999% (11 nines)&lt;/td&gt;
					&lt;td&gt;99.999% (within AZ)&lt;/td&gt;
					&lt;td&gt;99.999999999% (multi-AZ)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Use case&lt;/td&gt;
					&lt;td&gt;Static assets, backups, data lakes&lt;/td&gt;
					&lt;td&gt;OS disks, databases&lt;/td&gt;
					&lt;td&gt;Shared config, CMS content&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Cost model&lt;/td&gt;
					&lt;td&gt;Per GB stored + requests&lt;/td&gt;
					&lt;td&gt;Per GB provisioned&lt;/td&gt;
					&lt;td&gt;Per GB used&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Concurrency&lt;/td&gt;
					&lt;td&gt;Unlimited concurrent readers&lt;/td&gt;
					&lt;td&gt;Single writer&lt;/td&gt;
					&lt;td&gt;Multiple readers/writers&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="when-to-use-each"&gt;When to Use Each&lt;a class="anchor" href="#when-to-use-each"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="mermaid"&gt;graph TD
 Q1{Need shared filesystem?} --&amp;gt;|Yes| EFS[EFS / File Storage]
 Q1 --&amp;gt;|No| Q2{Need low-latency block device?}
 Q2 --&amp;gt;|Yes| EBS[EBS / Block Storage]
 Q2 --&amp;gt;|No| S3[S3 / Object Storage]&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="object-storage-s3-deep-dive"&gt;Object Storage (S3) Deep Dive&lt;a class="anchor" href="#object-storage-s3-deep-dive"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="key-concepts"&gt;Key Concepts&lt;a class="anchor" href="#key-concepts"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bucket&lt;/strong&gt; — container for objects (globally unique name)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Object&lt;/strong&gt; — file + metadata, identified by a key (path-like string)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefix&lt;/strong&gt; — simulated folder structure (&lt;code&gt;images/2024/photo.jpg&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versioning&lt;/strong&gt; — keep multiple versions of every object&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lifecycle policies&lt;/strong&gt; — automatically transition or delete objects based on age&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="storage-classes-and-lifecycle"&gt;Storage Classes and Lifecycle&lt;a class="anchor" href="#storage-classes-and-lifecycle"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Storage Class&lt;/th&gt;
					&lt;th&gt;Access Pattern&lt;/th&gt;
					&lt;th&gt;Retrieval&lt;/th&gt;
					&lt;th&gt;Cost (relative)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 Standard&lt;/td&gt;
					&lt;td&gt;Frequent access&lt;/td&gt;
					&lt;td&gt;Immediate&lt;/td&gt;
					&lt;td&gt;$$$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 Intelligent-Tiering&lt;/td&gt;
					&lt;td&gt;Unknown/changing patterns&lt;/td&gt;
					&lt;td&gt;Immediate&lt;/td&gt;
					&lt;td&gt;$$ (auto-tiers)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 Standard-IA&lt;/td&gt;
					&lt;td&gt;Infrequent (monthly)&lt;/td&gt;
					&lt;td&gt;Immediate&lt;/td&gt;
					&lt;td&gt;$$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 One Zone-IA&lt;/td&gt;
					&lt;td&gt;Infrequent, non-critical&lt;/td&gt;
					&lt;td&gt;Immediate&lt;/td&gt;
					&lt;td&gt;$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 Glacier Instant&lt;/td&gt;
					&lt;td&gt;Rare, needs instant access&lt;/td&gt;
					&lt;td&gt;Immediate&lt;/td&gt;
					&lt;td&gt;$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 Glacier Flexible&lt;/td&gt;
					&lt;td&gt;Archival&lt;/td&gt;
					&lt;td&gt;Minutes to hours&lt;/td&gt;
					&lt;td&gt;¢&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;S3 Glacier Deep Archive&lt;/td&gt;
					&lt;td&gt;Compliance, long-term&lt;/td&gt;
					&lt;td&gt;12-48 hours&lt;/td&gt;
					&lt;td&gt;¢¢&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="lifecycle-policy-example"&gt;Lifecycle Policy Example&lt;a class="anchor" href="#lifecycle-policy-example"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Rules&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ArchiveOldLogs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Prefix&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;logs/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Transitions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;Days&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;StorageClass&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;STANDARD_IA&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;Days&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;StorageClass&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;GLACIER&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Expiration&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;Days&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="cdn-architecture"&gt;CDN Architecture&lt;a class="anchor" href="#cdn-architecture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Content Delivery Network (CDN) caches content at geographically distributed edge locations, reducing latency for end users by serving content from a nearby point of presence (PoP).&lt;/p&gt;</description></item><item><title>Reliability &amp; Resilience</title><link>https://kyngo.github.io/learning-paths/paths/system-design/09-reliability-resilience/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/09-reliability-resilience/</guid><description>&lt;h1 id="reliability--resilience"&gt;Reliability &amp;amp; Resilience&lt;a class="anchor" href="#reliability--resilience"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Failures are inevitable in distributed systems. Reliability engineering is about designing systems that continue operating correctly despite hardware failures, network partitions, software bugs, and operator errors. Resilience is the ability to recover quickly when failures occur.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="fault-tolerance-principles"&gt;Fault Tolerance Principles&lt;a class="anchor" href="#fault-tolerance-principles"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Principle&lt;/th&gt;
					&lt;th&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Assume failure&lt;/td&gt;
					&lt;td&gt;Design every component assuming it will fail&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Blast radius&lt;/td&gt;
					&lt;td&gt;Contain failures to the smallest possible scope&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Graceful degradation&lt;/td&gt;
					&lt;td&gt;Serve partial results rather than complete failure&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;No single point of failure&lt;/td&gt;
					&lt;td&gt;Every critical path has redundancy&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fail fast&lt;/td&gt;
					&lt;td&gt;Detect failures quickly rather than hanging&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Design for recovery&lt;/td&gt;
					&lt;td&gt;Optimise mean time to recovery (MTTR), not just mean time between failures (MTBF)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="failure-categories"&gt;Failure Categories&lt;a class="anchor" href="#failure-categories"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Type&lt;/th&gt;
					&lt;th&gt;Examples&lt;/th&gt;
					&lt;th&gt;Mitigation&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Hardware&lt;/td&gt;
					&lt;td&gt;Disk failure, server crash&lt;/td&gt;
					&lt;td&gt;Replication, multi-AZ&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Network&lt;/td&gt;
					&lt;td&gt;Partition, packet loss, high latency&lt;/td&gt;
					&lt;td&gt;Timeouts, retries, circuit breakers&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Software&lt;/td&gt;
					&lt;td&gt;Bugs, memory leaks, crashes&lt;/td&gt;
					&lt;td&gt;Health checks, auto-restart, canary deploys&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Dependency&lt;/td&gt;
					&lt;td&gt;Third-party API down&lt;/td&gt;
					&lt;td&gt;Circuit breaker, fallbacks, bulkheads&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Capacity&lt;/td&gt;
					&lt;td&gt;Traffic spike, resource exhaustion&lt;/td&gt;
					&lt;td&gt;Auto-scaling, rate limiting, load shedding&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Human&lt;/td&gt;
					&lt;td&gt;Misconfig, bad deploy&lt;/td&gt;
					&lt;td&gt;Canary releases, rollback procedures&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="redundancy-patterns"&gt;Redundancy Patterns&lt;a class="anchor" href="#redundancy-patterns"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="active-active"&gt;Active-Active&lt;a class="anchor" href="#active-active"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All instances handle traffic simultaneously. If one fails, the remaining instances absorb its load.&lt;/p&gt;</description></item><item><title>Observability</title><link>https://kyngo.github.io/learning-paths/paths/system-design/10-observability/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/10-observability/</guid><description>&lt;h1 id="observability"&gt;Observability&lt;a class="anchor" href="#observability"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Observability is the ability to understand the internal state of a system by examining its external outputs. In distributed systems, you cannot debug by attaching a debugger — you need telemetry: metrics, logs, and traces working together to answer &amp;ldquo;why is this broken?&amp;rdquo;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="observability-vs-monitoring"&gt;Observability vs Monitoring&lt;a class="anchor" href="#observability-vs-monitoring"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Aspect&lt;/th&gt;
					&lt;th&gt;Monitoring&lt;/th&gt;
					&lt;th&gt;Observability&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Approach&lt;/td&gt;
					&lt;td&gt;Predefined checks against known failures&lt;/td&gt;
					&lt;td&gt;Explore unknown failures dynamically&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Questions&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;Is the system up?&amp;rdquo; (known-knowns)&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;Why is it slow for user X?&amp;rdquo; (unknown-unknowns)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Data&lt;/td&gt;
					&lt;td&gt;Predefined metrics and thresholds&lt;/td&gt;
					&lt;td&gt;High-cardinality, high-dimensionality data&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Alerts&lt;/td&gt;
					&lt;td&gt;Threshold-based (CPU &amp;gt; 80%)&lt;/td&gt;
					&lt;td&gt;SLO burn-rate based&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Debug flow&lt;/td&gt;
					&lt;td&gt;Dashboard → runbook → fix&lt;/td&gt;
					&lt;td&gt;Query telemetry → form hypothesis → verify&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Monitoring tells you &lt;strong&gt;something is wrong&lt;/strong&gt;. Observability helps you understand &lt;strong&gt;why&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Security Architecture</title><link>https://kyngo.github.io/learning-paths/paths/system-design/11-security-architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/11-security-architecture/</guid><description>&lt;h1 id="security-architecture"&gt;Security Architecture&lt;a class="anchor" href="#security-architecture"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Security is not a feature you bolt on after launch — it is an architectural concern woven through every layer of the system. This section covers the patterns for authentication at scale, zero-trust networking, and secrets management in distributed systems.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="authentication-at-scale"&gt;Authentication at Scale&lt;a class="anchor" href="#authentication-at-scale"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="token-based-authentication-jwt"&gt;Token-Based Authentication (JWT)&lt;a class="anchor" href="#token-based-authentication-jwt"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Client → Login(credentials) → Auth Service → JWT ← Client stores token
Client → API Request + JWT → API Gateway → Validates JWT → Backend Service&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Component&lt;/th&gt;
					&lt;th&gt;Responsibility&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Auth Service&lt;/td&gt;
					&lt;td&gt;Validates credentials, issues tokens&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;JWT (access token)&lt;/td&gt;
					&lt;td&gt;Short-lived (5-15 min), carries claims (user ID, roles)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Refresh token&lt;/td&gt;
					&lt;td&gt;Long-lived (days/weeks), used to get new access tokens&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;API Gateway&lt;/td&gt;
					&lt;td&gt;Validates JWT signature, checks expiration, extracts claims&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="oauth-20--openid-connect-flows"&gt;OAuth 2.0 / OpenID Connect Flows&lt;a class="anchor" href="#oauth-20--openid-connect-flows"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Flow&lt;/th&gt;
					&lt;th&gt;Use Case&lt;/th&gt;
					&lt;th&gt;Example&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Authorization Code + PKCE&lt;/td&gt;
					&lt;td&gt;Web apps, SPAs, mobile&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;Log in with Google&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Client Credentials&lt;/td&gt;
					&lt;td&gt;Service-to-service&lt;/td&gt;
					&lt;td&gt;Backend calling another backend&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Device Authorization&lt;/td&gt;
					&lt;td&gt;Smart TVs, CLIs&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;Enter this code at example.com/device&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="session-vs-token"&gt;Session vs Token&lt;a class="anchor" href="#session-vs-token"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;Server-Side Sessions&lt;/th&gt;
					&lt;th&gt;JWT Tokens&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Storage&lt;/td&gt;
					&lt;td&gt;Server (Redis, DB)&lt;/td&gt;
					&lt;td&gt;Client (cookie, localStorage)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Revocation&lt;/td&gt;
					&lt;td&gt;Delete session record&lt;/td&gt;
					&lt;td&gt;Cannot revoke until expiry (unless denylist)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Scaling&lt;/td&gt;
					&lt;td&gt;Requires shared session store&lt;/td&gt;
					&lt;td&gt;Stateless — any server can validate&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Size&lt;/td&gt;
					&lt;td&gt;Session ID (small)&lt;/td&gt;
					&lt;td&gt;JWT payload (larger, contains claims)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="authorisation-patterns"&gt;Authorisation Patterns&lt;a class="anchor" href="#authorisation-patterns"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="rbac-role-based-access-control"&gt;RBAC (Role-Based Access Control)&lt;a class="anchor" href="#rbac-role-based-access-control"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;User → has → Role → has → Permissions
Alice → Admin → [read, write, delete]
Bob → Editor → [read, write]
Carol → Viewer → [read]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Simple, works for most applications. Breaks down when permissions depend on the specific resource.&lt;/p&gt;</description></item><item><title>Search &amp; Analytics</title><link>https://kyngo.github.io/learning-paths/paths/system-design/12-search-and-analytics/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/system-design/12-search-and-analytics/</guid><description>&lt;h1 id="search--analytics"&gt;Search &amp;amp; Analytics&lt;a class="anchor" href="#search--analytics"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Most applications eventually need full-text search, analytics dashboards, or both. This section covers the systems and patterns for indexing, querying, and analysing large datasets — from Elasticsearch to data lake architectures.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="full-text-search"&gt;Full-Text Search&lt;a class="anchor" href="#full-text-search"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="why-not-just-sql-like"&gt;Why Not Just SQL LIKE?&lt;a class="anchor" href="#why-not-just-sql-like"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;LIKE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%wireless headphones%&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Problem&lt;/th&gt;
					&lt;th&gt;Explanation&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;No relevance ranking&lt;/td&gt;
					&lt;td&gt;Results are unordered — no way to rank &amp;ldquo;best match&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;No fuzzy matching&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;headphnes&amp;rdquo; won&amp;rsquo;t match &amp;ldquo;headphones&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;No stemming&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;running&amp;rdquo; won&amp;rsquo;t match &amp;ldquo;run&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Full table scan&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;LIKE '%term%'&lt;/code&gt; cannot use indexes — O(n)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;No synonym support&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;laptop&amp;rdquo; won&amp;rsquo;t match &amp;ldquo;notebook&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="search-engine-architecture"&gt;Search Engine Architecture&lt;a class="anchor" href="#search-engine-architecture"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Documents → Analyser (tokenise, stem, normalise) → Inverted Index → Query → Ranked Results&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Inverted index:&lt;/strong&gt; maps each term to the list of documents containing it:&lt;/p&gt;</description></item></channel></rss>