<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Web Architecture on Noman Chowdhury Munna | Blog</title><link>http://hellonoman.dev/blog/categories/web-architecture/</link><description>Recent content in Web Architecture on Noman Chowdhury Munna | Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sat, 22 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://hellonoman.dev/blog/categories/web-architecture/index.xml" rel="self" type="application/rss+xml"/><item><title>Web Systems Architecture Foundations: From Sockets to Application Servers</title><link>http://hellonoman.dev/blog/p/web-architecture-foundations/</link><pubDate>Thu, 20 Aug 2026 00:00:00 +0000</pubDate><guid>http://hellonoman.dev/blog/p/web-architecture-foundations/</guid><description>&lt;img src="http://hellonoman.dev/blog/p/web-architecture-foundations/cover.png" alt="Featured image of post Web Systems Architecture Foundations: From Sockets to Application Servers" /&gt;&lt;p&gt;Welcome back, everyone. Take your seats.&lt;/p&gt;&#10;&lt;p&gt;Today we are kicking off our deep-dive series on modern backend engineering and infrastructure architecture. Before we talk about Kubernetes, load balancers, or fancy service meshes, we must build an unshakeable understanding of fundamental web mechanics.&lt;/p&gt;&#10;&lt;p&gt;If you don&amp;rsquo;t understand what actually happens at the OS and network level when a user clicks a button on a web page, you will spend your entire career Cargo-culting configuration files and scratching your head during production outages.&lt;/p&gt;&#10;&lt;p&gt;So let me strip away the magic. Grab your notebook, and let me examine the foundations of web systems architecture.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-the-client-server-model--life-of-a-request"&gt;1. The Client-Server Model &amp;amp; Life of a Request&#10;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s start with the baseline paradigm: &lt;strong&gt;Client-Server Architecture&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;In software engineering, client-server is a distributed application structure that partitions tasks or workloads between service providers (&lt;strong&gt;servers&lt;/strong&gt;) and service requesters (&lt;strong&gt;clients&lt;/strong&gt;).&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +------------------+ +-------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | | HTTP GET Request | |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | Client Browser | -------------------&amp;gt; | Web Server |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | (e.g., Chrome) | &amp;lt;------------------- | (e.g., Nginx) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | | HTTP 200 Response | |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +------------------+ +-------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;The Client&lt;/strong&gt;: Usually a web browser (Chrome, Firefox), a mobile application, or a CLI tool like &lt;code&gt;curl&lt;/code&gt;. It initiates communication by asking for a resource or sending data.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;The Server&lt;/strong&gt;: A machine (or software process) that waits passively for incoming network connections, processes requests, and returns responses.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="what-happens-when-you-type-httpsexamplecom-into-a-browser"&gt;What Happens When You Type &lt;code&gt;https://example.com&lt;/code&gt; into a Browser?&#10;&lt;/h3&gt;&lt;p&gt;This is a classic software engineering interview question, but more importantly, it tests your holistic understanding of networking. When a user hits &lt;code&gt;Enter&lt;/code&gt;, a precise chain of events triggers:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[User Types URL] -&amp;gt; [1. DNS Lookup] -&amp;gt; [2. TCP Handshake] -&amp;gt; [3. TLS Handshake] -&amp;gt; [4. HTTP Request] -&amp;gt; [5. Server Processing] -&amp;gt; [6. HTTP Response] -&amp;gt; [7. DOM Render]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;URL Parsing &amp;amp; Protocol Identification&lt;/strong&gt;: The browser parses &lt;code&gt;https://example.com&lt;/code&gt;, recognizing the protocol (&lt;code&gt;https://&lt;/code&gt;), domain name (&lt;code&gt;example.com&lt;/code&gt;), and implicit default port (&lt;code&gt;443&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;DNS Resolution&lt;/strong&gt;: The computer needs an IP address (e.g., &lt;code&gt;93.184.216.34&lt;/code&gt;). The browser checks its local cache, OS cache, router cache, and finally queries a Recursive DNS Resolver.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TCP Connection (3-Way Handshake)&lt;/strong&gt;: The browser opens a socket to port 443 at IP &lt;code&gt;93.184.216.34&lt;/code&gt;. The OS executes the TCP handshake: &lt;code&gt;SYN&lt;/code&gt; $\rightarrow$ &lt;code&gt;SYN-ACK&lt;/code&gt; $\rightarrow$ &lt;code&gt;ACK&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TLS Handshake&lt;/strong&gt;: Because the protocol is &lt;code&gt;HTTPS&lt;/code&gt;, the client and server negotiate encryption keys, exchange cryptographic certificates, and verify host identities.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;HTTP Request Transmission&lt;/strong&gt;: The browser sends an HTTP request payload over the encrypted TCP connection (e.g., &lt;code&gt;GET / HTTP/1.1\r\nHost: example.com...&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Server Processing &amp;amp; Response&lt;/strong&gt;: The server receives the bytes via socket buffers, processes the request (executing business logic or fetching static files), and writes an HTTP response back (&lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Client Rendering&lt;/strong&gt;: The browser receives HTML, parses the document tree (DOM), requests secondary assets (CSS, JS, images), executes JS, and renders the UI.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="2-dissecting-urls-hostnames-ips-ports-and-sockets"&gt;2. Dissecting URLs, Hostnames, IPs, Ports, and Sockets&#10;&lt;/h2&gt;&lt;p&gt;Students often mix up these terms. Let&amp;rsquo;s make the distinctions crystal clear.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Term&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;What it is&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Real-world Physical Analogy&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;IP Address&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The numerical network address of a machine on the internet (e.g., &lt;code&gt;192.168.1.1&lt;/code&gt; or &lt;code&gt;93.184.216.34&lt;/code&gt;).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The street address of an apartment building.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Port&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;A 16-bit integer (0–65535) identifying a specific process on that machine.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The apartment number inside the building.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Hostname&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;A human-readable name that maps to an IP address (e.g., &lt;code&gt;api.example.com&lt;/code&gt;).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The name of the building (&amp;ldquo;Empire State Building&amp;rdquo;).&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;URL&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Uniform Resource Locator: host + port + path + query parameters + protocol (&lt;code&gt;https://example.com:8080/users?id=5&lt;/code&gt;).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The complete mailing instructions to deliver a letter to a specific person.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Socket&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;An OS file descriptor representing an endpoint bound to an IP + Port pair (&lt;code&gt;192.168.1.1:443&lt;/code&gt;).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;The actual telephone plug in the wall connected to a phone line.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="what-does-it-mean-for-a-server-to-listen-on-a-port"&gt;What does it mean for a server to &amp;ldquo;listen&amp;rdquo; on a port?&#10;&lt;/h3&gt;&lt;p&gt;When you run a backend application (say, Python&amp;rsquo;s FastAPI or Node.js), the program makes system calls to the operating system kernel:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;socket()&lt;/code&gt;: Requests a network socket file descriptor.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;bind(IP, Port)&lt;/code&gt;: Tells the kernel &amp;ldquo;associate this socket with IP &lt;code&gt;0.0.0.0&lt;/code&gt; and Port &lt;code&gt;8000&lt;/code&gt;&amp;rdquo;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;listen()&lt;/code&gt;: Tells the kernel &amp;ldquo;accept incoming TCP connections on this socket and queue them up&amp;rdquo;.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;When a server is &amp;ldquo;listening,&amp;rdquo; the OS kernel handles the raw TCP packets in the background. When a client connects, the OS places the established socket in an accept queue for your application code to read.&lt;/p&gt;&#10;&lt;h3 id="exposing-a-port-to-the-internet"&gt;Exposing a Port to the Internet&#10;&lt;/h3&gt;&lt;p&gt;When you &lt;strong&gt;expose a port&lt;/strong&gt;, you configure your network interface and firewall (e.g., AWS Security Group, &lt;code&gt;ufw&lt;/code&gt;, or router port forwarding) to allow external IP addresses on the public internet to reach that listening socket port. If a port is bound to &lt;code&gt;127.0.0.1&lt;/code&gt; (localhost), it is strictly private to the machine. If it is bound to &lt;code&gt;0.0.0.0&lt;/code&gt; (all interfaces) and the firewall allows incoming traffic, it is publicly exposed.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="3-protocols-http-vs-https--dns"&gt;3. Protocols: HTTP vs. HTTPS &amp;amp; DNS&#10;&lt;/h2&gt;&lt;h3 id="http-hypertext-transfer-protocol"&gt;HTTP (Hypertext Transfer Protocol)&#10;&lt;/h3&gt;&lt;p&gt;HTTP is an application-layer request-response protocol running over TCP. It is completely plaintext. Anyone eavesdropping on the network path (Wi-Fi router, ISP, transit provider) can inspect, alter, or inject data into your traffic.&lt;/p&gt;&#10;&lt;h3 id="https-http-secure"&gt;HTTPS (HTTP Secure)&#10;&lt;/h3&gt;&lt;p&gt;HTTPS is standard HTTP wrapped inside &lt;strong&gt;TLS (Transport Layer Security)&lt;/strong&gt; encryption.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;span class="lnt"&gt;9&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| Application Layer: HTTP |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| Security Layer: TLS (Encryption) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| Transport Layer: TCP |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| Network Layer: IP |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;HTTPS guarantees three fundamental security principles:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Confidentiality&lt;/strong&gt;: Payload is encrypted; eavesdroppers see only random bytes.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Integrity&lt;/strong&gt;: Data cannot be tampered with in transit without detection.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Authentication&lt;/strong&gt;: Digital certificates issued by Certificate Authorities (CAs) prove that the server actually owns the requested domain.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="dns-domain-name-system"&gt;DNS (Domain Name System)&#10;&lt;/h3&gt;&lt;p&gt;DNS is the internet&amp;rsquo;s phonebook. It translates human-friendly hostnames (&lt;code&gt;example.com&lt;/code&gt;) into machine-routable IP addresses (&lt;code&gt;93.184.216.34&lt;/code&gt;). It operates primarily over &lt;strong&gt;UDP port 53&lt;/strong&gt; for quick request-response lookups.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="4-the-server-hierarchy-web-server-vs-application-server-vs-backend"&gt;4. The Server Hierarchy: Web Server vs. Application Server vs. Backend&#10;&lt;/h2&gt;&lt;p&gt;One of the biggest sources of confusion for junior engineers is distinguishing between &lt;strong&gt;Web Servers&lt;/strong&gt;, &lt;strong&gt;Application Servers&lt;/strong&gt;, and &lt;strong&gt;Backend Servers&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Public Internet ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v (Port 80/443 - Public)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+-------------------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| WEB SERVER (e.g., Nginx, Caddy, Apache) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| - TLS Termination |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| - Serves static assets (HTML/CSS/Images) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| - Rate limiting &amp;amp; request filtering |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+-------------------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v (Port 8000 - Internal Socket / Loopback)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+-------------------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| APPLICATION SERVER (e.g., Gunicorn, Uvicorn) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| - Runs dynamic code (Python, Node, Java, Go) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| - Manages WSGI/ASGI worker process pools |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+-------------------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v (Internal Database Protocol)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+-------------------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| BACKEND DATABASE (e.g., PostgreSQL, Redis) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| - Data persistence &amp;amp; business state |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+-------------------------------------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="1-web-server"&gt;1. Web Server&#10;&lt;/h3&gt;&lt;p&gt;A software application dedicated to handling HTTP protocols, serving static files directly from disk, managing TLS certificates, and forwarding dynamic requests.&#10;&lt;em&gt;Examples&lt;/em&gt;: Nginx, Apache HTTP Server, Caddy.&lt;/p&gt;&#10;&lt;h3 id="2-application-server"&gt;2. Application Server&#10;&lt;/h3&gt;&lt;p&gt;A runtime engine designed to execute dynamic programming code and business logic (Python, Java, Ruby, JS). It translates incoming raw HTTP payloads into programmatic objects (e.g., Python &lt;code&gt;dict&lt;/code&gt; or Express &lt;code&gt;req&lt;/code&gt;/&lt;code&gt;res&lt;/code&gt; objects).&#10;&lt;em&gt;Examples&lt;/em&gt;: Gunicorn / Uvicorn (Python), Puma (Ruby), Tomcat (Java), Node.js runtime.&lt;/p&gt;&#10;&lt;h3 id="3-backend-server"&gt;3. Backend Server&#10;&lt;/h3&gt;&lt;p&gt;A broader architectural term encompassing everything behind the user-facing tier—including application servers, background worker queues (Celery, BullMQ), microservices, and databases.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="5-why-cant-you-expose-your-application-server-directly-to-the-internet"&gt;5. Why Can&amp;rsquo;t You Expose Your Application Server Directly to the Internet?&#10;&lt;/h2&gt;&lt;p&gt;Students frequently ask me: &lt;em&gt;&amp;ldquo;Professor, my FastAPI/Node.js app has a built-in server. Why can&amp;rsquo;t I just bind it to port 80/443 on my VPS and expose it directly?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;Technically, you &lt;em&gt;can&lt;/em&gt;, but in production, &lt;strong&gt;this is an architectural sin&lt;/strong&gt;. Here is why:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Slow Client Attacks (Slowloris)&lt;/strong&gt;: Application servers (like Gunicorn or Node.js event loops) are optimized for complex business logic, not holding open thousands of idle connection threads. An attacker sending 1 byte every 10 seconds can quickly exhaust all worker threads, taking your app offline.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Poor Static Asset Performance&lt;/strong&gt;: Application servers execute code to serve files. Reading a static &lt;code&gt;logo.png&lt;/code&gt; off disk via Python or JS is 10x to 100x slower and consumes vastly more CPU/RAM than Nginx serving it using OS zero-copy &lt;code&gt;sendfile()&lt;/code&gt; kernel calls.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Security &amp;amp; Privilege Escalation&lt;/strong&gt;: Binding to ports below 1024 (like port 80 or 443) requires root privileges on Linux. Running your application code (FastAPI/Node) as root means any Remote Code Execution (RCE) vulnerability gives the attacker full control of your server.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Lack of Robust TLS Management&lt;/strong&gt;: Application runtime TLS stacks are rarely as optimized, battle-tested, or easily automated (via Certbot) as dedicated web servers like Nginx.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;No Zero-Downtime Reloads&lt;/strong&gt;: Modern web servers can reload their configuration and worker processes without dropping a single active TCP connection. Application runtimes typically require restarting the whole process.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="classroom-recap--concept-check"&gt;Classroom Recap &amp;amp; Concept Check&#10;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s review what we learned today:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Client-Server&lt;/strong&gt;: Clients request, servers listen on TCP sockets.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Port vs IP&lt;/strong&gt;: IP is the machine&amp;rsquo;s address; Port is the process doorway.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;DNS &amp;amp; Sockets&lt;/strong&gt;: DNS translates hostnames to IPs; Sockets are the OS file handles for networking.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Web vs App Server&lt;/strong&gt;: Web servers (Nginx) handle HTTP/TLS/Static files blazingly fast; App servers (Uvicorn/Gunicorn) run business logic.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Exposure&lt;/strong&gt;: Never expose app servers directly; place a dedicated web server or reverse proxy in front.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;In our next lecture, we will take this foundation and explore &lt;strong&gt;Reverse Proxies &amp;amp; Nginx Implementation&lt;/strong&gt; in depth. Class dismissed!&lt;/p&gt;&#10;</description></item><item><title>Demystifying Reverse Proxies &amp; Nginx: Architecture, Configuration &amp; Production Pitfalls</title><link>http://hellonoman.dev/blog/p/reverse-proxies-and-nginx-deep-dive/</link><pubDate>Fri, 21 Aug 2026 00:00:00 +0000</pubDate><guid>http://hellonoman.dev/blog/p/reverse-proxies-and-nginx-deep-dive/</guid><description>&lt;img src="http://hellonoman.dev/blog/p/reverse-proxies-and-nginx-deep-dive/cover.png" alt="Featured image of post Demystifying Reverse Proxies &amp; Nginx: Architecture, Configuration &amp; Production Pitfalls" /&gt;&lt;p&gt;Welcome back to Systems Architecture. Today, we are taking our foundational knowledge of web servers and diving headfirst into one of the most vital components of modern infrastructure: &lt;strong&gt;The Reverse Proxy&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;If you look at the infrastructure of Google, Netflix, or any modern startup, you will find reverse proxies standing at the edge of their networks. Today, we&amp;rsquo;re going to demystify what a reverse proxy is, why it&amp;rsquo;s called &amp;ldquo;reverse,&amp;rdquo; how Nginx implements it, and how to troubleshoot it when things inevitably explode in production.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-proxies-101-forward-proxy-vs-reverse-proxy"&gt;1. Proxies 101: Forward Proxy vs. Reverse Proxy&#10;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s start by clarifying the word &lt;strong&gt;proxy&lt;/strong&gt;. A proxy is simply an intermediary process that acts on behalf of another entity. But which entity is it acting on behalf of?&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FORWARD PROXY (Protects/Hides Clients)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Client A ] --\&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Client B ] ---&amp;gt; [ Forward Proxy ] ---------&amp;gt; [ Public Internet / Web Server ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Client C ] --/ (e.g., Corporate VPN) (Server sees ONLY Proxy IP)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-------------------------------------------------------------------------------&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;REVERSE PROXY (Protects/Hides Servers)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Public Client ] ---&amp;gt; [ Reverse Proxy ] ---\---&amp;gt; [ Backend Server 1 (FastAPI) ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(Client sees ONLY (e.g., Nginx) |---&amp;gt; [ Backend Server 2 (Node) ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Reverse Proxy IP) \---&amp;gt; [ Static File Storage ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="forward-proxy"&gt;Forward Proxy&#10;&lt;/h3&gt;&lt;p&gt;A &lt;strong&gt;Forward Proxy&lt;/strong&gt; sits in front of &lt;strong&gt;clients&lt;/strong&gt;. When you are on a corporate office network or using a VPN, your laptop sends traffic to the forward proxy first. The proxy forwards the request out to the internet, receives the response, and hands it back to your laptop.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Protects/hides clients, enforces content filtering (blocking social media at school), and circumvents geo-blocks.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Identity Awareness&lt;/strong&gt;: The client &lt;em&gt;knows&lt;/em&gt; the proxy exists (it&amp;rsquo;s configured in browser/network settings). The destination server on the internet has &lt;em&gt;no idea&lt;/em&gt; who the real client is—it only sees the proxy&amp;rsquo;s IP address.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="reverse-proxy"&gt;Reverse Proxy&#10;&lt;/h3&gt;&lt;p&gt;A &lt;strong&gt;Reverse Proxy&lt;/strong&gt; sits in front of &lt;strong&gt;backend servers&lt;/strong&gt;. It intercepts all incoming requests from the public internet and routes them to appropriate internal backend application instances.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Why is it called &amp;ldquo;Reverse&amp;rdquo;?&lt;/strong&gt;: Because it acts on behalf of the &lt;strong&gt;servers&lt;/strong&gt; rather than the clients. It sits at the destination network edge rather than the source network edge.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Identity Awareness&lt;/strong&gt;: The client believes it is talking directly to the destination server (e.g., &lt;code&gt;api.example.com&lt;/code&gt; resolves to Nginx&amp;rsquo;s IP). The client usually has &lt;em&gt;no idea&lt;/em&gt; that a reverse proxy is secretly sitting in front of 10 internal microservices.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="proxying-vs-redirecting"&gt;Proxying vs. Redirecting&#10;&lt;/h3&gt;&lt;p&gt;Do not confuse proxying with HTTP redirecting (&lt;code&gt;301 Moved Permanently&lt;/code&gt; or &lt;code&gt;302 Found&lt;/code&gt;):&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Redirecting&lt;/strong&gt;: Server responds to the browser with a &lt;code&gt;30x&lt;/code&gt; header and a &lt;code&gt;Location: https://new-site.com&lt;/code&gt; URL. The &lt;strong&gt;browser&amp;rsquo;s URL bar changes&lt;/strong&gt;, and the client opens a brand-new connection to the new URL.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Proxying&lt;/strong&gt;: The reverse proxy receives the request, internally fetches data from an upstream backend server, and returns it to the client. The &lt;strong&gt;browser&amp;rsquo;s URL bar does NOT change&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="2-core-problems-solved-by-a-reverse-proxy"&gt;2. Core Problems Solved by a Reverse Proxy&#10;&lt;/h2&gt;&lt;p&gt;Why do we put Nginx or HAProxy in front of our applications?&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Infrastructure Obfuscation &amp;amp; Security&lt;/strong&gt;: Hides internal backend IP addresses, network topology, and private ports. Attackers cannot directly port-scan or target internal application servers.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Host &amp;amp; Path Routing&lt;/strong&gt;: Exposes multiple applications (e.g., Next.js frontend, FastAPI backend, Go microservice) under a single public IP or single domain name (&lt;code&gt;example.com/api&lt;/code&gt; vs &lt;code&gt;example.com/&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TLS/SSL Termination&lt;/strong&gt;: Offloads CPU-heavy RSA/ECC cryptographic handshakes to Nginx, keeping application server code clean and fast.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Compression &amp;amp; Caching&lt;/strong&gt;: Compresses HTTP responses (gzip/brotli) and caches static assets in memory/disk before requests ever touch application servers.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Rate Limiting &amp;amp; Basic Auth&lt;/strong&gt;: Intercepts abusive traffic at the network perimeter.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="3-tls-mechanics-termination-vs-passthrough"&gt;3. TLS Mechanics: Termination vs. Passthrough&#10;&lt;/h2&gt;&lt;p&gt;When handling HTTPS, a reverse proxy can operate in two distinct modes:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TLS TERMINATION&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Client ] === (Encrypted HTTPS) ===&amp;gt; [ Nginx Proxy ] --- (Plain HTTP) ---&amp;gt; [ Backend App ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (Decrypts here)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TLS PASSTHROUGH (SSL Passthrough)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Client ] === (Encrypted HTTPS) ===&amp;gt; [ Nginx L4 Proxy ] === (Encrypted HTTPS) ===&amp;gt; [ Backend App ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (Passes raw TCP) (Decrypts here)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="tls-termination"&gt;TLS Termination&#10;&lt;/h3&gt;&lt;p&gt;The reverse proxy holds the SSL/TLS private key and certificate. It decrypts incoming HTTPS traffic from the client, inspects the HTTP headers/body, and forwards plaintext HTTP (or re-encrypted HTTP) over a secure private network to backend servers.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;: Centralized certificate management (via Certbot/Let&amp;rsquo;s Encrypt), enables HTTP header inspection/modification, response caching, and rate limiting.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="tls-passthrough"&gt;TLS Passthrough&#10;&lt;/h3&gt;&lt;p&gt;The proxy operates at Layer 4 (TCP) without decrypting traffic. It routes raw encrypted TLS bytes directly to the backend server, which holds the private key.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;: Zero-trust security (the proxy cannot read sensitive payload data).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;: Proxy cannot inspect HTTP headers, route by path (&lt;code&gt;/api&lt;/code&gt;), or inject &lt;code&gt;X-Forwarded-For&lt;/code&gt; headers.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="4-http-headers--the-x-forwarded-for-security-trap"&gt;4. HTTP Headers &amp;amp; The &lt;code&gt;X-Forwarded-For&lt;/code&gt; Security Trap&#10;&lt;/h2&gt;&lt;p&gt;Because a reverse proxy creates a &lt;em&gt;new&lt;/em&gt; TCP connection to the backend server, the backend server&amp;rsquo;s socket naturally sees &lt;code&gt;127.0.0.1&lt;/code&gt; or the proxy&amp;rsquo;s private IP as the client address!&lt;/p&gt;&#10;&lt;p&gt;To fix this, the proxy injects standardization headers into the request forwarded upstream:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;X-Forwarded-For&lt;/code&gt;: A comma-separated list of client and proxy IPs (&lt;code&gt;X-Forwarded-For: &amp;lt;client-ip&amp;gt;, &amp;lt;proxy1-ip&amp;gt;&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;X-Forwarded-Proto&lt;/code&gt;: Indicates the original protocol (&lt;code&gt;http&lt;/code&gt; or &lt;code&gt;https&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;X-Forwarded-Host&lt;/code&gt;: Indicates the original &lt;code&gt;Host&lt;/code&gt; header sent by the client.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Incoming Request: Client IP 203.0.113.19 -&amp;gt; Nginx (10.0.0.1) -&amp;gt; FastAPI (10.0.0.2)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Nginx injects headers upstream:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Host: api.example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; X-Real-IP: 203.0.113.19&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; X-Forwarded-For: 203.0.113.19&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; X-Forwarded-Proto: https&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="-the-dangerous-vulnerability-trusting-x-forwarded-for-blindly"&gt;⚠️ The Dangerous Vulnerability: Trusting &lt;code&gt;X-Forwarded-For&lt;/code&gt; Blindly&#10;&lt;/h3&gt;&lt;p&gt;Suppose your application checks client IP for rate-limiting or admin access using &lt;code&gt;request.headers.get(&amp;quot;X-Forwarded-For&amp;quot;)&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;If an attacker on the internet sends a request with a fake header:&#10;&lt;code&gt;X-Forwarded-For: 127.0.0.1&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;If Nginx simply appends to the incoming header, the header reaching FastAPI becomes:&#10;&lt;code&gt;X-Forwarded-For: 127.0.0.1, 203.0.113.19&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;If your backend code simply reads the &lt;em&gt;first&lt;/em&gt; IP in the list, &lt;strong&gt;the attacker just bypassed your IP restrictions!&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;: Always configure Nginx to clear or explicitly override &lt;code&gt;X-Forwarded-For&lt;/code&gt; with &lt;code&gt;$remote_addr&lt;/code&gt;, or configure your backend framework&amp;rsquo;s proxy middleware to trust only specific proxy IP ranges.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="5-nginx-hands-on-implementation"&gt;5. Nginx Hands-On Implementation&#10;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s look at real Nginx configuration files.&lt;/p&gt;&#10;&lt;h3 id="anatomy-of-nginx-location-block-matching"&gt;Anatomy of Nginx Location Block Matching&#10;&lt;/h3&gt;&lt;p&gt;When a request arrives, Nginx selects a &lt;code&gt;location&lt;/code&gt; block using this strict precedence order:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;location = /exact&lt;/code&gt;: Exact string match (Highest priority).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;location ^~ /images/&lt;/code&gt;: Preferential prefix match (Stops regex searching).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;location ~ \.(png|jpg)$&lt;/code&gt;: Case-sensitive Regex match.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;location ~* \.(png|jpg)$&lt;/code&gt;: Case-insensitive Regex match.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;location /prefix&lt;/code&gt;: Standard prefix match (Longest prefix wins).&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="proxy_pass-trailing-slash-gotcha"&gt;&lt;code&gt;proxy_pass&lt;/code&gt; Trailing Slash Gotcha!&#10;&lt;/h3&gt;&lt;p&gt;Pay extremely close attention to the trailing slash in &lt;code&gt;proxy_pass&lt;/code&gt;—this trips up developers every single day:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# CASE A: Trailing slash present on proxy_pass&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:8000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Request to /api/users/5 --&amp;gt; forwards to http://localhost:8000/users/5 (Strips /api)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# CASE B: NO Trailing slash on proxy_pass&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Request to /api/users/5 --&amp;gt; forwards to http://localhost:8000/api/users/5 (Preserves /api)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="production-config-nextjs-frontend--fastapi-backend--websockets"&gt;Production Config: Next.js Frontend + FastAPI Backend + WebSockets&#10;&lt;/h3&gt;&lt;p&gt;Here is a full production-ready Nginx configuration:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;span class="lnt"&gt;24&#10;&lt;/span&gt;&lt;span class="lnt"&gt;25&#10;&lt;/span&gt;&lt;span class="lnt"&gt;26&#10;&lt;/span&gt;&lt;span class="lnt"&gt;27&#10;&lt;/span&gt;&lt;span class="lnt"&gt;28&#10;&lt;/span&gt;&lt;span class="lnt"&gt;29&#10;&lt;/span&gt;&lt;span class="lnt"&gt;30&#10;&lt;/span&gt;&lt;span class="lnt"&gt;31&#10;&lt;/span&gt;&lt;span class="lnt"&gt;32&#10;&lt;/span&gt;&lt;span class="lnt"&gt;33&#10;&lt;/span&gt;&lt;span class="lnt"&gt;34&#10;&lt;/span&gt;&lt;span class="lnt"&gt;35&#10;&lt;/span&gt;&lt;span class="lnt"&gt;36&#10;&lt;/span&gt;&lt;span class="lnt"&gt;37&#10;&lt;/span&gt;&lt;span class="lnt"&gt;38&#10;&lt;/span&gt;&lt;span class="lnt"&gt;39&#10;&lt;/span&gt;&lt;span class="lnt"&gt;40&#10;&lt;/span&gt;&lt;span class="lnt"&gt;41&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# HTTP -&amp;gt; HTTPS Redirect&#10;&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;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt; &lt;span class="s"&gt;http2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="s"&gt;/etc/letsencrypt/live/example.com/fullchain.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="s"&gt;/etc/letsencrypt/live/example.com/privkey.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 1. Next.js Frontend&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2. FastAPI REST Backend&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:8000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Strips /api/ prefix&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;client_max_body_size&lt;/span&gt; &lt;span class="s"&gt;10M&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Handle large uploads&#10;&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;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 3. WebSocket Connection Upgrade&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/ws/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:8000/ws/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Upgrade&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Upgrade&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="s"&gt;86400s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Prevent WS idle timeout drop&#10;&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;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="6-troubleshooting-nginx-errors-in-production"&gt;6. Troubleshooting Nginx Errors in Production&#10;&lt;/h2&gt;&lt;p&gt;When Nginx throws an error, don&amp;rsquo;t panic. Check your &lt;code&gt;/var/log/nginx/error.log&lt;/code&gt; and use this diagnostic guide:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; INCOMING REQUEST&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [ Is Nginx Running? ] --- No ---&amp;gt; Connection Refused&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [ Can Nginx reach Backend? ] --- No ---&amp;gt; 502 Bad Gateway&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [ Does Backend respond within timeout? ] --- No ---&amp;gt; 504 Gateway Timeout&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 200 OK / 400 / 500&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="1-502-bad-gateway"&gt;1. &lt;code&gt;502 Bad Gateway&lt;/code&gt;&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Meaning&lt;/strong&gt;: Nginx contacted the upstream backend socket, but received an invalid response, connection reset, or connection refused.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Common Causes&lt;/strong&gt;:&#10;&lt;ul&gt;&#10;&lt;li&gt;Backend server (FastAPI/Node) crashed or isn&amp;rsquo;t running.&lt;/li&gt;&#10;&lt;li&gt;Backend is listening on &lt;code&gt;127.0.0.1:8000&lt;/code&gt;, but Nginx is configured to proxy to &lt;code&gt;10.0.0.5:8000&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Permission denied on UNIX domain socket (&lt;code&gt;/tmp/uvicorn.sock&lt;/code&gt;).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="2-504-gateway-timeout"&gt;2. &lt;code&gt;504 Gateway Timeout&lt;/code&gt;&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Meaning&lt;/strong&gt;: Nginx successfully connected to the backend server, but the backend server failed to send a response within Nginx&amp;rsquo;s configured &lt;code&gt;proxy_read_timeout&lt;/code&gt; window.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Common Causes&lt;/strong&gt;:&#10;&lt;ul&gt;&#10;&lt;li&gt;Long-running SQL query or synchronous blocking operation in python code.&lt;/li&gt;&#10;&lt;li&gt;Downstream database deadlock.&lt;/li&gt;&#10;&lt;li&gt;Increase timeout in Nginx if expected: &lt;code&gt;proxy_read_timeout 120s;&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="7-what-happens-if-nginx-itself-goes-down-high-availability"&gt;7. What Happens If Nginx Itself Goes Down? (High Availability)&#10;&lt;/h2&gt;&lt;p&gt;If Nginx is your single entry point and Nginx crashes, your whole application goes down. How do we prevent this single point of failure (SPOF)?&lt;/p&gt;&#10;&lt;p&gt;We use &lt;strong&gt;High Availability (HA) with Keepalived &amp;amp; VRRP (Virtual Router Redundancy Protocol)&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [ Virtual IP (VIP): 192.168.1.100 ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +---------------------+---------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | (Active) | (Standby)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +------------------+ +------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | Nginx Server #1 | | Nginx Server #2 |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | (Master) | | (Backup) |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +------------------+ +------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;ol&gt;&#10;&lt;li&gt;Two Nginx servers share a single &lt;strong&gt;Virtual IP (VIP)&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;keepalived&lt;/code&gt; sends heartbeat packets over the local network.&lt;/li&gt;&#10;&lt;li&gt;If Nginx Server #1 fails, Server #2 instantly claims the Virtual IP in under 1 second. The client never notices an interruption!&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="classroom-summary--homework"&gt;Classroom Summary &amp;amp; Homework&#10;&lt;/h2&gt;&lt;p&gt;Today we mastered:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Forward proxies shield clients; Reverse proxies shield servers.&lt;/li&gt;&#10;&lt;li&gt;TLS termination simplifies backend code and accelerates handshake performance.&lt;/li&gt;&#10;&lt;li&gt;Always sanitize &lt;code&gt;X-Forwarded-For&lt;/code&gt; to prevent IP spoofing attacks.&lt;/li&gt;&#10;&lt;li&gt;Memorize &lt;code&gt;502&lt;/code&gt; (Backend down/unreachable) vs &lt;code&gt;504&lt;/code&gt; (Backend took too long).&lt;/li&gt;&#10;&lt;li&gt;Use VRRP/Keepalived to eliminate Nginx as a single point of failure.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Next class: &lt;strong&gt;Load Balancing Algorithms, Layer 4 vs Layer 7, and Sticky Sessions&lt;/strong&gt;. Class dismissed!&lt;/p&gt;&#10;</description></item><item><title>Load Balancing Mastery: L4 vs L7, Algorithms, Session Persistence &amp; Distributed Scaling</title><link>http://hellonoman.dev/blog/p/load-balancing-fundamentals-and-patterns/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>http://hellonoman.dev/blog/p/load-balancing-fundamentals-and-patterns/</guid><description>&lt;img src="http://hellonoman.dev/blog/p/load-balancing-fundamentals-and-patterns/cover.png" alt="Featured image of post Load Balancing Mastery: L4 vs L7, Algorithms, Session Persistence &amp; Distributed Scaling" /&gt;&lt;p&gt;Welcome back to Systems Architecture. In our previous lecture, we placed Nginx in front of a single backend server as a reverse proxy. But what happens when your application explodes in popularity and a single backend machine can no longer keep up with incoming traffic?&lt;/p&gt;&#10;&lt;p&gt;Today, we dive into &lt;strong&gt;Load Balancing&lt;/strong&gt;—the art and science of distributing network traffic across a pool of backend servers to achieve high availability, fault tolerance, and horizontal scalability.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-the-scaling-dilemma-vertical-vs-horizontal"&gt;1. The Scaling Dilemma: Vertical vs. Horizontal&#10;&lt;/h2&gt;&lt;p&gt;When a single server reaches 100% CPU or RAM utilization, you have two options to scale:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;VERTICAL SCALING (Scale Up) HORIZONTAL SCALING (Scale Out)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------+ +--------+ +--------+ +--------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| BIGGER SERVER | | Node 1 | | Node 2 | | Node 3 |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| 128 Cores, 512GB RAM | | 4 Cores| | 4 Cores| | 4 Cores|&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+------------------------+ +--------+ +--------+ +--------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(Single point of failure, expensive) (Requires a Load Balancer)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Dimension&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Vertical Scaling (Scale Up)&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Horizontal Scaling (Scale Out)&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Strategy&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Add more CPU, RAM, or NVMe storage to your existing server.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Add more cheap commodity server instances to a pool.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Cost Curve&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Non-linear / Exponentially expensive at high specs.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Linear cost curve (pay only for nodes added).&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Hardware Limit&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;You eventually hit motherboard &amp;amp; CPU socket physical ceilings.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Virtually unlimited (scale to thousands of nodes).&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Downtime&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Upgrading RAM/CPU requires shutting down the machine.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Zero downtime (dynamically add/remove nodes).&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Fault Tolerance&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Zero. If the big server hardware fails, everything goes down.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;High. If Node 1 crashes, Nodes 2 and 3 take the load.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Horizontal scaling is the foundation of modern cloud architecture. However, horizontal scaling &lt;strong&gt;requires a Load Balancer&lt;/strong&gt; to sit in front of the pool and decide which server gets which request.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="2-where-does-a-load-balancer-sit"&gt;2. Where Does a Load Balancer Sit?&#10;&lt;/h2&gt;&lt;p&gt;A Load Balancer (LB) sits between the clients (or reverse proxies) and the pool of worker instances:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;span class="lnt"&gt;9&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Public Clients ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ External Load Balancer ] (e.g., AWS ALB / HAProxy)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; +-------------------+-------------------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | | |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v v v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [ Backend App #1 ] [ Backend App #2 ] [ Backend App #3 ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="is-a-reverse-proxy-the-same-as-a-load-balancer"&gt;Is a Reverse Proxy the same as a Load Balancer?&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Reverse Proxy&lt;/strong&gt;: Primarily focused on acting on behalf of servers (TLS termination, header rewrite, caching, path routing).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Load Balancer&lt;/strong&gt;: Primarily focused on &lt;strong&gt;traffic distribution&lt;/strong&gt; across multiple targets.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Can one tool do both?&lt;/strong&gt;: Absolutely! Tools like &lt;strong&gt;Nginx, HAProxy, and Traefik&lt;/strong&gt; excel as both reverse proxies AND load balancers simultaneously.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="3-layer-4-vs-layer-7-load-balancing"&gt;3. Layer 4 vs. Layer 7 Load Balancing&#10;&lt;/h2&gt;&lt;p&gt;Load balancers operate at different layers of the OSI model. Choosing between Layer 4 (L4) and Layer 7 (L7) is one of the most critical design choices in system architecture.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OSI&lt;/span&gt; &lt;span class="n"&gt;LAYER&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Transport&lt;/span&gt; &lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;UDP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;Packet&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SRC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;203.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;113.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;3.4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="n"&gt;L4&lt;/span&gt; &lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;rewrites&lt;/span&gt; &lt;span class="ne"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NAT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;IPVS&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;eBPF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;Packet&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SRC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;203.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;113.5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.12&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&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="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;inspect&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------------------------------------------------------&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OSI&lt;/span&gt; &lt;span class="n"&gt;LAYER&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Application&lt;/span&gt; &lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;HTTPS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="n"&gt;L7&lt;/span&gt; &lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;decrypts&lt;/span&gt; &lt;span class="n"&gt;TLS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parses&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Forwarded&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Checkout&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Pool&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.12&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="detailed-comparison-l4-vs-l7"&gt;Detailed Comparison: L4 vs. L7&#10;&lt;/h3&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Feature&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Layer 4 Load Balancer (Transport)&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th style="text-align: left"&gt;Layer 7 Load Balancer (Application)&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;OSI Layer&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Layer 4 (TCP / UDP).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Layer 7 (HTTP / HTTPS / gRPC / WebSockets).&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Payload Visibility&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Blind to application data (no HTTP headers, cookies, or URL paths).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Full visibility into HTTP headers, cookies, paths, and JSON bodies.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Performance / Throughput&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Extremely fast (Millions of RPS). Minimal CPU overhead (packet routing in kernel).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Moderate (Hundreds of thousands of RPS). Requires CPU to parse HTTP/TLS.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Routing Capability&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;IP address &amp;amp; TCP/UDP port only.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;Path-based (&lt;code&gt;/api&lt;/code&gt;), Host-based (&lt;code&gt;api.com&lt;/code&gt;), Header/Cookie routing.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;TLS Handling&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;SSL Passthrough (no decryption).&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;TLS Termination (decryption &amp;amp; re-encryption).&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;AWS NLB, IPVS, HAProxy (TCP mode), F5 BIG-IP.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td style="text-align: left"&gt;AWS ALB, Nginx, HAProxy (HTTP mode), Envoy.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="4-load-balancing-algorithms"&gt;4. Load Balancing Algorithms&#10;&lt;/h2&gt;&lt;p&gt;How does the load balancer choose which backend server gets the next request?&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. ROUND-ROBIN 2. LEAST-CONNECTIONS 3. CONSISTENT HASHING&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Request 1 -&amp;gt; S1 Request -&amp;gt; S2 (Only 2 active) Hash(user_id=42) -&amp;gt; S3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Request 2 -&amp;gt; S2 (S1 has 15, S3 has 8) (Always routes user 42 to S3)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Request 3 -&amp;gt; S3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="1-round-robin--weighted-round-robin"&gt;1. Round-Robin &amp;amp; Weighted Round-Robin&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Standard Round-Robin&lt;/strong&gt;: Requests are distributed sequentially across servers ($S_1 \rightarrow S_2 \rightarrow S_3 \rightarrow S_1$). Assumes all servers have equal capacity and processing times.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Weighted Round-Robin&lt;/strong&gt;: Assigns weights to servers based on hardware spec ($S_1$: Weight 3, $S_2$: Weight 1). $S_1$ gets 3 requests for every 1 sent to $S_2$.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="2-least-connections"&gt;2. Least Connections&#10;&lt;/h3&gt;&lt;p&gt;Directs incoming requests to the server with the lowest number of active open connections. Ideal for long-running requests (e.g., file processing or WebSocket streams) where connection durations vary wildly.&lt;/p&gt;&#10;&lt;h3 id="3-ip-hash--consistent-hashing"&gt;3. IP-Hash &amp;amp; Consistent Hashing&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;IP-Hash&lt;/strong&gt;: Hashes the client IP address (&lt;code&gt;hash(Client_IP) % N_servers&lt;/code&gt;). Ensures a specific client consistently hits the same backend.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Consistent Hashing&lt;/strong&gt;: Hashes request keys onto a virtual ring. When adding or removing a server, only $\frac{1}{N}$ of keys need to be remapped, rather than re-shuffling the entire key space. Essential for distributed caching clusters (Memcached/Redis).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="5-health-checking--failover-mechanics"&gt;5. Health Checking &amp;amp; Failover Mechanics&#10;&lt;/h2&gt;&lt;p&gt;What happens if Backend Server 2 crashes or suffers a hardware kernel panic?&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ Load Balancer ] --- (1. Active Health Probe GET /health) ---&amp;gt; [ Server 1: 200 OK ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --- (2. Active Health Probe GET /health) ---&amp;gt; [ Server 2: TIMEOUT ] ❌&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [ LB Marks Server 2 DOWN &amp;amp; Evicts from Pool ] &amp;lt;------+&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="active-vs-passive-health-checks"&gt;Active vs. Passive Health Checks&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Active Health Check&lt;/strong&gt;: The load balancer periodically (e.g., every 5s) sends explicit probe requests (&lt;code&gt;GET /health&lt;/code&gt;) to each backend. If a server fails 3 consecutive checks (returns 5xx or times out), it is marked &lt;strong&gt;Unhealthy&lt;/strong&gt; and evicted from the pool.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Passive Health Check&lt;/strong&gt;: The LB monitors actual user traffic. If a backend fails 3 real client requests in a row, the LB temporarily suspends traffic to that instance.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="connection-draining-graceful-shutdown"&gt;Connection Draining (Graceful Shutdown)&#10;&lt;/h3&gt;&lt;p&gt;When deploying new code or terminating an auto-scaled instance, you don&amp;rsquo;t abruptly kill the server. The LB enables &lt;strong&gt;Connection Draining&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;LB stops sending &lt;em&gt;new&lt;/em&gt; incoming requests to the target server.&lt;/li&gt;&#10;&lt;li&gt;LB allows existing active requests/connections a grace period (e.g., 30–60 seconds) to complete.&lt;/li&gt;&#10;&lt;li&gt;Once active connections drop to zero, the server is safely shut down.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="6-session-persistence-sticky-sessions-vs-stateless-architecture"&gt;6. Session Persistence: Sticky Sessions vs. Stateless Architecture&#10;&lt;/h2&gt;&lt;p&gt;If a user logs in on Server 1, their session data is created. What happens when their next request lands on Server 2?&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;span class="lnt"&gt;9&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;STATEFUL&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Sticky&lt;/span&gt; &lt;span class="n"&gt;Sessions&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Anti&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Pattern&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;Scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&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="n"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;Load&lt;/span&gt; &lt;span class="n"&gt;Balancer&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cookie&lt;/span&gt; &lt;span class="n"&gt;says&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Holds&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;RAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Problem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;If&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;dies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;lost&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="n"&gt;Unbalanced&lt;/span&gt; &lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="n"&gt;across&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-------------------------------------------------------------------------------&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;STATELESS&lt;/span&gt; &lt;span class="n"&gt;ARCHITECTURE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Recommended&lt;/span&gt; &lt;span class="n"&gt;Production&lt;/span&gt; &lt;span class="n"&gt;Pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&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="n"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;Load&lt;/span&gt; &lt;span class="n"&gt;Balancer&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Reads&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;Central&lt;/span&gt; &lt;span class="n"&gt;Redis&lt;/span&gt; &lt;span class="n"&gt;Cluster&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Benefit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;fail&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;without&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="sticky-sessions-session-persistence"&gt;Sticky Sessions (Session Persistence)&#10;&lt;/h3&gt;&lt;p&gt;The load balancer inspects a cookie or IP hash to bind a client to a specific backend server.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Drawbacks&lt;/strong&gt;: Causes unequal server load (one heavy user can overload one server), breaks autoscaling, and user sessions are wiped if that specific server crashes.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="the-stateless-architecture-solution"&gt;The Stateless Architecture Solution&#10;&lt;/h3&gt;&lt;p&gt;Store session state &lt;strong&gt;outside&lt;/strong&gt; the application servers in a fast, distributed memory store like &lt;strong&gt;Redis&lt;/strong&gt; or use self-contained &lt;strong&gt;JWT (JSON Web Tokens)&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Backend app servers hold zero user state in local RAM.&lt;/li&gt;&#10;&lt;li&gt;Any request can hit any backend server interchangeably.&lt;/li&gt;&#10;&lt;li&gt;Servers can be added or destroyed dynamically without affecting connected users.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="7-global-load-balancing-anycast-dns-lb--cdns"&gt;7. Global Load Balancing: Anycast, DNS LB &amp;amp; CDNs&#10;&lt;/h2&gt;&lt;p&gt;At enterprise scale, load balancing isn&amp;rsquo;t just inside a single datacenter; it spans the planet.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ User in Tokyo ] -------&amp;gt; [ Anycast IP / DNS Geo-Routing ] -------&amp;gt; [ Tokyo Datacenter ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ User in Frankfurt ] ---&amp;gt; [ Anycast IP / DNS Geo-Routing ] -------&amp;gt; [ Frankfurt Datacenter ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;DNS Round-Robin / Geo-DNS&lt;/strong&gt;: DNS server returns different IP addresses based on the client&amp;rsquo;s geographic origin (resolving &lt;code&gt;example.com&lt;/code&gt; to Tokyo IP for Asian users).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Anycast BGP Routing&lt;/strong&gt;: Multiple datacenters across the globe advertise the exact same public IP address via Border Gateway Protocol (BGP). Internet routers automatically route client packets to the topologically closest datacenter!&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;CDN vs. Load Balancer&lt;/strong&gt;: A CDN (Cloudflare, Fastly) sits &lt;em&gt;in front&lt;/em&gt; of your load balancer. It caches static content (images, JS, CSS) at edge locations worldwide, absorbing up to 90% of traffic before it ever touches your primary load balancer.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="classroom-summary--key-takeaways"&gt;Classroom Summary &amp;amp; Key Takeaways&#10;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s review the main concepts:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Scaling&lt;/strong&gt;: Horizontal scaling out-classes vertical scaling in resilience and cost.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;L4 vs L7&lt;/strong&gt;: L4 is blistering fast packet routing; L7 is smart HTTP path/cookie routing.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Algorithms&lt;/strong&gt;: Use Least Connections for variable workloads, Consistent Hashing for caching.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Stateless Architecture&lt;/strong&gt;: Never rely on sticky sessions in production—offload state to Redis or use JWTs.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;High Availability&lt;/strong&gt;: Combine active health checks with connection draining for zero-downtime deploys.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Next lecture: &lt;strong&gt;API Gateways, Resilience Patterns (Circuit Breakers &amp;amp; Retries), and Distributed Tracing&lt;/strong&gt;. Class dismissed!&lt;/p&gt;&#10;</description></item></channel></rss>