<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Crack That Weekly]]></title><description><![CDATA[Build real systems from scratch in Python — coding interview prep for DevOps and backend engineers.]]></description><link>https://www.crackthat.io</link><image><url>https://substackcdn.com/image/fetch/$s_!qTv6!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad6caf2a-9a20-4f80-89de-4721f4eed0bd_257x257.png</url><title>Crack That Weekly</title><link>https://www.crackthat.io</link></image><generator>Substack</generator><lastBuildDate>Tue, 21 Apr 2026 03:37:47 GMT</lastBuildDate><atom:link href="https://www.crackthat.io/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Sharon Sahadevan]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[crackthat@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[crackthat@substack.com]]></itunes:email><itunes:name><![CDATA[Sharon Sahadevan]]></itunes:name></itunes:owner><itunes:author><![CDATA[Sharon Sahadevan]]></itunes:author><googleplay:owner><![CDATA[crackthat@substack.com]]></googleplay:owner><googleplay:email><![CDATA[crackthat@substack.com]]></googleplay:email><googleplay:author><![CDATA[Sharon Sahadevan]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Build a DNS Resolver in Python From Scratch]]></title><description><![CDATA[Build a recursive DNS resolver in Python with TTL caching. Learn the Chain of Responsibility pattern and how CoreDNS, Route53, and dig work under the hood.]]></description><link>https://www.crackthat.io/p/build-dns-resolver-python</link><guid isPermaLink="false">https://www.crackthat.io/p/build-dns-resolver-python</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Fri, 10 Apr 2026 16:14:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!05sY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every command you run hits DNS. Every curl, every kubectl, every terraform apply. Your browser made a DNS query to load this page. DNS is the most heavily used distributed system on the planet, and most engineers have never seen what happens inside a resolver.</p><p>Today we build one from scratch. A DNS resolver with TTL caching and the Chain of Responsibility pattern.</p><h2>The 3-Question Framework</h2><p><strong>What does the system DO?</strong> It translates domain names into IP addresses by walking the DNS hierarchy. This is the <strong>Chain of Responsibility pattern</strong>. A request passes through a chain of handlers (cache, hosts file, recursive resolver) until one of them can answer it.</p><p><strong>What operations must be FAST?</strong> Most DNS lookups should return instantly from cache. A dict with TTL gives us O(1) cache hits. Cache misses trigger network calls, which are slower but infrequent for popular domains.</p><p><strong>What is the core LOGIC?</strong> Recursive resolution. Start at the root DNS servers. They point you to the TLD servers (.com, .io). The TLD servers point you to the authoritative servers. The authoritative server gives you the final IP address. Cache every answer with its TTL so you only walk the tree once.</p><pre><code><code>Pattern:    Chain of Responsibility (cache -&gt; resolver -&gt; root -&gt; TLD -&gt; auth)
Structure:  dict with TTL (DNS cache)
Algorithm:  Recursive resolution with caching at every level
</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-z_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-z_E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 424w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 848w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1272w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-z_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png" width="1456" height="557" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:557,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-z_E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 424w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 848w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1272w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>How DNS Resolution Actually Works</h2><p>When you type crackthat.io in your browser, here is what happens:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4YNi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4YNi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 424w, https://substackcdn.com/image/fetch/$s_!4YNi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 848w, https://substackcdn.com/image/fetch/$s_!4YNi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!4YNi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4YNi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png" width="1456" height="828" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:828,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:245176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/191751112?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4YNi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 424w, https://substackcdn.com/image/fetch/$s_!4YNi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 848w, https://substackcdn.com/image/fetch/$s_!4YNi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!4YNi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e477e23-05c5-435a-83cf-7a3553882d76_2136x1214.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is a chain. Each handler either answers the question or passes it to the next handler in the chain. That is the Chain of Responsibility pattern.</p><p>The key insight: after the first lookup, Step 1 returns the answer instantly for the next 300 seconds. Without caching, every HTTP request would add 50 to 100ms walking the DNS tree.</p><h2>Step 1: The DNS Cache</h2><p>The foundation. A simple dict with TTL expiration. Same lazy expiration pattern from Issue 3.</p><pre><code><code>import time

class DNSCache:

    def __init__(self):
        self._cache = {}

    def get(self, domain, record_type="A"):
        key = (domain, record_type)
        entry = self._cache.get(key)
        if entry is None:
            return None
        if time.time() &gt; entry["expiry"]:
            del self._cache[key]
            return None
        return entry["value"]

    def put(self, domain, value, ttl, record_type="A"):
        key = (domain, record_type)
        self._cache[key] = {
            "value": value,
            "expiry": time.time() + ttl,
        }

    def size(self):
        return len(self._cache)
</code></code></pre><p><strong>Interview phrasing:</strong> &#8220;The DNS cache is a hash map keyed by (domain, record_type) with lazy TTL expiration. Same pattern as Redis. O(1) lookups. Expired entries are cleaned up on access.&#8221;</p><h2>Step 2: The Resolver</h2><p>The resolver sends a query to a DNS server and returns the IP address. We use Python&#8217;s socket library to make the actual network call.</p><pre><code><code>import socket

class DNSResolver:

    def __init__(self):
        self.cache = DNSCache()
        self._queries = 0

    def resolve(self, domain):
        cached = self.cache.get(domain)
        if cached:
            return cached

        ip = self._do_lookup(domain)
        if ip:
            self.cache.put(domain, ip, 300)
        return ip

    def _do_lookup(self, domain):
        self._queries += 1
        try:
            result = socket.getaddrinfo(domain, None, socket.AF_INET)
            if result:
                return result[0][4][0]
        except socket.gaierror:
            return None
        return None

    def stats(self):
        return {
            "cache_size": self.cache.size(),
            "queries_made": self._queries,
        }
</code></code></pre><p>On the first call, the resolver makes a real DNS query using the operating system&#8217;s resolver. The result is cached for 300 seconds. Every subsequent call for the same domain returns instantly from cache.</p><p>In production DNS servers like CoreDNS or Unbound, the resolver builds raw UDP packets and walks the tree from root servers to authoritative servers. Our implementation delegates to the OS for simplicity, but the caching and chain of responsibility architecture is identical.</p><p><strong>How production recursive resolution works:</strong></p><ol><li><p>Ask root server for crackthat.io</p></li><li><p>Root says &#8220;Try the .io TLD servers&#8221;</p></li><li><p>Ask .io TLD server for crackthat.io</p></li><li><p>TLD says &#8220;The authoritative server is ns1.vercel-dns.com&#8221;</p></li><li><p>Ask authoritative server for crackthat.io</p></li><li><p>Authoritative says &#8220;76.76.21.21&#8221; with TTL=300</p></li><li><p>Cache the answer and return the IP</p></li></ol><h2>Step 3: The Chain of Responsibility</h2><p>The Chain of Responsibility pattern makes the resolver extensible. Each handler tries to answer the query. If it cannot, it passes to the next handler.</p><pre><code><code>from abc import ABC, abstractmethod

class DNSHandler(ABC):

    def __init__(self):
        self._next = None

    def set_next(self, handler):
        self._next = handler
        return handler

    def pass_to_next(self, domain):
        if self._next:
            return self._next.handle(domain)
        return None

    @abstractmethod
    def handle(self, domain):
        pass


class CacheHandler(DNSHandler):

    def __init__(self, cache):
        super().__init__()
        self._cache = cache

    def handle(self, domain):
        result = self._cache.get(domain)
        if result:
            return result
        return self.pass_to_next(domain)

class HostsFileHandler(DNSHandler):
    """Check local host mappings before going to network."""

    def __init__(self, hosts_path=None):
        super().__init__()
        import os
        if hosts_path is None:
            hosts_path = os.path.join(os.sep, "etc", "hosts")
        self._hosts = self._load_hosts(hosts_path)

    def _load_hosts(self, path):
        hosts = {}
        try:
            with open(path) as f:
                for line in f:
                    line = line.strip()
                    if line and not line.startswith("#"):
                        parts = line.split()
                        if len(parts) &gt;= 2:
                            ip = parts[0]
                            for hostname in parts[1:]:
                                hosts[hostname] = ip
        except FileNotFoundError:
            pass
        return hosts

    def handle(self, domain):
        result = self._hosts.get(domain)
        if result:
            return result
        return self.pass_to_next(domain)


class RecursiveHandler(DNSHandler):

    def __init__(self, resolver):
        super().__init__()
        self._resolver = resolver

    def handle(self, domain):
        return self._resolver.resolve(domain)
</code></code></pre><p>Now we wire the chain together:</p><pre><code><code>def build_resolver_chain():
    cache = DNSCache()
    resolver = DNSResolver()
    resolver.cache = cache

    cache_handler = CacheHandler(cache)
    hosts_handler = HostsFileHandler()
    recursive_handler = RecursiveHandler(resolver)

    cache_handler.set_next(hosts_handler).set_next(recursive_handler)
    return cache_handler


chain = build_resolver_chain()
ip = chain.handle("crackthat.io")
print(f"crackthat.io resolved to {ip}")
</code></code></pre><p><strong>Why the chain matters:</strong></p><p>Most queries hit the cache handler and return in microseconds. Only cache misses reach the hosts file handler. Only misses from both reach the recursive handler which makes network calls. This is the same layered lookup your operating system uses:</p><ol><li><p>Application DNS cache (Chrome, Firefox)</p></li><li><p>OS resolver cache (the local hosts file, systemd-resolved)</p></li><li><p>Local recursive resolver (CoreDNS, dnsmasq)</p></li><li><p>Upstream recursive resolver (8.8.8.8, 1.1.1.1)</p></li><li><p>Root servers to TLD to Authoritative</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-z_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-z_E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 424w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 848w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1272w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-z_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png" width="1456" height="557" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:557,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:233607,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/191751112?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-z_E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 424w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 848w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1272w, https://substackcdn.com/image/fetch/$s_!-z_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026ebbdd-68c1-4bb8-8fd0-782ad1c25c7a_2180x834.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Comparison: DNS Resolution Strategies</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RdMI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RdMI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 424w, https://substackcdn.com/image/fetch/$s_!RdMI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 848w, https://substackcdn.com/image/fetch/$s_!RdMI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!RdMI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RdMI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png" width="1456" height="710" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:710,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:184700,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/191751112?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RdMI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 424w, https://substackcdn.com/image/fetch/$s_!RdMI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 848w, https://substackcdn.com/image/fetch/$s_!RdMI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!RdMI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F295e936a-c045-4c84-afdd-126f0a96b999_2124x1036.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The DevOps Connection</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!05sY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!05sY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 424w, https://substackcdn.com/image/fetch/$s_!05sY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 848w, https://substackcdn.com/image/fetch/$s_!05sY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 1272w, https://substackcdn.com/image/fetch/$s_!05sY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!05sY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png" width="1456" height="792" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:269256,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/191751112?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!05sY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 424w, https://substackcdn.com/image/fetch/$s_!05sY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 848w, https://substackcdn.com/image/fetch/$s_!05sY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 1272w, https://substackcdn.com/image/fetch/$s_!05sY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189ade30-3be4-4e8b-b1cc-eec4657ea5f0_2144x1166.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Scaling to Millions: DNS at Production Scale</h2><p>Our resolver handles one machine. Production DNS serves billions of queries per day across the globe. Here is how it scales.</p><p></p><div class="paywall-jump" data-component-name="PaywallToDOM"></div><p><strong>Anycast Routing</strong></p><p>Every root DNS server has one IP address, but that IP is announced from dozens of locations worldwide. When you query 198.41.0.4, your packets go to the nearest physical server. This is called anycast. Cloudflare uses the same technique for their 1.1.1.1 resolver. One IP, 300+ locations. Your query never crosses the ocean.</p><p><strong>GeoDNS</strong></p><p>A single domain can return different IP addresses based on where the client is. A user in Dubai gets routed to a server in the Middle East. A user in London gets routed to a server in Europe. Route53, Cloudflare, and Akamai all support this. It is how CDNs deliver content from the closest edge node.</p><p><strong>Caching Hierarchy</strong></p><p>Production DNS uses multiple layers of caching to absorb traffic before it reaches authoritative servers.</p><pre><code><code>Browser cache (Chrome, Firefox)
    -&gt; OS cache (systemd-resolved)
        -&gt; Local resolver (CoreDNS in your K8s cluster)
            -&gt; ISP resolver (your provider's DNS)
                -&gt; Authoritative server (only on full miss)</code></code></pre><p>Each layer absorbs 80 to 90% of queries. By the time a request reaches the authoritative server, it represents thousands of identical queries that were served from cache.</p><p><strong>Negative Caching</strong></p><p>Production resolvers also cache &#8220;domain not found&#8221; responses (NXDOMAIN). Without this, a typo like &#8220;gogle.com&#8221; would hit the authoritative server on every single request. Negative caching with a short TTL (30 to 60 seconds) prevents this.</p><p><strong>DNS Failover and Health Checks</strong></p><p>Route53 and Cloudflare support health checked DNS records. If a server fails its health check, the DNS record is automatically updated to point to a healthy server. The TTL on these records is kept low (30 to 60 seconds) so clients pick up the change quickly.</p><pre><code><code>Normal:     api.example.com -&gt; 10.0.0.1 (healthy)
Failover:   api.example.com -&gt; 10.0.0.2 (backup)
Recovery:   api.example.com -&gt; 10.0.0.1 (restored)</code></code></pre><p>This is the foundation of active/passive failover. Your Terraform configs probably already use this pattern.</p><p><strong>Rate Limiting DNS Servers</strong></p><p>At scale, DNS servers must protect themselves from abuse. Techniques include response rate limiting (RRL) to cap the number of identical responses per second, and query rate limiting per source IP. Without these, a DNS amplification attack can take down your resolver.</p><p><strong>Interview upgrade:</strong> When the interviewer asks about DNS, mention anycast for global distribution, caching hierarchy for traffic absorption, and health checked records for failover. This shows you think at production scale, not just single machine implementations.</p><div><hr></div><h2>Interview Walkthrough Script</h2><p>When the interviewer asks &#8220;Design a DNS resolver&#8221;:</p><blockquote><p><strong>&#8220;I would use the Chain of Responsibility pattern. A DNS query passes through a chain of handlers: first the local cache for O(1) lookups, then the hosts file, then a recursive resolver. The recursive resolver walks the DNS tree starting at root servers, following referrals through TLD servers to the authoritative server. Every response is cached with its TTL. Most production traffic hits the cache and returns in microseconds. For reliability I would add retry logic, multiple root servers, and negative caching for NXDOMAIN responses.&#8221;</strong></p></blockquote><h2>Challenge: Try It Yourself</h2><ol><li><p><strong>CNAME resolution.</strong> Add support for CNAME records. When you get a CNAME instead of an A record, resolve the CNAME target recursively.</p></li><li><p><strong>Negative caching.</strong> Cache NXDOMAIN (domain not found) responses too. This prevents repeated lookups for nonexistent domains.</p></li><li><p><strong>Benchmark cache hit rates.</strong> Resolve 1000 random domains, then resolve them again. Measure the hit rate and time difference.</p></li></ol><p><em>Next week: <strong>Build a Task Queue in Python (Priority Queue)</strong></em></p><p><em>Previous: <a href="https://crackthat.io/p/build-load-balancer-python">Build a Load Balancer</a> | <a href="https://crackthat.io/p/build-rate-limiter-python-sliding-window">Build a Rate Limiter</a> | <a href="https://crackthat.io/p/why-redis-uses-c-not-python-gil">The GIL Explained</a></em></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Build a Load Balancer in Python From Scratch]]></title><description><![CDATA[Build round-robin, weighted, and least-connections load balancing in Python. Learn the Strategy pattern and how nginx, HAProxy, and Kubernetes route traffic.]]></description><link>https://www.crackthat.io/p/build-a-load-balancer-in-python-from</link><guid isPermaLink="false">https://www.crackthat.io/p/build-a-load-balancer-in-python-from</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Fri, 03 Apr 2026 13:00:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Dyfw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You have written this exact config hundreds of times:</p><pre><code><code>upstream backend {
    server 10.0.0.1 weight=3;
    server 10.0.0.2 weight=1;
    server 10.0.0.3 weight=1;
}
</code></code></pre><p>But have you ever built what happens inside that <code>upstream</code> block? Today, we build three load balancing algorithms from scratch and learn the design pattern that lets you swap them at runtime without changing a single line of caller code.</p><div><hr></div><h2>The 3-Question Framework</h2><p><strong>What does the system DO?</strong> It distributes incoming requests across multiple backend servers. This is the <strong>Strategy pattern</strong> &#8212; the load balancer owns a pluggable algorithm that decides which server gets the next request. </p><p>You can swap algorithms (round-robin, weighted, and least-connections) at runtime without changing the routing code.</p><p><strong>What operations must be FAST?</strong> Every single request passes through the load balancer. Selecting the next server must be O(1). </p><p>We cannot scan all servers or sort them on every request. </p><p>A <strong>list + index counter</strong> gives us O(1) round-robin. </p><p>A <strong>pre-expanded list</strong> gives us O(1) weighted selection. </p><p>A <strong>min-heap or linear scan</strong> handles the least connections.</p><p><strong>What is the core LOGIC?</strong> Each algorithm answers the same question differently: &#8220;Given N servers, which one should handle this request?&#8221;</p><pre><code><code>Pattern:    Strategy (swap algorithms at runtime)
Structure:  list + counter (round-robin), expanded list (weighted), heap (least-conn)
Algorithm:  Stateless rotation, weighted expansion, connection-aware selection
</code></code></pre><div><hr></div><h2>The Strategy Pattern: Why It Matters Here</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ILkw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ILkw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 424w, https://substackcdn.com/image/fetch/$s_!ILkw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 848w, https://substackcdn.com/image/fetch/$s_!ILkw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 1272w, https://substackcdn.com/image/fetch/$s_!ILkw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ILkw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png" width="1456" height="694" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:694,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199408,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190188246?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ILkw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 424w, https://substackcdn.com/image/fetch/$s_!ILkw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 848w, https://substackcdn.com/image/fetch/$s_!ILkw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 1272w, https://substackcdn.com/image/fetch/$s_!ILkw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feae552f1-c8a9-4ca9-aa1d-a8e6769489a7_2126x1014.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Before we write any load-balancing code, let us build the pattern that holds it all together. The Strategy pattern is one of the most useful patterns in system design interviews &#8212; and one you already use daily.</p><pre><code><code>from abc import ABC, abstractmethod

class LoadBalancer(ABC):
    """Base class &#8212; all algorithms implement this interface."""

    @abstractmethod
    def select(self) -&gt; str:
        """Return the address of the next server to handle a request."""
        pass

    @abstractmethod
    def add_server(self, address: str, weight: int = 1) -&gt; None:
        pass

    @abstractmethod
    def remove_server(self, address: str) -&gt; None:
        pass
</code></code></pre><p>Every algorithm we build will implement this interface. The caller never knows which algorithm is running, and it just calls <code>select()</code> and gets a server address. This is exactly how nginx, HAProxy, and Kubernetes Services work internally.</p><p><strong>Interview phrasing:</strong> &#8220;I would use the Strategy pattern so we can swap load-balancing algorithms without changing the routing code. This is the same pattern behind Terraform providers &#8212; same interface, different implementation.&#8221;</p><div><hr></div><h2>Algorithm 1: Round-Robin</h2><p>The simplest approach. Rotate through servers in order. Every server gets equal traffic.</p><pre><code><code>import threading

class RoundRobinBalancer(LoadBalancer):
    """Distribute requests evenly across all servers in rotation."""

    def __init__(self):
        self._servers = []
        self._index = 0
        self._lock = threading.Lock()

    def add_server(self, address: str, weight: int = 1) -&gt; None:
        with self._lock:
            if address not in self._servers:
                self._servers.append(address)

    def remove_server(self, address: str) -&gt; None:
        with self._lock:
            if address in self._servers:
                self._servers.remove(address)
                if self._index &gt;= len(self._servers):
                    self._index = 0

    def select(self) -&gt; str:
        with self._lock:
            if not self._servers:
                raise RuntimeError("No servers available")
            server = self._servers[self._index]
            self._index = (self._index + 1) % len(self._servers)
            return server
</code></code></pre><p><strong>Complexity:</strong> O(1) select. O(n) add/remove (list operations), but these are rare.</p><pre><code><code>Request 1 &#8594; Server A
Request 2 &#8594; Server B
Request 3 &#8594; Server C
Request 4 &#8594; Server A  (wraps around)
Request 5 &#8594; Server B
...
</code></code></pre><p><strong>When to use:</strong> All servers have equal capacity. Simple, predictable, stateless.</p><p><strong>When it fails:</strong> If server A is a 32-core machine and server B is a 2-core machine, round-robin sends them equal traffic. Server B collapses.</p><div><hr></div><h2>Algorithm 2: Weighted Round-Robin</h2><p>Assign weights to servers. Higher-weight servers get proportionally more traffic.</p><pre><code><code>class WeightedRoundRobinBalancer(LoadBalancer):
    """Servers with higher weight receive more requests."""

    def __init__(self):
        self._servers = {}  # address -&gt; weight
        self._expanded = []  # pre-expanded list for O(1) select
        self._index = 0
        self._lock = threading.Lock()

    def add_server(self, address: str, weight: int = 1) -&gt; None:
        with self._lock:
            self._servers[address] = weight
            self._rebuild()

    def remove_server(self, address: str) -&gt; None:
        with self._lock:
            self._servers.pop(address, None)
            self._rebuild()

    def _rebuild(self):
        """Expand weights into a flat list for O(1) selection."""
        self._expanded = []
        for address, weight in self._servers.items():
            self._expanded.extend([address] * weight)
        self._index = 0

    def select(self) -&gt; str:
        with self._lock:
            if not self._expanded:
                raise RuntimeError("No servers available")
            server = self._expanded[self._index]
            self._index = (self._index + 1) % len(self._expanded)
            return server
</code></code></pre><p><strong>Complexity:</strong> O(1) select. O(total_weight) rebuild on add/remove.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pZDj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pZDj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 424w, https://substackcdn.com/image/fetch/$s_!pZDj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 848w, https://substackcdn.com/image/fetch/$s_!pZDj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 1272w, https://substackcdn.com/image/fetch/$s_!pZDj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pZDj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png" width="1456" height="990" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:990,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:285733,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190188246?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pZDj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 424w, https://substackcdn.com/image/fetch/$s_!pZDj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 848w, https://substackcdn.com/image/fetch/$s_!pZDj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 1272w, https://substackcdn.com/image/fetch/$s_!pZDj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13809309-be75-4532-8e7c-915d5ce51df2_2262x1538.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>The trick:</strong> Pre-expanding weights into a flat list turns weighted selection into a simple array index. No math per request.</p><p><strong>When to use:</strong> Servers have different capacities. This is the <code>weight=3</code> in your nginx upstream config.</p><div><hr></div><h2>Algorithm 3: Least-Connections</h2><p>Route to the server with the fewest active connections. The most adaptive approach.</p><pre><code><code>class LeastConnectionsBalancer(LoadBalancer):
    """Route to the server with the fewest active connections."""

    def __init__(self):
        self._connections = {}  # address -&gt; active connection count
        self._lock = threading.Lock()

    def add_server(self, address: str, weight: int = 1) -&gt; None:
        with self._lock:
            if address not in self._connections:
                self._connections[address] = 0

    def remove_server(self, address: str) -&gt; None:
        with self._lock:
            self._connections.pop(address, None)

    def select(self) -&gt; str:
        with self._lock:
            if not self._connections:
                raise RuntimeError("No servers available")
            # Find server with minimum connections
            server = min(self._connections, key=self._connections.get)
            self._connections[server] += 1
            return server

    def release(self, address: str) -&gt; None:
        """Call when a request completes."""
        with self._lock:
            if address in self._connections:
                self._connections[address] = max(0, self._connections[address] - 1)
</code></code></pre><p><strong>Complexity:</strong> O(n) select (scans all servers). For small server counts (typically &lt;100), this is negligible. For massive pools, use a min-heap.</p><pre><code><code>Server A: 12 active connections
Server B: 3 active connections   &#8592; selected
Server C: 8 active connections

New request &#8594; B (fewest connections)
B now has 4 active connections
</code></code></pre><p><strong>When to use:</strong> Requests have variable processing time (some take 10ms, some take 10s). Round-robin would overload a server stuck on slow requests. Least-connections adapts in real time.</p><p><strong>The release() pattern:</strong> The caller must notify the load balancer when a request completes. This is how HAProxy&#8217;s <code>leastconn</code> and Kubernetes&#8217; endpoint tracking work.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Dyfw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Dyfw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 424w, https://substackcdn.com/image/fetch/$s_!Dyfw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 848w, https://substackcdn.com/image/fetch/$s_!Dyfw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 1272w, https://substackcdn.com/image/fetch/$s_!Dyfw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Dyfw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png" width="1456" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:255244,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190188246?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Dyfw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 424w, https://substackcdn.com/image/fetch/$s_!Dyfw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 848w, https://substackcdn.com/image/fetch/$s_!Dyfw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 1272w, https://substackcdn.com/image/fetch/$s_!Dyfw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0cc97a8-9788-47d7-a120-a4e52336ac6d_2144x848.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Putting It Together: Swap Algorithms at Runtime</h2><pre><code><code># Start with round-robin
balancer: LoadBalancer = RoundRobinBalancer()
balancer.add_server("10.0.0.1")
balancer.add_server("10.0.0.2")
balancer.add_server("10.0.0.3")

# Handle requests
for request in incoming_requests:
    server = balancer.select()
    forward(request, server)

# Hot-swap to weighted &#8212; no caller changes needed
balancer = WeightedRoundRobinBalancer()
balancer.add_server("10.0.0.1", weight=3)
balancer.add_server("10.0.0.2", weight=1)
balancer.add_server("10.0.0.3", weight=1)

# Same loop works &#8212; the interface is identical
for request in incoming_requests:
    server = balancer.select()
    forward(request, server)
</code></code></pre><p>This is the power of the Strategy pattern. The routing code never changes. Only the algorithm inside the <code>select()</code> call changes. </p><p><strong>Terraform uses this exact pattern</strong> &#8212; <code>terraform apply</code> calls the same interface whether the provider is AWS, GCP, or Azure.</p><div><hr></div><h2>Adding Health Checks</h2><p>A production load balancer needs to detect failed servers. Here is a simple health check wrapper:</p><pre><code><code>import time
import threading
import urllib.request

class HealthCheckedBalancer:
    """Wraps any LoadBalancer with periodic health checks."""

    def __init__(self, balancer: LoadBalancer, check_interval: float = 5.0):
        self._balancer = balancer
        self._all_servers = {}  # address -&gt; health path
        self._check_interval = check_interval
        self._start_health_checks()

    def add_server(self, address: str, health_path: str = "/health"):
        self._all_servers[address] = health_path
        self._balancer.add_server(address)

    def select(self) -&gt; str:
        return self._balancer.select()

    def _check_health(self):
        for address, path in list(self._all_servers.items()):
            try:
                url = f"http://{address}{path}"
                urllib.request.urlopen(url, timeout=2)
                self._balancer.add_server(address)  # re-add if healthy
            except Exception:
                self._balancer.remove_server(address)  # remove if unhealthy

    def _start_health_checks(self):
        def run():
            while True:
                time.sleep(self._check_interval)
                self._check_health()
        threading.Thread(target=run, daemon=True).start()
</code></code></pre><p><strong>Interview phrasing:</strong> &#8220;I would wrap the load balancer with a health check decorator. A background thread pings each server&#8217;s <code>/health</code> endpoint every 5 seconds. </p><p>Unhealthy servers are removed from the pool. When they recover, they are automatically re-added. This is how ELB health checks and Kubernetes readiness probes work.&#8221;</p><div><hr></div><h2>Comparison: When to Use What</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VON-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VON-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 424w, https://substackcdn.com/image/fetch/$s_!VON-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 848w, https://substackcdn.com/image/fetch/$s_!VON-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 1272w, https://substackcdn.com/image/fetch/$s_!VON-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VON-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png" width="1068" height="415" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:415,&quot;width&quot;:1068,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56792,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190188246?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VON-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 424w, https://substackcdn.com/image/fetch/$s_!VON-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 848w, https://substackcdn.com/image/fetch/$s_!VON-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 1272w, https://substackcdn.com/image/fetch/$s_!VON-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc236d357-fe54-43f8-9a08-be6288dbea88_1068x415.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The DevOps Connection</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!57bl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!57bl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 424w, https://substackcdn.com/image/fetch/$s_!57bl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 848w, https://substackcdn.com/image/fetch/$s_!57bl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 1272w, https://substackcdn.com/image/fetch/$s_!57bl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!57bl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png" width="1071" height="586" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:586,&quot;width&quot;:1071,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105436,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190188246?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!57bl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 424w, https://substackcdn.com/image/fetch/$s_!57bl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 848w, https://substackcdn.com/image/fetch/$s_!57bl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 1272w, https://substackcdn.com/image/fetch/$s_!57bl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2986ad75-4352-47ca-bca7-7cb4aec76fc5_1071x586.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Interview Walkthrough Script</h2><p>When the interviewer asks, &#8220;Design a load balancer&#8221;:</p><blockquote><p><strong>&#8220;I would use the Strategy pattern with a pluggable algorithm behind a common interface. The default would be weighted round-robin &#8212; pre-expand weights into a flat array for O(1) selection. </strong></p><p><strong>For variable-latency workloads, I would swap to least-connections, which routes to the server with the fewest active requests. I would wrap the balancer with health checks &#8212; a background thread pinging /health endpoints, automatically removing failed servers and re-adding recovered ones. </strong></p><p><strong>For session affinity, I would add an IP hash strategy. The key design decision is that all strategies implement the same interface, so the routing layer never changes when you swap algorithms.&#8221;</strong></p></blockquote><div><hr></div><h2>Challenge: Try It Yourself</h2><ol><li><p><strong>IP Hash.</strong> Implement a strategy that hashes the client IP to consistently route the same client to the same server. Hint: <code>hash(ip) % len(servers)</code>.</p></li><li><p><strong>Weighted least-connections.</strong> Combine weights with connection counts: <code>score = connections / weight</code>. The server with the lowest score wins.</p></li><li><p><strong>FastAPI integration.</strong> Build an HTTP reverse proxy that accepts requests and forwards them to backends using your load balancer. Use <code>httpx</code> for async forwarding.</p></li></ol><div><hr></div><p><em>Next week: <strong>Build a DNS Resolver in Python</strong></em></p><p><em>Previous: <a href="https://crackthat.io/p/build-rate-limiter-python-sliding-window">Build a Rate Limiter</a> | <a href="https://crackthat.io/p/why-redis-uses-c-not-python-gil">The GIL Explained</a> | <a href="https://crackthat.io/p/implement-ttl-key-expiry-python">TTL &amp; Key Expiry</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Build a Rate Limiter From Scratch in Python]]></title><description><![CDATA[Implement fixed-window, sliding-window log, and token-bucket rate limiting in Python. Learn which algorithm to pick and why.]]></description><link>https://www.crackthat.io/p/build-rate-limiter-python-sliding-window</link><guid isPermaLink="false">https://www.crackthat.io/p/build-rate-limiter-python-sliding-window</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Fri, 27 Mar 2026 13:01:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!M0uG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You have used rate limiters every day of your career. nginx <code>limit_req</code>. AWS API Gateway throttling. Redis-backed middleware. Cloudflare&#8217;s DDoS protection. But have you ever built one?</p><p>Today we build three rate limiting algorithms from scratch in Python &#8212; and learn why &#8220;100 requests per minute&#8221; is a harder problem than it sounds.</p><div><hr></div><h2>The 3-Question Framework</h2><p><strong>What does the system DO?</strong> It decides whether to allow or reject a request based on the number of requests a client has made recently. This is the <strong>Strategy pattern</strong> &#8212; we can swap algorithms (fixed window, sliding window, token bucket) at runtime without changing the caller.</p><p><strong>What operations must be FAST?</strong> Every single request hits the rate limiter. It must decide to allow/deny in O(1). We cannot afford to scan all past requests. </p><p>A <strong>deque</strong> gives us O(1) append and O(1) popleft &#8212; perfect for maintaining a sliding window of timestamps.</p><p><strong>What is the core LOGIC?</strong> The sliding window log: store each request&#8217;s timestamp in a deque. </p><p>On every new request, evict timestamps outside the window, then count what remains. If count &gt;= limit, reject.</p><pre><code><code>Pattern:    Strategy (swap algorithms at runtime)
Structure:  deque (sliding window of timestamps)
Algorithm:  Sliding window log &#8212; evict old, count remaining
</code></code></pre><div><hr></div><h2>Why &#8220;100 Requests Per Minute&#8221; Is Harder Than It Sounds</h2><p>The naive approach, fixed window and it has a fatal flaw:</p><p>Imagine a limit of 100 requests per minute, with windows at :00 and :01.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!63vs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!63vs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 424w, https://substackcdn.com/image/fetch/$s_!63vs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 848w, https://substackcdn.com/image/fetch/$s_!63vs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 1272w, https://substackcdn.com/image/fetch/$s_!63vs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!63vs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png" width="1046" height="414" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:414,&quot;width&quot;:1046,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:74102,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190185974?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!63vs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 424w, https://substackcdn.com/image/fetch/$s_!63vs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 848w, https://substackcdn.com/image/fetch/$s_!63vs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 1272w, https://substackcdn.com/image/fetch/$s_!63vs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85a1de7e-b304-4b89-a8c3-5b6c1005e1b9_1046x414.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The boundary between windows creates a burst vulnerability. This is why every production rate limiter uses sliding windows or token buckets instead.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/build-rate-limiter-python-sliding-window?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Crack That Weekly! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/build-rate-limiter-python-sliding-window?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.crackthat.io/p/build-rate-limiter-python-sliding-window?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><div><hr></div><h2>Strategy 1: Fixed Window Counter</h2><p>The simplest approach. Fast, memory-efficient, but vulnerable to boundary bursts.</p><pre><code><code>import time
from collections import defaultdict

class FixedWindowLimiter:
    """Count requests per fixed time window."""

    def __init__(self, max_requests: int, window_seconds: int):
        self.max_requests = max_requests
        self.window_seconds = window_seconds
        self._counters = defaultdict(lambda: {"count": 0, "window_start": 0})

    def allow(self, client_id: str) -&gt; bool:
        now = time.time()
        entry = self._counters[client_id]
        window_start = now - (now % self.window_seconds)

        if entry["window_start"] != window_start:
            entry["count"] = 0
            entry["window_start"] = window_start

        if entry["count"] &gt;= self.max_requests:
            return False

        entry["count"] += 1
        return True
</code></code></pre><p><strong>Complexity:</strong> O(1) time, O(n) space where n = number of clients.</p><p><strong>Interview phrasing:</strong> &#8220;Fixed window is the simplest rate limiter &#8212; one counter per window per client. </p><p>It fails at window boundaries where a burst can exceed the limit by nearly 2x. Good enough for rough protection, not for strict enforcement.&#8221;</p><div><hr></div><h2>Strategy 2: Sliding Window Log</h2><p>The precise approach. Stores every request timestamp. No boundary problem.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zOKY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zOKY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 424w, https://substackcdn.com/image/fetch/$s_!zOKY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 848w, https://substackcdn.com/image/fetch/$s_!zOKY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 1272w, https://substackcdn.com/image/fetch/$s_!zOKY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zOKY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png" width="1085" height="547" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:547,&quot;width&quot;:1085,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94412,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190185974?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zOKY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 424w, https://substackcdn.com/image/fetch/$s_!zOKY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 848w, https://substackcdn.com/image/fetch/$s_!zOKY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 1272w, https://substackcdn.com/image/fetch/$s_!zOKY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221cfb5c-a4b1-493b-bb71-4f89ecf36f0f_1085x547.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><pre><code><code>import time
from collections import defaultdict, deque

class SlidingWindowLogLimiter:
    """Track exact timestamps in a deque. Precise but memory-heavy."""

    def __init__(self, max_requests: int, window_seconds: int):
        self.max_requests = max_requests
        self.window_seconds = window_seconds
        self._requests = defaultdict(deque)

    def allow(self, client_id: str) -&gt; bool:
        now = time.time()
        window_start = now - self.window_seconds
        req_log = self._requests[client_id]

        # Evict timestamps outside the window
        while req_log and req_log[0] &lt;= window_start:
            req_log.popleft()

        if len(req_log) &gt;= self.max_requests:
            return False

        req_log.append(now)
        return True
</code></code></pre><p><strong>Complexity:</strong> O(1) amortized (each timestamp is appended once, popped once). Space: O(max_requests * clients).</p><p><strong>Interview phrasing:</strong> &#8220;The sliding window log stores every request timestamp in a deque. On each request, evict entries older than the window, then check the count. It is perfectly precise &#8212; no boundary bursts. The trade-off is memory: if you allow 10,000 requests per minute, you store 10,000 timestamps per client.&#8221;</p><div><hr></div><h2>Strategy 3: Token Bucket</h2><p>The flexible approach. Allows controlled bursts. Used by AWS, Stripe, and most API gateways.</p><pre><code><code>import time

class TokenBucketLimiter:
    """Refill tokens at a fixed rate. Each request costs one token."""

    def __init__(self, max_tokens: int, refill_rate: float):
        self.max_tokens = max_tokens
        self.refill_rate = refill_rate  # tokens per second
        self._buckets = {}

    def allow(self, client_id: str) -&gt; bool:
        now = time.time()

        if client_id not in self._buckets:
            self._buckets[client_id] = {
                "tokens": self.max_tokens,
                "last_refill": now,
            }

        bucket = self._buckets[client_id]

        # Refill tokens based on elapsed time
        elapsed = now - bucket["last_refill"]
        bucket["tokens"] = min(
            self.max_tokens,
            bucket["tokens"] + elapsed * self.refill_rate,
        )
        bucket["last_refill"] = now

        if bucket["tokens"] &lt; 1:
            return False

        bucket["tokens"] -= 1
        return True
</code></code></pre><p><strong>Complexity:</strong> O(1) time, O(1) space per client (just two numbers: token count + last refill time).</p><p><strong>Interview phrasing:</strong> &#8220;Token bucket refills at a constant rate and allows bursts up to the bucket size. It is the most memory-efficient &#8212; just two numbers per client. </p><p>AWS and Stripe use it because it naturally shapes traffic: steady traffic gets steady throughput, while short bursts are absorbed by the bucket. </p><p>The trade-off: less precise than sliding window, but much more memory-efficient at scale.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M0uG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M0uG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 424w, https://substackcdn.com/image/fetch/$s_!M0uG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 848w, https://substackcdn.com/image/fetch/$s_!M0uG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 1272w, https://substackcdn.com/image/fetch/$s_!M0uG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M0uG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png" width="1092" height="523" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:523,&quot;width&quot;:1092,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:135481,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190185974?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!M0uG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 424w, https://substackcdn.com/image/fetch/$s_!M0uG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 848w, https://substackcdn.com/image/fetch/$s_!M0uG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 1272w, https://substackcdn.com/image/fetch/$s_!M0uG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9f62bb9-be3e-41d5-a58a-37db9b3ee569_1092x523.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Strategy Pattern: Swap Algorithms at Runtime</h2><p>The real power: wrap all three behind one interface so you can switch algorithms without changing any caller code.</p><pre><code><code>from abc import ABC, abstractmethod

class RateLimiter(ABC):
    @abstractmethod
    def allow(self, client_id: str) -&gt; bool:
        pass

class FixedWindowLimiter(RateLimiter):
    # ... (implementation above)
    pass

class SlidingWindowLogLimiter(RateLimiter):
    # ... (implementation above)
    pass

class TokenBucketLimiter(RateLimiter):
    # ... (implementation above)
    pass

# Swap at runtime &#8212; no caller changes needed
limiter: RateLimiter = SlidingWindowLogLimiter(100, 60)
# Later: limiter = TokenBucketLimiter(100, 100/60)
</code></code></pre><p>This is the <strong>Strategy pattern</strong> &#8212; the same pattern behind Terraform&#8217;s provider system (swap AWS for GCP), nginx&#8217;s load balancing (swap round-robin for least-connections), and Kubernetes&#8217; scheduler (swap scoring plugins).</p><div><hr></div><h2>Comparison: When to Use What</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YtcM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YtcM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 424w, https://substackcdn.com/image/fetch/$s_!YtcM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 848w, https://substackcdn.com/image/fetch/$s_!YtcM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 1272w, https://substackcdn.com/image/fetch/$s_!YtcM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YtcM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png" width="1054" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1054,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:64385,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190185974?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YtcM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 424w, https://substackcdn.com/image/fetch/$s_!YtcM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 848w, https://substackcdn.com/image/fetch/$s_!YtcM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 1272w, https://substackcdn.com/image/fetch/$s_!YtcM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224cd407-9c96-4ad3-bd16-05e66329aab6_1054x400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>The DevOps Connection</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!monz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!monz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 424w, https://substackcdn.com/image/fetch/$s_!monz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 848w, https://substackcdn.com/image/fetch/$s_!monz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 1272w, https://substackcdn.com/image/fetch/$s_!monz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!monz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png" width="1082" height="573" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:573,&quot;width&quot;:1082,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101613,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190185974?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!monz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 424w, https://substackcdn.com/image/fetch/$s_!monz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 848w, https://substackcdn.com/image/fetch/$s_!monz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 1272w, https://substackcdn.com/image/fetch/$s_!monz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F064d9644-a7e2-4cff-8502-a717b1bbef30_1082x573.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Scaling to Distributed Systems</h2><p>Our single-process implementation works for one server. In production with multiple servers, you need shared state:</p><pre><code><code># Distributed sliding window using Redis sorted sets
import redis
import time

class DistributedSlidingWindow:
    def __init__(self, redis_client, max_requests, window_seconds):
        self.r = redis_client
        self.max = max_requests
        self.window = window_seconds

    def allow(self, client_id: str) -&gt; bool:
        key = f"ratelimit:{client_id}"
        now = time.time()
        window_start = now - self.window

        pipe = self.r.pipeline()
        pipe.zremrangebyscore(key, 0, window_start)  # evict old
        pipe.zadd(key, {str(now): now})               # add current
        pipe.zcard(key)                                # count
        pipe.expire(key, self.window + 1)              # auto-cleanup
        results = pipe.execute()

        return results[2] &lt;= self.max
</code></code></pre><p><strong>Interview phrasing:</strong> &#8220;For distributed rate limiting, I would use Redis sorted sets. Each request adds a member with score = timestamp. ZREMRANGEBYSCORE removes old entries, ZCARD counts remaining. </p><p>The pipeline makes it atomic. This is the standard pattern used by Kong, Envoy, and most API gateways.&#8221;</p><div><hr></div><h2>Interview Walkthrough Script</h2><p>When the interviewer asks &#8220;Design a rate limiter&#8221;:</p><blockquote><p><strong>&#8220;I would use the Strategy pattern to support multiple algorithms behind one interface. For the default, I would pick sliding window log &#8212; store timestamps in a deque, evict entries outside the window on each request, reject if count exceeds the limit. It is O(1) amortized and perfectly precise. If memory is a concern at scale, I would switch to token bucket &#8212; just two numbers per client, allows controlled bursts, which is what AWS and Stripe use. For distributed systems, Redis sorted sets give us the sliding window pattern with atomic pipelines.&#8221;</strong></p></blockquote><div><hr></div><h2>Challenge: Try It Yourself</h2><ol><li><p><strong>Add HTTP headers.</strong> Return <code>X-RateLimit-Limit</code>, <code>X-RateLimit-Remaining</code>, and <code>X-RateLimit-Reset</code> headers &#8212; these are the standard rate limit response headers.</p></li><li><p><strong>Sliding window counter.</strong> Implement the hybrid approach &#8212; weight the previous window&#8217;s count by the overlap percentage. More precise than fixed window, less memory than sliding log.</p></li><li><p><strong>Multi-tier limits.</strong> Implement rate limiting with multiple windows: 10 per second AND 100 per minute AND 1,000 per hour.</p></li></ol><div><hr></div><p><em>Next week: <strong>Build a Load Balancer in Python</strong></em></p><p><em>Previous: <a href="https://crackthat.io/p/why-redis-uses-c-not-python-gil">The GIL Explained</a> | <a href="https://crackthat.io/p/implement-ttl-key-expiry-python">TTL &amp; Key Expiry</a> | <a href="https://crackthat.io/p/redis-persistence-python-wal-snapshots">Redis Persistence</a> | <a href="https://crackthat.io/p/build-redis-python-key-value-store">Build Your Own Redis</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Why Redis Uses C, Not Python: The GIL Explained]]></title><description><![CDATA[Your MiniRedis has a hidden bottleneck. Understanding it is the difference between a junior and senior answer in system design interviews.]]></description><link>https://www.crackthat.io/p/why-redis-uses-c-not-python-gil</link><guid isPermaLink="false">https://www.crackthat.io/p/why-redis-uses-c-not-python-gil</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Fri, 20 Mar 2026 13:01:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9o5b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We just spent three issues building a Redis clone in Python. It works. It handles TTL, persistence, and active expiration. But there is an elephant in the room.</p><p><strong>Our MiniRedis cannot serve 100 clients at full speed. Not because of our code. Because of Python itself.</strong></p><p>Today, we crack open the GIL, Python&#8217;s Global Interpreter Lock, and understand why Redis chose C, why your Python services need Gunicorn workers, and how to give the senior-level answer when an interviewer asks about concurrency.</p><div><hr></div><h2>The 3-Question Framework</h2><p><strong>What does the system DO?</strong> It serves thousands of concurrent clients doing GET/SET operations. This is the <strong>Reactor pattern</strong>, a single event loop dispatches work without spawning threads per connection.</p><p><strong>What operations must be FAST?</strong> Everything. Every GET and SET must complete in microseconds. The bottleneck is not the data structure (a dict is O(1)), but how we handle multiple clients at the same time.</p><p><strong>What is the core LOGIC?</strong> Two competing models:</p><ul><li><p><strong>Multi-threaded:</strong> One thread per client. Simple to write, but Python&#8217;s GIL serializes CPU work anyway.</p></li><li><p><strong>Event loop:</strong> One thread, non-blocking I/O. No GIL contention. This is what Redis actually does.</p></li></ul><pre><code><code>Pattern:    Reactor (single event loop dispatches I/O)
Structure:  Event queue + file descriptor table
Trade-off:  Threads (simple but GIL-bound) vs Event loop (fast but complex)
</code></code></pre><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/why-redis-uses-c-not-python-gil?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Crack That Weekly! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/why-redis-uses-c-not-python-gil?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.crackthat.io/p/why-redis-uses-c-not-python-gil?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><h2>What Is the GIL, Actually?</h2><p>The Global Interpreter Lock is a mutex inside CPython (the standard Python interpreter). It allows <strong>only one thread to execute Python bytecode at a time</strong>, even on a 64-core machine.</p><p>Here is the mental model:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Cbto!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cbto!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 424w, https://substackcdn.com/image/fetch/$s_!Cbto!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 848w, https://substackcdn.com/image/fetch/$s_!Cbto!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 1272w, https://substackcdn.com/image/fetch/$s_!Cbto!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Cbto!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png" width="1260" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e41a47ff-66b3-4177-897e-000917156d22_1260x584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:1260,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104582,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189856975?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cbto!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 424w, https://substackcdn.com/image/fetch/$s_!Cbto!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 848w, https://substackcdn.com/image/fetch/$s_!Cbto!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 1272w, https://substackcdn.com/image/fetch/$s_!Cbto!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41a47ff-66b3-4177-897e-000917156d22_1260x584.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is not a bug. It is a design decision. The GIL makes CPython&#8217;s memory management (reference counting) thread-safe without fine-grained locking. </p><p>The trade-off: simpler internals, but no true CPU parallelism from threads.</p><div><hr></div><h2>Why This Kills Our MiniRedis</h2><p>Remember our active expiration from Issue 3? We used a background thread:</p><pre><code><code># From Issue 3 - our background cleanup thread
def _start_cleanup(self):
    def run():
        while True:
            time.sleep(self._cleanup_interval)
            self._cleanup_expired()    # &lt;-- needs the GIL
    t = threading.Thread(target=run, daemon=True)
    t.start()
</code></code></pre><p>When this cleanup thread runs, <strong>every client request is blocked</strong>. Not because of our lock, because of the GIL. The cleanup thread holds the GIL while iterating the heap, and no other thread can execute Python code until it releases it.</p><p>With 100 concurrent clients and a cleanup cycle running, you get:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9hU3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9hU3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 424w, https://substackcdn.com/image/fetch/$s_!9hU3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 848w, https://substackcdn.com/image/fetch/$s_!9hU3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 1272w, https://substackcdn.com/image/fetch/$s_!9hU3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9hU3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png" width="1278" height="558" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:558,&quot;width&quot;:1278,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:97250,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189856975?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9hU3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 424w, https://substackcdn.com/image/fetch/$s_!9hU3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 848w, https://substackcdn.com/image/fetch/$s_!9hU3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 1272w, https://substackcdn.com/image/fetch/$s_!9hU3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cf4251-9403-48e3-b69c-5c1ebe1b8b4e_1278x558.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>This is why Redis uses C.</strong> In C, there is no GIL. Threads can truly run in parallel on multiple cores. But Redis goes further;</p><p>It does not even use multiple threads for the main workload. It uses something better.</p><div><hr></div><h2>How Redis Actually Works: The Event Loop</h2><p>Redis uses a <strong>single-threaded event loop</strong> based on epoll/kqueue. One thread. No locks. No context switching. No GIL.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kSkl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kSkl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 424w, https://substackcdn.com/image/fetch/$s_!kSkl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 848w, https://substackcdn.com/image/fetch/$s_!kSkl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 1272w, https://substackcdn.com/image/fetch/$s_!kSkl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kSkl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png" width="1266" height="610" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:610,&quot;width&quot;:1266,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:163873,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189856975?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kSkl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 424w, https://substackcdn.com/image/fetch/$s_!kSkl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 848w, https://substackcdn.com/image/fetch/$s_!kSkl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 1272w, https://substackcdn.com/image/fetch/$s_!kSkl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf2b3657-d1fc-469a-9a78-cb59895155b9_1266x610.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Why is this fast?</p><ol><li><p><strong>No lock contention.</strong> One thread means no locks needed. Zero overhead.</p></li><li><p><strong>No context switching.</strong> The OS does not swap threads in and out. Pure CPU time.</p></li><li><p><strong>CPU cache friendly.</strong> One thread keeps data in the L1/L2 cache. Threads thrash the cache.</p></li><li><p><strong>I/O is the bottleneck, not CPU.</strong> A GET/SET in memory takes ~100ns. Network I/O takes ~100us. The CPU is idle 99.9% of the time, waiting for network packets. One thread is enough.</p></li></ol><div><hr></div><h2>The Python Concurrency Landscape</h2><p>So if threads do not work for CPU-bound Python, what are the options?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9o5b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9o5b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 424w, https://substackcdn.com/image/fetch/$s_!9o5b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 848w, https://substackcdn.com/image/fetch/$s_!9o5b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 1272w, https://substackcdn.com/image/fetch/$s_!9o5b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9o5b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png" width="1264" height="552" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:552,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:140109,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189856975?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9o5b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 424w, https://substackcdn.com/image/fetch/$s_!9o5b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 848w, https://substackcdn.com/image/fetch/$s_!9o5b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 1272w, https://substackcdn.com/image/fetch/$s_!9o5b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9192d5-8dfb-4e37-8c7e-39cdfc79dc6d_1264x552.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The interview-level insight: <strong>Python threads are only useful when you are waiting for I/O</strong> (network calls, disk reads). </p><p>The GIL is released during I/O waits, so threads can overlap their waiting time. But for CPU work like iterating a heap or computing a hash, threads give you zero speedup.</p><div><hr></div><h2>Building a Better MiniRedis: asyncio Version</h2><p>Here is what our MiniRedis would look like using asyncio instead of threads &#8212; the same pattern Redis uses, just in Python:</p><pre><code><code>import asyncio
import time

class AsyncMiniRedis:
    def __init__(self):
        self._store = {}

    async def handle_client(self, reader, writer):
        while True:
            data = await reader.readline()
            if not data:
                break
            command = data.decode().strip().split()
            response = self._execute(command)
            writer.write(f"{response}\n".encode())
            await writer.drain()
        writer.close()

    def _execute(self, command):
        cmd = command[0].upper()
        if cmd == "GET":
            entry = self._store.get(command[1])
            if entry is None:
                return "(nil)"
            if entry["expiry"] and time.time() &gt; entry["expiry"]:
                del self._store[command[1]]
                return "(nil)"
            return entry["value"]
        elif cmd == "SET":
            ttl = None
            if len(command) &gt; 3 and command[3].upper() == "EX":
                ttl = time.time() + int(command[4])
            self._store[command[1]] = {"value": command[2], "expiry": ttl}
            return "OK"
        return "ERR unknown command"

    async def start(self, host="0.0.0.0", port=6380):
        server = await asyncio.start_server(
            self.handle_client, host, port
        )
        # Schedule background expiry
        asyncio.create_task(self._expire_cycle())
        async with server:
            await server.serve_forever()

    async def _expire_cycle(self):
        """Non-blocking expiry cycle - never blocks the event loop."""
        while True:
            await asyncio.sleep(0.1)
            now = time.time()
            expired = [
                k for k, v in list(self._store.items())
                if v["expiry"] and v["expiry"] &lt;= now
            ]
            for k in expired:
                self._store.pop(k, None)
</code></code></pre><p>No threads. No locks. No GIL contention. The <code>await</code> points are where the event loop can switch to another client. The <code>_expire_cycle</code> cooperatively yields control so client requests are never blocked.</p><div><hr></div><h2>The DevOps Connection</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tm4s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tm4s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 424w, https://substackcdn.com/image/fetch/$s_!tm4s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 848w, https://substackcdn.com/image/fetch/$s_!tm4s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 1272w, https://substackcdn.com/image/fetch/$s_!tm4s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tm4s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png" width="1246" height="458" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/696e72a1-205d-4e68-94c0-09f084662281_1246x458.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:458,&quot;width&quot;:1246,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:124410,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189856975?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tm4s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 424w, https://substackcdn.com/image/fetch/$s_!tm4s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 848w, https://substackcdn.com/image/fetch/$s_!tm4s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 1272w, https://substackcdn.com/image/fetch/$s_!tm4s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F696e72a1-205d-4e68-94c0-09f084662281_1246x458.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Interview Walkthrough Script</h2><p>When the interviewer asks, &#8220;Why doesn&#8217;t Redis use Python?&#8221; or &#8220;Explain the GIL&#8221;:</p><blockquote><p><strong>&#8220;The GIL is a mutex in CPython that allows only one thread to execute Python bytecode at a time. </strong></p><p><strong>This means Python threads cannot achieve true CPU parallelism; they are only useful for overlapping I/O waits. Redis needs microsecond latency for every operation, so it uses C with a single-threaded event loop based on epoll. </strong></p><p><strong>One thread, no locks, no context switching. The CPU work per command is tiny; it is I/O bound, so a single thread handling thousands of file descriptors via epoll is more efficient than thousands of threads fighting for the GIL. </strong></p><p><strong>In Python, the equivalent architecture is asyncio.&#8221;</strong></p></blockquote><div><hr></div><h2>Challenge: Try It Yourself</h2><ol><li><p><strong>Benchmark threads vs asyncio.</strong> Spin up 100 concurrent clients hitting your MiniRedis. Compare latency with the threaded version (Issue 3) vs the asyncio version above.</p></li><li><p><strong>Add pipelining.</strong> Real Redis clients send multiple commands in one TCP write. Modify <code>handle_client</code> to parse and execute batched commands.</p></li><li><p><strong>Implement pub/sub.</strong> Add SUBSCRIBE and PUBLISH commands using asyncio &#8212; this is where event loops truly shine.</p></li></ol><div><hr></div><p><em>Next week: <strong>Build a Rate Limiter From Scratch in Python</strong></em></p><p><em>Previous: <a href="https://www.crackthat.io/p/implement-ttl-key-expiry-python">TTL &amp; Key Expiry</a> | <a href="https://www.crackthat.io/p/redis-persistence-python-wal-snapshots">Redis Persistence</a> | <a href="https://www.crackthat.io/p/build-redis-python-key-value-store">Build Your Own Redis</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Implement TTL and Key Expiry in Python From Scratch]]></title><description><![CDATA[Two expiration strategies, one min-heap, and the clever trick Redis uses to expire millions of keys without freezing]]></description><link>https://www.crackthat.io/p/implement-ttl-key-expiry-python</link><guid isPermaLink="false">https://www.crackthat.io/p/implement-ttl-key-expiry-python</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Fri, 13 Mar 2026 13:02:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ATyi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Issue 1, we built a key-value store with basic TTL support. In Issue 2, we made it survive crashes. But there is a problem we have not solved yet.</p><p>When a key expires, it remains in memory. Our lazy expiration only removes it when someone asks for it. What about the millions of keys nobody ever reads again? They are just leaking memory. Forever.</p><p>Today, we fix that by building two expiration strategies from scratch.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cQWZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cQWZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 424w, https://substackcdn.com/image/fetch/$s_!cQWZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 848w, https://substackcdn.com/image/fetch/$s_!cQWZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 1272w, https://substackcdn.com/image/fetch/$s_!cQWZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cQWZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png" width="1260" height="708" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:708,&quot;width&quot;:1260,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:189237,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189787187?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cQWZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 424w, https://substackcdn.com/image/fetch/$s_!cQWZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 848w, https://substackcdn.com/image/fetch/$s_!cQWZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 1272w, https://substackcdn.com/image/fetch/$s_!cQWZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7376afe-3e96-463c-a939-72d7eae042e3_1260x708.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The 3-Question Framework</h2><p><strong>What does the system DO?</strong> It monitors all keys with a TTL and removes them when they expire. This is the <strong>Observer pattern</strong>.</p><p><strong>What operations must be FAST?</strong> Find the next key to expire instantly. <strong>Min-heap</strong> (heapq) -- earliest expiry always on top.</p><p><strong>What is the core LOGIC?</strong> Two complementary algorithms:</p><ul><li><p><strong>Lazy expiration:</strong> Check on read. If expired, delete it. O(1) per read.</p></li><li><p><strong>Active expiration:</strong> Background process using a min-heap to proactively remove expired keys.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/implement-ttl-key-expiry-python?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.crackthat.io/p/implement-ttl-key-expiry-python?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y9Ku!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 424w, https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 848w, https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 1272w, https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png" width="1258" height="758" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:758,&quot;width&quot;:1258,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:183463,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189787187?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 424w, https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 848w, https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 1272w, https://substackcdn.com/image/fetch/$s_!Y9Ku!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f90679c-3590-42c2-a196-49f4433a5179_1258x758.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Strategy 1: Lazy Expiration (The Baseline)</h2><p>Check TTL on every GET. If expired, delete and return None. Zero write overhead, but dead keys stay in memory if never read.</p><p><strong>Interview phrasing:</strong> Lazy expiration is ideal when most keys get read at least once after their TTL. It falls apart with write-heavy workloads where keys are never read again.</p><div><hr></div><h2>Strategy 2: Active Expiration with a Min-Heap</h2><p>A min-heap keeps the next-to-expire key at position 0. Background thread polls the heap and removes expired keys.</p><ul><li><p>heappush: O(log n) -- add new expiry</p></li><li><p>heappop: O(log n) -- remove the minimum</p></li><li><p>heap[0]: O(1) -- peek at next expiry</p></li></ul><p>Watch out for <strong>stale heap entries</strong>: when a key is overwritten with a new TTL, the old entry stays in the heap. Always verify the store current expiry matches before deleting.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ATyi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ATyi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 424w, https://substackcdn.com/image/fetch/$s_!ATyi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 848w, https://substackcdn.com/image/fetch/$s_!ATyi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 1272w, https://substackcdn.com/image/fetch/$s_!ATyi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ATyi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png" width="1278" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1278,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:161870,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189787187?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ATyi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 424w, https://substackcdn.com/image/fetch/$s_!ATyi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 848w, https://substackcdn.com/image/fetch/$s_!ATyi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 1272w, https://substackcdn.com/image/fetch/$s_!ATyi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb877e08-be23-4115-8253-bdcb4180b6ce_1278x608.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Strategy 3: Redis-Style Probabilistic Sampling</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m9yd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m9yd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 424w, https://substackcdn.com/image/fetch/$s_!m9yd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 848w, https://substackcdn.com/image/fetch/$s_!m9yd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 1272w, https://substackcdn.com/image/fetch/$s_!m9yd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!m9yd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png" width="1266" height="572" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:572,&quot;width&quot;:1266,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:134649,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189787187?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!m9yd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 424w, https://substackcdn.com/image/fetch/$s_!m9yd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 848w, https://substackcdn.com/image/fetch/$s_!m9yd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 1272w, https://substackcdn.com/image/fetch/$s_!m9yd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da9373-320b-425d-a4e6-f5ff45f733da_1266x572.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Redis runs this algorithm 10 times per second:</p><ol><li><p>Pick 20 random keys that have a TTL</p></li><li><p>Delete the ones that are expired</p></li><li><p>If more than 25 percent were expired, go back to step 1</p></li><li><p>Otherwise, stop until next cycle</p></li></ol><p>This is adaptive -- few expired keys means minimal CPU, many expired keys means aggressive cleanup. Self-balancing.</p><p><strong>Interview phrasing:</strong> Redis avoids maintaining a sorted structure for expiry because it would add O(log n) overhead to every write. Instead, it uses probabilistic sampling that is statistically guaranteed to converge.</p><h2>Comparison: When to Use What</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!59WA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!59WA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 424w, https://substackcdn.com/image/fetch/$s_!59WA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 848w, https://substackcdn.com/image/fetch/$s_!59WA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 1272w, https://substackcdn.com/image/fetch/$s_!59WA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!59WA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png" width="1226" height="408" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:408,&quot;width&quot;:1226,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90580,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189787187?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!59WA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 424w, https://substackcdn.com/image/fetch/$s_!59WA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 848w, https://substackcdn.com/image/fetch/$s_!59WA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 1272w, https://substackcdn.com/image/fetch/$s_!59WA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5468717-8164-4e88-b4e9-89b885e8845c_1226x408.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The DevOps Connection</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gkx1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gkx1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 424w, https://substackcdn.com/image/fetch/$s_!Gkx1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 848w, https://substackcdn.com/image/fetch/$s_!Gkx1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 1272w, https://substackcdn.com/image/fetch/$s_!Gkx1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gkx1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png" width="1200" height="444" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:444,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:115445,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189787187?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gkx1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 424w, https://substackcdn.com/image/fetch/$s_!Gkx1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 848w, https://substackcdn.com/image/fetch/$s_!Gkx1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 1272w, https://substackcdn.com/image/fetch/$s_!Gkx1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198518f-51f1-4c87-a40d-80f3458e3fdf_1200x444.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Interview Walkthrough Script</h2><blockquote><p>I would use two complementary strategies: lazy and active expiration. Lazy checks on every read. </p><p>But lazy alone leaks memory for unread keys. So I would add active expiration, either a min-heap for deterministic cleanup, or Redis-style probabilistic sampling for scale. For millions of keys, go with the Redis approach.</p></blockquote><div><hr></div><h2>Challenge: Try It Yourself</h2><ol><li><p>Implement EXPIRE and PERSIST commands</p></li><li><p>Implement heap compaction to remove stale entries</p></li><li><p>Benchmark all three strategies with 100K keys</p></li></ol><div><hr></div><p><em>Next week: <strong>Why Redis Uses C, Not Python: The GIL Explained</strong></em></p><p><em>Previous: Redis Persistence: WAL and Snapshots | Build Your Own Redis: Key-Value Store From Scratch</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Build a Key-Value Store in Go]]></title><description><![CDATA[Build a Redis-like key-value store in Go with TTL, HTTP API, and goroutine-safe concurrency. Includes Python vs Go comparison.]]></description><link>https://www.crackthat.io/p/build-key-value-store-go</link><guid isPermaLink="false">https://www.crackthat.io/p/build-key-value-store-go</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Sat, 07 Mar 2026 10:01:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2qIO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ca4706b-f5d0-46eb-ae49-2727e299d803_2178x1244.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>This is the Go companion to <a href="https://crackthat.io/p/build-redis-python-key-value-store">Issue 1: Build Your Own Redis in Python</a>.</strong> Read that first for the 3-Question Framework, design pattern analysis, and interview strategy. This post focuses on the Go implementation and what changes when you leave Python behind.</p><div><hr></div><h2>Why Go for This?</h2><p>In the Python version, we built a key-value store using a <code>dict</code> and FastAPI. It works, but it has a fundamental problem we explored in Issue 4: <strong>the GIL</strong>. Python threads cannot run in parallel on CPU work. Our background expiration thread blocks client requests.</p><p>Go has none of these problems:</p><ul><li><p><strong>No GIL.</strong> Goroutines run on real OS threads across all CPU cores.</p></li><li><p><strong>Built-in concurrency.</strong> <code>sync.RWMutex</code> gives us concurrent reads with exclusive writes &#8212; exactly what a KV store needs.</p></li><li><p><strong>Static typing.</strong> The compiler catches type errors before runtime. No <code>None</code> surprises.</p></li><li><p><strong>Single binary.</strong> <code>go build</code> produces one binary. No virtualenv, no pip, no dependency hell.</p></li></ul><p>This is why tools like Redis (if built today), etcd, CockroachDB, and Kubernetes are all written in Go.</p><div><hr></div><h2>Step 1: The Core Store</h2><p>Python used a <code>dict</code>. Go uses a <code>map</code> &#8212; same O(1) hash map, but with explicit types.</p><pre><code><code>package store

import (
&#9;"sync"
&#9;"time"
)

type entry struct {
&#9;Value  string
&#9;Expiry *time.Time // nil = no expiry
}

type KeyValueStore struct {
&#9;mu   sync.RWMutex
&#9;data map[string]entry
}

func New() *KeyValueStore {
&#9;return &amp;KeyValueStore{
&#9;&#9;data: make(map[string]entry),
&#9;}
}
</code></code></pre><p><strong>What changed from Python:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tUnv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tUnv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 424w, https://substackcdn.com/image/fetch/$s_!tUnv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 848w, https://substackcdn.com/image/fetch/$s_!tUnv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 1272w, https://substackcdn.com/image/fetch/$s_!tUnv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tUnv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png" width="1456" height="718" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:718,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:240677,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/190182361?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tUnv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 424w, https://substackcdn.com/image/fetch/$s_!tUnv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 848w, https://substackcdn.com/image/fetch/$s_!tUnv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 1272w, https://substackcdn.com/image/fetch/$s_!tUnv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d15ac6d-05bf-4e52-a1d1-3313706dd3e8_2110x1040.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The <code>RWMutex</code> is the big win. In Python, the GIL means only one thread runs at a time, regardless. In Go, <code>RLock()</code> allows unlimited concurrent readers, while <code>Lock()</code> (write) blocks everyone. This is exactly how production databases handle concurrent access.</p><p></p>
      <p>
          <a href="https://www.crackthat.io/p/build-key-value-store-go">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Redis Persistence in Python: WAL & Snapshots From Scratch]]></title><description><![CDATA[Your key-value store survives restarts &#8212; using the exact same techniques Redis, PostgreSQL, and Kafka use under the hood]]></description><link>https://www.crackthat.io/p/redis-persistence-python-wal-snapshots</link><guid isPermaLink="false">https://www.crackthat.io/p/redis-persistence-python-wal-snapshots</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Fri, 06 Mar 2026 15:15:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OSgK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last week, we built a key-value store in Python with TTL support. One problem: kill the process and everything disappears.</p><p>That&#8217;s fine for a cache. It&#8217;s not fine for a database. So how do real databases like Redis, PostgreSQL, and Kafka survive crashes without losing data?</p><p>They all use the same two techniques: <strong>write-ahead logs</strong> and <strong>snapshots</strong>. Today, you&#8217;ll implement both from scratch.</p><div><hr></div><h2>The 3-Question Framework</h2><p><strong>What does the system DO?</strong> Our persistence layer records every mutation to disk so state can be rebuilt after a crash. This is the <strong>Observer pattern</strong> &#8212; the store publishes events (writes), and the persistence layer observes and records them.</p><p><strong>What operations must be FAST?</strong> Writing to disk on every PUT must not kill performance. Sequential append to a file is the fastest disk operation &#8212; O(1) per write. We need an <strong>append-only list</strong> (a file).</p><p><strong>What&#8217;s the core LOGIC?</strong> Two algorithms working together:</p><ul><li><p><strong>Write-Ahead Log (WAL):</strong> Append every operation to a file before confirming it. On crash, replay the file.</p></li><li><p><strong>Snapshotting:</strong> Periodically dump the entire state to disk. On restart, load the snapshot first, then replay only the WAL entries after it.</p></li></ul><pre><code><code>Pattern:    Observer (store publishes writes &#8594; persistence layer records them)
Structure:  Append-only file (sequential writes &#8212; fastest disk I/O)
Algorithms: WAL replay + periodic snapshotting + log compaction
</code></code></pre><div><hr></div><h2>Why Append-Only? The Disk I/O Insight</h2><p>This is the kind of insight that impresses in interviews:</p><pre><code><code>Random writes to disk:    ~0.1 MB/s  (seek time dominates)
Sequential appends:       ~500 MB/s  (5000x faster!)

Writing the entire file on every PUT &#8594; random I/O &#8594; slow
Appending one line on every PUT &#8594; sequential I/O &#8594; fast
</code></code></pre><p>This is why databases don&#8217;t just overwrite a JSON file on every change. They append to a log. It&#8217;s the same reason Kafka is fast &#8212; it&#8217;s fundamentally an append-only log.</p><p>As a DevOps engineer, you&#8217;ve seen this tradeoff in <code>redis.conf</code>:</p><pre><code><code># Redis AOF fsync policies &#8212; same concept we're building
appendfsync always      # fsync every write (safest, slowest)
appendfsync everysec    # fsync once per second (default &#8212; good balance)  
appendfsync no          # let OS decide (fastest, riskiest)
</code></code></pre><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/redis-persistence-python-wal-snapshots?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Crack That Weekly! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/redis-persistence-python-wal-snapshots?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.crackthat.io/p/redis-persistence-python-wal-snapshots?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><h2>Step 1: Write-Ahead Log (WAL)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hLd6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hLd6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 424w, https://substackcdn.com/image/fetch/$s_!hLd6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 848w, https://substackcdn.com/image/fetch/$s_!hLd6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 1272w, https://substackcdn.com/image/fetch/$s_!hLd6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hLd6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png" width="1264" height="552" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:552,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:119273,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189775821?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hLd6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 424w, https://substackcdn.com/image/fetch/$s_!hLd6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 848w, https://substackcdn.com/image/fetch/$s_!hLd6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 1272w, https://substackcdn.com/image/fetch/$s_!hLd6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66c243cb-6047-4f89-a017-17fb1fd9a582_1264x552.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The WAL is simple: before confirming any write to the client, append the operation to a file. If the process crashes, replay the file on startup.</p><pre><code><code>import json
import os
import time

class WriteAheadLog:
    def __init__(self, path="appendonly.aof"):
        self.path = path
        self._file = open(path, "a")

    def append(self, operation: dict):
        """Append one operation to the log &#8212; O(1) sequential write"""
        self._file.write(json.dumps(operation) + "\n")
        self._file.flush()       # push to OS buffer
        # os.fsync(self._file.fileno())  # uncomment for full durability

    def replay(self):
        """Read all operations from disk to rebuild state"""
        if not os.path.exists(self.path):
            return []
        with open(self.path, "r") as f:
            operations = []
            for line in f:
                if line.strip():
                    operations.append(json.loads(line))
            return operations

    def truncate(self):
        """Clear the log (called after a snapshot)"""
        self._file.close()
        self._file = open(self.path, "w")  # overwrite with empty file

    def close(self):
        self._file.close()
</code></code></pre><h3>What flush() vs fsync() Actually Means</h3><p>This distinction comes up in interviews, and you already understand it from managing databases:</p><pre><code><code>your code          &#8594;  OS buffer (RAM)  &#8594;  disk (permanent)
                   &#8593;                   &#8593;
              flush()              fsync()

flush(): "I'm done writing, push my data to the OS"
         Data is in the OS page cache &#8212; survives your process crashing
         Does NOT survive a power failure

fsync(): "Force the OS to write to physical disk RIGHT NOW"
         Survives power failure
         But costs ~1-10ms per call (huge at high throughput)
</code></code></pre><p>Redis <code>appendfsync everysec</code> calls fsync once per second &#8212; losing at most 1 second of data on power failure. That&#8217;s the sweet spot.</p><div><hr></div><h2>Step 2: Snapshots (RDB-Style)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9CiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9CiV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 424w, https://substackcdn.com/image/fetch/$s_!9CiV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 848w, https://substackcdn.com/image/fetch/$s_!9CiV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 1272w, https://substackcdn.com/image/fetch/$s_!9CiV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9CiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png" width="1270" height="478" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:478,&quot;width&quot;:1270,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:128675,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189775821?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9CiV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 424w, https://substackcdn.com/image/fetch/$s_!9CiV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 848w, https://substackcdn.com/image/fetch/$s_!9CiV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 1272w, https://substackcdn.com/image/fetch/$s_!9CiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29ed87c2-74e5-45a8-80db-33eb9e6ee120_1270x478.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Snapshots dump the entire in-memory state to a file periodically. On restart, loading a snapshot is instant &#8212; no need to replay thousands of log entries.</p><pre><code><code>import json
import os
import time
import threading

class SnapshotManager:
    def __init__(self, path="dump.rdb.json"):
        self.path = path

    def save(self, store_data: dict):
        """Atomic snapshot: write to temp file, then rename"""
        snapshot = {
            "timestamp": time.time(),
            "num_keys": len(store_data),
            "data": store_data
        }

        # Write to temp file first
        tmp_path = self.path + ".tmp"
        with open(tmp_path, "w") as f:
            json.dump(snapshot, f)

        # Atomic rename &#8212; this is the trick
        # If we crash during json.dump, the old snapshot is still intact
        # os.replace is atomic on most filesystems
        os.replace(tmp_path, self.path)

    def load(self) -&gt; dict:
        """Load snapshot from disk"""
        if not os.path.exists(self.path):
            return {}
        with open(self.path, "r") as f:
            snapshot = json.load(f)
        print(f"Snapshot loaded: {snapshot['num_keys']} keys "
              f"(saved at {time.ctime(snapshot['timestamp'])})")
        return snapshot["data"]
</code></code></pre><h3>Why the Temp File + Rename?</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6Hp2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6Hp2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 424w, https://substackcdn.com/image/fetch/$s_!6Hp2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 848w, https://substackcdn.com/image/fetch/$s_!6Hp2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 1272w, https://substackcdn.com/image/fetch/$s_!6Hp2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6Hp2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png" width="1456" height="559" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:112727,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189775821?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6Hp2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 424w, https://substackcdn.com/image/fetch/$s_!6Hp2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 848w, https://substackcdn.com/image/fetch/$s_!6Hp2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 1272w, https://substackcdn.com/image/fetch/$s_!6Hp2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e4588c5-4431-4dee-8aea-600548f84545_2078x798.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is an important systems concept. If you write directly to <code>dump.rdb.json</code> and crash halfway through, you&#8217;ve corrupted both the old data AND the new data. </p><p>By writing to a temp file and atomically renaming, either the old file or the new file exists &#8212; never a half-written one.</p><p>Redis does exactly this with its <code>BGSAVE</code> command. PostgreSQL does this with WAL checkpoints. You&#8217;ve probably seen <code>.tmp</code> files in production systems &#8212; now you know why they exist.</p><div><hr></div><h2>Step 3: Putting It All Together &#8212; MiniRedis</h2><p>Now we integrate both persistence strategies with our key-value store:</p><pre><code><code>import json
import os
import time
import threading

class MiniRedis:
    def __init__(self, wal_path="appendonly.aof", snapshot_path="dump.rdb.json",
                 snapshot_interval=300):
        self._store = {}
        self.wal = WriteAheadLog(wal_path)
        self.snapshots = SnapshotManager(snapshot_path)
        self.snapshot_interval = snapshot_interval
        self._write_count = 0

        # Recovery: snapshot first, then replay WAL
        self._recover()

        # Background snapshots
        self._start_auto_snapshot()

    def _recover(self):
        """
        Recovery order (same as Redis):
        1. Load snapshot  &#8594; gets bulk of data instantly
        2. Replay WAL     &#8594; applies writes since last snapshot
        """
        # Step 1: Load snapshot
        snapshot_data = self.snapshots.load()
        self._store = snapshot_data

        # Step 2: Replay WAL on top of snapshot
        operations = self.wal.replay()
        for op in operations:
            if op["op"] == "PUT":
                self._store[op["key"]] = {
                    "value": op["value"],
                    "expiry": op.get("expiry")
                }
            elif op["op"] == "DELETE":
                self._store.pop(op["key"], None)

        wal_count = len(operations)
        total = len(self._store)
        print(f"Recovery complete: {total} keys "
              f"({total - wal_count} from snapshot, {wal_count} from WAL)")

    # &#9472;&#9472; Core Operations &#9472;&#9472;

    def put(self, key, value, ttl_seconds=None):
        expiry = time.time() + ttl_seconds if ttl_seconds else None
        entry = {"value": value, "expiry": expiry}

        # WAL first, then memory (write-AHEAD log)
        self.wal.append({
            "op": "PUT", "key": key,
            "value": value, "expiry": expiry
        })
        self._store[key] = entry
        self._write_count += 1

    def get(self, key):
        entry = self._store.get(key)
        if entry is None:
            return None
        if entry["expiry"] and time.time() &gt; entry["expiry"]:
            self.delete(key)
            return None
        return entry["value"]

    def delete(self, key):
        if key in self._store:
            self.wal.append({"op": "DELETE", "key": key})
            del self._store[key]
            return True
        return False

    def keys(self):
        now = time.time()
        return [
            k for k, v in self._store.items()
            if v["expiry"] is None or now &lt;= v["expiry"]
        ]

    def dbsize(self):
        return len(self._store)

    # &#9472;&#9472; Snapshot Management &#9472;&#9472;

    def save(self):
        """Manual snapshot &#8212; like Redis BGSAVE"""
        self.snapshots.save(self._store.copy())
        self.wal.truncate()     # WAL is now redundant &#8212; snapshot has everything
        self._write_count = 0
        print(f"Snapshot saved: {len(self._store)} keys. WAL truncated.")

    def _start_auto_snapshot(self):
        """Background thread &#8212; like Redis save 300 10"""
        def auto_save():
            while True:
                time.sleep(self.snapshot_interval)
                if self._write_count &gt; 0:
                    self.save()
        t = threading.Thread(target=auto_save, daemon=True)
        t.start()
</code></code></pre><div><hr></div><h2>Step 4: Testing the Crash-Recovery Cycle</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OSgK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OSgK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 424w, https://substackcdn.com/image/fetch/$s_!OSgK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 848w, https://substackcdn.com/image/fetch/$s_!OSgK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 1272w, https://substackcdn.com/image/fetch/$s_!OSgK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OSgK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png" width="1270" height="554" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:554,&quot;width&quot;:1270,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117274,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189775821?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OSgK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 424w, https://substackcdn.com/image/fetch/$s_!OSgK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 848w, https://substackcdn.com/image/fetch/$s_!OSgK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 1272w, https://substackcdn.com/image/fetch/$s_!OSgK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b6e35d-ab4e-48d0-bdd5-35024a5a5aed_1270x554.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let&#8217;s prove it works:</p><pre><code><code># === Session 1: Write data ===
store = MiniRedis(snapshot_interval=10)

store.put("user:1", "sharon")
store.put("user:2", "alex")
store.put("city", "dubai", ttl_seconds=3600)
store.put("temp_key", "delete_me")
store.delete("temp_key")

print(f"Keys: {store.keys()}")
# Keys: ['user:1', 'user:2', 'city']

# Force a snapshot
store.save()
# Snapshot saved: 3 keys. WAL truncated.

# Write more data AFTER the snapshot
store.put("user:3", "jordan")
store.put("user:4", "casey")

# Now imagine the process crashes here...
# The WAL has user:3 and user:4
# The snapshot has user:1, user:2, city
</code></code></pre><pre><code><code># === Session 2: Restart after "crash" ===
store = MiniRedis(snapshot_interval=10)
# Output:
# Snapshot loaded: 3 keys (saved at Thu Feb 27 20:30:00 2026)
# Recovery complete: 5 keys (3 from snapshot, 2 from WAL)

print(store.get("user:1"))    # "sharon"  &#8212; from snapshot
print(store.get("user:4"))    # "casey"   &#8212; from WAL replay
print(store.get("temp_key"))  # None      &#8212; correctly deleted
</code></code></pre><p>Nothing was lost. The snapshot provided most of the data instantly, and the WAL filled in the gaps.</p><div><hr></div><h2>The Recovery Timeline (What Interviewers Want to Hear)</h2><pre><code><code>Timeline of writes:
&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9658;

 write  write  write  SNAPSHOT  write  write  CRASH
  1      2      3     (saves     4      5
                       1,2,3)         &#8593; these are
                                       in the WAL

On restart:
1. Load snapshot    &#8594; restores keys 1, 2, 3       (instant)
2. Replay WAL       &#8594; restores keys 4, 5          (fast)
3. Ready to serve   &#8594; lost: 0 keys
</code></code></pre><div><hr></div><h2>The fsync Tradeoff Table</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xhIk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xhIk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 424w, https://substackcdn.com/image/fetch/$s_!xhIk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 848w, https://substackcdn.com/image/fetch/$s_!xhIk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 1272w, https://substackcdn.com/image/fetch/$s_!xhIk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xhIk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png" width="1272" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1272,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:120200,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189775821?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xhIk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 424w, https://substackcdn.com/image/fetch/$s_!xhIk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 848w, https://substackcdn.com/image/fetch/$s_!xhIk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 1272w, https://substackcdn.com/image/fetch/$s_!xhIk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0e0c6-b315-400b-a72f-5f2776b0ea36_1272x562.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>How This Maps to Your DevOps World</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5dPj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5dPj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 424w, https://substackcdn.com/image/fetch/$s_!5dPj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 848w, https://substackcdn.com/image/fetch/$s_!5dPj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 1272w, https://substackcdn.com/image/fetch/$s_!5dPj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5dPj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png" width="1456" height="1257" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1257,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:250989,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189775821?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5dPj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 424w, https://substackcdn.com/image/fetch/$s_!5dPj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 848w, https://substackcdn.com/image/fetch/$s_!5dPj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 1272w, https://substackcdn.com/image/fetch/$s_!5dPj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff04496d3-aa79-4510-86da-bbb6862a8247_1596x1378.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You&#8217;ve been configuring these settings in production for years. Now you can implement them and explain why they exist.</p><div><hr></div><h2>Interview Walkthrough Script</h2><p>When the interviewer extends &#8220;Design a key-value store&#8221; with &#8220;How would you make it persistent?&#8221;:</p><blockquote><p><strong>&#8220;I&#8217;d combine two persistence strategies &#8212; write-ahead logging and periodic snapshots.</strong></p><p><strong>For every write, I&#8217;d append the operation to an append-only file before updating memory. This is sequential I/O &#8212; about 5000x faster than random writes. On crash, I replay the log to rebuild state.</strong></p><p><strong>The problem is the log grows forever and replay gets slow. So I&#8217;d run periodic snapshots &#8212; dump the entire state to a file using an atomic write (temp file + rename). After each snapshot, I truncate the log.</strong></p><p><strong>On recovery: load the snapshot first for speed, then replay only the WAL entries since that snapshot. You get fast recovery plus minimal data loss.</strong></p><p><strong>The durability knob is fsync frequency &#8212; fsync every write for zero data loss, or every second for a good balance. That&#8217;s a product decision, not an engineering one.&#8221;</strong></p></blockquote><div><hr></div><h2>Challenge: Try It Yourself</h2><p>Extend MiniRedis with these features (solutions next week):</p><ol><li><p><strong>fsync policies:</strong> Add a <code>fsync_policy</code> parameter that supports <code>"always"</code>, <code>"everysec"</code>, and <code>"no"</code>. Implement the <code>"everysec"</code> mode using a background thread.</p></li><li><p><strong>WAL compaction without snapshot:</strong> Instead of truncating the WAL after a snapshot, rewrite it with only the current state. This is what Redis <code>BGREWRITEAOF</code> does.</p></li><li><p><strong>Binary protocol:</strong> Right now the WAL uses JSON (human-readable but large). Implement a binary format using <code>struct.pack</code> for the WAL entries. Compare file sizes.</p></li></ol><div><hr></div><p><em>Next week in Crack That Weekly: <strong>Implement TTL &amp; Key Expiry in Python</strong> &#8212; we&#8217;ll build both lazy and active expiration, exactly how Redis handles millions of expiring keys without scanning them all.</em></p><p><em>Previous issue: <a href="https://www.crackthat.io/p/build-redis-python-key-value-store">Build Your Own Redis: Key-Value Store From Scratch</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>About Crack That Weekly:</strong> A weekly newsletter that bridges the gap between real-world DevOps experience and coding interview prep. Every issue builds a real system from scratch in Python, connecting design patterns, data structures, and algorithms to tools you already use.</p><p>Written by Sharon Sahadevan, a DevOps engineer who got tired of interview prep that ignores operational experience.</p>]]></content:encoded></item><item><title><![CDATA[Build Your Own Redis in Python: Key-Value Store From Scratch]]></title><description><![CDATA[Why every DevOps engineer already understands Redis internals &#8212; and how to prove it in a coding interview]]></description><link>https://www.crackthat.io/p/build-redis-python-key-value-store</link><guid isPermaLink="false">https://www.crackthat.io/p/build-redis-python-key-value-store</guid><dc:creator><![CDATA[Sharon Sahadevan]]></dc:creator><pubDate>Sat, 28 Feb 2026 15:05:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UBVx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You&#8217;ve typed <code>redis.set("session:abc", token)</code> a thousand times. You&#8217;ve configured <code>redis.conf</code>, set up replication, monitored memory with <code>INFO</code>, and debugged eviction policies at 2 AM.</p><p>But if an interviewer asks you to <strong>build a key-value store from scratch in Python</strong>, can you do it?</p><p>Most DevOps engineers freeze here &#8212; not because they don&#8217;t understand the concepts, but because they&#8217;ve never translated their operational knowledge into code. This issue fixes that.</p><p>By the end, you&#8217;ll have a working key-value store in Python that supports <code>get</code>, <code>put</code>, <code>delete</code>, and TTL-based expiry. More importantly, you&#8217;ll understand exactly which <strong>design pattern</strong> and <strong>data structure</strong> powers it &#8212; and how to explain your choices in an interview.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/build-redis-python-key-value-store?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Crack That Weekly! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/p/build-redis-python-key-value-store?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.crackthat.io/p/build-redis-python-key-value-store?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><div><hr></div><h2>The 3-Question Framework: How to Approach Any System Design Problem</h2><p>Before writing a single line of code, train yourself to ask three questions. This framework works for every system design problem you&#8217;ll face in an interview:</p><p><strong>Question 1: What does the system DO?</strong> &#8594; This reveals the <strong>design pattern</strong>.</p><p>A key-value store sits between a client and data storage. It intercepts requests, stores data, and returns it on demand. That&#8217;s the <strong>Proxy pattern</strong> &#8212; the same pattern behind Nginx reverse proxying, CDN caching, and API gateways. You already use proxies daily; now you&#8217;re building one.</p><p><strong>Question 2: What operations must be FAST?</strong> &#8594; This reveals the <strong>data structure</strong>.</p><p>A key-value store needs O(1) lookup, O(1) insert, and O(1) delete. There&#8217;s exactly one data structure that gives you all three: a <strong>hash map</strong>. In Python, that&#8217;s a <code>dict</code>.</p><p><strong>Question 3: What&#8217;s the core LOGIC?</strong> &#8594; This reveals the <strong>algorithm</strong>.</p><p>For basic get/put, it&#8217;s straightforward hash map operations. For TTL (time-to-live), we need <strong>lazy expiration</strong> &#8212; check if a key has expired only when someone tries to access it. This is exactly how Redis handles expiry in practice.</p><pre><code><code>System: Key-Value Store
Pattern: Proxy (sits between client and data)
Data Structure: dict (hash map) &#8212; O(1) for get, put, delete
Algorithm: Lazy expiration for TTL
</code></code></pre><p>Memorize this framework. It works for every system design question.</p><div><hr></div><h2>Step 1: The Simplest Key-Value Store (10 Lines)</h2><p>Let&#8217;s start with the absolute minimum. This is what you&#8217;d write in the first 2 minutes of an interview:</p><pre><code><code>class KeyValueStore:
    def __init__(self):
        self._store = {}

    def put(self, key, value):
        self._store[key] = value

    def get(self, key):
        return self._store.get(key)

    def delete(self, key):
        return self._store.pop(key, None) is not None

    def keys(self):
        return list(self._store.keys())
</code></code></pre><p>That&#8217;s it. A working key-value store. The <code>_store</code> prefix signals it&#8217;s a private implementation detail &#8212; a Pythonic convention interviewers notice.</p><p>But an interviewer will immediately ask: &#8220;What about expiry? What happens when keys should expire after a certain time?&#8221;</p><div><hr></div><h2>Step 2: Adding TTL (Time-To-Live) &#8212; Lazy Expiration</h2><p>This is where it gets interesting. Redis supports <code>SETEX</code> and <code>EXPIRE</code> commands that make keys auto-delete after a timeout. Let&#8217;s implement the same thing.</p><p>The trick is <strong>lazy expiration</strong>: don&#8217;t actively scan for expired keys. Instead, check the expiry timestamp when someone accesses the key. If it&#8217;s expired, delete it and return <code>None</code>.</p><pre><code><code>import time

class KeyValueStore:
    def __init__(self):
        self._store = {}    # key &#8594; {"value": ..., "expiry": timestamp | None}

    def put(self, key, value, ttl_seconds=None):
        expiry = time.time() + ttl_seconds if ttl_seconds else None
        self._store[key] = {"value": value, "expiry": expiry}

    def get(self, key):
        if key not in self._store:
            return None

        entry = self._store[key]

        # Lazy expiration: check on access
        if entry["expiry"] and time.time() &gt; entry["expiry"]:
            del self._store[key]
            return None

        return entry["value"]

    def delete(self, key):
        return self._store.pop(key, None) is not None

    def keys(self):
        now = time.time()
        return [
            k for k, v in self._store.items()
            if v["expiry"] is None or now &lt;= v["expiry"]
        ]
</code></code></pre><h3>Why lazy expiration?</h3><p>Redis actually uses <strong>both</strong> lazy and active expiration:</p><ul><li><p><strong>Lazy:</strong> Check TTL on every <code>GET</code>. If expired, delete and return nil. This is what we implemented above.</p></li><li><p><strong>Active:</strong> A background job randomly samples 20 keys, deletes expired ones, and repeats if more than 25% were expired.</p></li></ul><p>In an interview, implementing lazy expiration is enough. But mentioning that Redis combines both approaches shows depth &#8212; and that&#8217;s what separates a &#8220;pass&#8221; from a &#8220;strong hire.&#8221;</p><div><hr></div><h2>Step 3: Making It a Real Server With FastAPI</h2><p>Your Python class is the engine. But how does a browser, CLI tool, or another service actually use it? Through an API layer. This is the piece most tutorials skip, and it&#8217;s the piece that clicks everything together:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UBVx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UBVx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 424w, https://substackcdn.com/image/fetch/$s_!UBVx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 848w, https://substackcdn.com/image/fetch/$s_!UBVx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 1272w, https://substackcdn.com/image/fetch/$s_!UBVx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UBVx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png" width="1360" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56274,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.crackthat.io/i/189268707?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UBVx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 424w, https://substackcdn.com/image/fetch/$s_!UBVx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 848w, https://substackcdn.com/image/fetch/$s_!UBVx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 1272w, https://substackcdn.com/image/fetch/$s_!UBVx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F040b4ace-fdce-467e-8bcd-71818015d2bf_1360x480.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><pre><code><code>from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()
store = KeyValueStore()     # lives in memory

class PutRequest(BaseModel):
    value: str
    ttl_seconds: int | None = None

@app.put("/store/{key}")
def put_key(key: str, req: PutRequest):
    store.put(key, req.value, req.ttl_seconds)
    return {"status": "ok", "key": key}

@app.get("/store/{key}")
def get_key(key: str):
    value = store.get(key)
    if value is None:
        raise HTTPException(404, "Key not found or expired")
    return {"key": key, "value": value}

@app.delete("/store/{key}")
def delete_key(key: str):
    if not store.delete(key):
        raise HTTPException(404, "Key not found")
    return {"status": "deleted"}

@app.get("/store")
def list_keys():
    return {"keys": store.keys()}
</code></code></pre><p>Run it with <code>uvicorn api:app --reload</code>, and now you can test with curl:</p><pre><code><code>curl -X PUT localhost:8000/store/name \
  -d '{"value":"sharon","ttl_seconds":60}' \
  -H "Content-Type: application/json"

curl localhost:8000/store/name
# {"key":"name","value":"sharon"}
</code></code></pre><p>In system design interviews, being able to describe this layered architecture &#8212; <strong>class &#8594; API &#8594; client</strong> &#8212; demonstrates that you think in terms of real systems, not just algorithms.</p><div><hr></div><h2>How to Explain This in an Interview (The 5-Minute Script)</h2><p>Here&#8217;s exactly how to walk through this when an interviewer says &#8220;Design a key-value store&#8221;:</p><blockquote><p><strong>&#8220;I&#8217;d start with an in-memory hash map for O(1) reads and writes &#8212; in Python, that&#8217;s a dict.</strong></p><p><strong>For TTL support, I&#8217;d store each value alongside an expiry timestamp. On every GET, I&#8217;d check the timestamp and lazily evict expired keys. This avoids background threads for the basic case.</strong></p><p><strong>For the API layer, I&#8217;d use FastAPI with PUT, GET, and DELETE endpoints mapping directly to the store&#8217;s methods. Pydantic handles request validation.</strong></p><p><strong>The tradeoff right now is durability &#8212; everything is in memory. If the process restarts, all data is lost. To fix that, I&#8217;d add a write-ahead log: append every PUT and DELETE to a file. On restart, replay the log to rebuild state. This is exactly what Redis does with AOF persistence.</strong></p><p><strong>For production, I&#8217;d also consider: snapshots for faster recovery, background compaction to keep the log from growing unbounded, and replication for high availability.&#8221;</strong></p></blockquote><p>This answer covers data structure choice, algorithm design, API architecture, persistence strategy, and production concerns &#8212; all in under 2 minutes. That&#8217;s a strong hire signal.</p><div><hr></div><h2>Your DevOps Advantage: What You Already Know</h2><p>If you&#8217;re a DevOps engineer reading this, you&#8217;ve been working with these concepts every day without realizing they&#8217;re &#8220;interview material&#8221;:</p><p>You&#8217;re not learning new concepts. You&#8217;re learning to <strong>name them</strong> and <strong>code them in Python</strong>.</p><div><hr></div><h2>Challenge: Try It Yourself</h2><p>Extend the key-value store with these features (solutions in next week&#8217;s issue):</p><ol><li><p><strong>Active expiration:</strong> Add a background thread that periodically scans and removes expired keys. Hint: use <code>threading.Thread</code> with <code>daemon=True</code>.</p></li><li><p><strong>Max capacity:</strong> Add a <code>max_keys</code> parameter. When the store is full, reject new keys with an error. (Bonus: instead of rejecting, evict the oldest key &#8212; that&#8217;s an LRU cache, which we&#8217;ll build in Issue 3!)</p></li><li><p><strong>Key patterns:</strong> Implement a <code>search(pattern)</code> method that returns all keys matching a glob pattern like <code>session:*</code>. Hint: <code>fnmatch.fnmatch()</code>.</p></li></ol><div><hr></div><p><em>Next week in Crack That Weekly: <strong>Redis Persistence in Python &#8212; Write-Ahead Logs &amp; Snapshots.</strong> We&#8217;ll make our key-value store survive restarts using the exact same techniques Redis uses under the hood.</em></p><p><em>If this helped you see the connection between your DevOps work and coding interviews, share it with a fellow engineer who&#8217;s preparing for interviews.</em></p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.crackthat.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Crack That Weekly is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p><strong>About Crack That Weekly:</strong> A weekly newsletter that bridges the gap between real-world DevOps experience and coding interview prep. Every issue builds a real system from scratch in Python, connecting design patterns, data structures, and algorithms to tools you already use. </p><p>Written by Sharon Sahadevan, a DevOps engineer who got tired of interview prep that ignores operational experience.</p>]]></content:encoded></item></channel></rss>