<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>huizhou92&#39;s Blog</title>
        <link>https://huizhou92.com/</link>
        <description>Recent content on huizhou92&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <copyright>Copyright © 2023 huizhou92</copyright>
        <lastBuildDate>Mon, 02 Mar 2026 23:03:33 +0800</lastBuildDate><atom:link href="https://huizhou92.com/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Why Your AI Agent Keeps Forgetting: A Practical Memory Architecture for Individual Users</title>
        <link>https://huizhou92.com/p/why-your-ai-agent-keeps-forgetting-a-practical-memory-architecture-for-individual-users/</link>
        <pubDate>Mon, 02 Mar 2026 23:03:33 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/why-your-ai-agent-keeps-forgetting-a-practical-memory-architecture-for-individual-users/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2026/03/8b8971ca1398b1df35a88d5ba9c7934a.png" alt="Featured image of post Why Your AI Agent Keeps Forgetting: A Practical Memory Architecture for Individual Users" /&gt;&lt;h3 id=&#34;the-problem-why-does-your-agent-get-dumber-over-time&#34;&gt;The Problem: Why Does Your Agent Get Dumber Over Time?
&lt;/h3&gt;&lt;p&gt;Picture this: you&amp;rsquo;ve been working with an AI agent for weeks, patiently teaching it your project structure, personal preferences, and workflows. Within a single conversation, it remembers your instructions just fine — but the next day, when you start a new session, it&amp;rsquo;s like meeting a stranger. Worse still, it starts &lt;strong&gt;confidently fabricating events that never happened&lt;/strong&gt;, asks you the same questions again, and forgets critical decisions made just hours ago.&lt;/p&gt;
&lt;!-- more--&gt;
&lt;p&gt;If this sounds familiar, don&amp;rsquo;t blame the agent&amp;rsquo;s intelligence — &lt;strong&gt;the problem is a fundamental flaw in memory system design&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Most people assume AI &amp;ldquo;has memory&amp;rdquo; because it can recall earlier parts of a conversation. What&amp;rsquo;s actually happening is far simpler: the agent is using its &lt;strong&gt;Context Window&lt;/strong&gt; — a temporary workspace, not permanent storage. When the conversation gets too long and triggers compaction, or when you start a new session, that workspace gets wiped clean.&lt;/p&gt;
&lt;p&gt;OpenClaw tries to fix this by persisting long-term memory to local Markdown files (&lt;code&gt;MEMORY.md&lt;/code&gt;, daily logs, etc.). In theory, memories can span months or even years. Files live on disk, are human-readable, editable, and git-versionable — sounds perfect, right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yet countless users report that their agents become progressively &amp;ldquo;demented&amp;rdquo; over time.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The root causes boil down to three layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Compaction-induced &amp;ldquo;summary amnesia&amp;rdquo;&lt;/strong&gt;: When the Context Window approaches its ceiling (say, Claude Opus 4.6&amp;rsquo;s 200K token boundary), OpenClaw automatically triggers compaction — it asks the model to &amp;ldquo;summarize&amp;rdquo; earlier conversation into shorter chunks, then discards the originals. Critical details get lost in translation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retrieval failure — &amp;ldquo;remembered but can&amp;rsquo;t recall&amp;rdquo;&lt;/strong&gt;: Important information does get written to disk (&lt;code&gt;MEMORY.md&lt;/code&gt;, &lt;code&gt;daily/YYYY-MM-DD.md&lt;/code&gt;), but retrieval depends on &lt;code&gt;memory_search&lt;/code&gt; / &lt;code&gt;memory_get&lt;/code&gt; tools. Missed recalls happen because the underlying embedding model isn&amp;rsquo;t strong enough, pure semantic search misses keyword matches, and &lt;code&gt;MEMORY.md&lt;/code&gt; bloats into an unwieldy mess over time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No forgetting + no conflict resolution&lt;/strong&gt;: OpenClaw almost never forgets — files only grow, never shrink. Outdated preferences, abandoned project decisions, early incorrect instructions — they all pile up. When new information arrives, the system doesn&amp;rsquo;t &amp;ldquo;update&amp;rdquo;; it only appends. Contradictions accumulate, noise dilutes signal during retrieval. &lt;strong&gt;Eventually the agent gets confused and starts fabricating stories to reconcile conflicting &amp;ldquo;facts.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/03/d44ca3ec9ba8f709634a5755489a4d53.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Context Window vs. Persistent Memory&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;six-structural-flaws-in-current-memory-systems&#34;&gt;Six Structural Flaws in Current Memory Systems
&lt;/h3&gt;&lt;p&gt;OpenClaw&amp;rsquo;s default memory scheme — &lt;strong&gt;Markdown files + vector search&lt;/strong&gt; — has obvious strengths: human-readable, git-versionable, zero external dependencies. But in practice, I&amp;rsquo;ve found six structural weaknesses, and none of them are trivial:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Flat and undifferentiated&lt;/strong&gt;: A casual chat from a year ago carries the same weight as yesterday&amp;rsquo;s architecture decision. Search results drown in noise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. No forgetting mechanism&lt;/strong&gt;: Append-only, never delete. The memory system eventually drowns itself — stale information masquerades as &amp;ldquo;facts&amp;rdquo; and pollutes current decisions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. No automatic consolidation&lt;/strong&gt;: Important insights must be manually distilled and written in. The agent never proactively &amp;ldquo;digests&amp;rdquo; what happened today.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. No temporal reasoning&lt;/strong&gt;: The agent knows &amp;ldquo;something happened&amp;rdquo; but not whether it was 3 days or 3 months ago — it simply can&amp;rsquo;t judge whether information is stale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. No memory promotion&lt;/strong&gt;: Critical decisions buried in logs stay buried forever. No mechanism promotes them to the long-term knowledge base.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. No knowledge graph&lt;/strong&gt;: Unable to express relational knowledge like &amp;ldquo;A knows B&amp;rdquo; or &amp;ldquo;Project X depends on tool Y.&amp;rdquo; Every memory is an isolated, flat entry.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/03/cb1fc4a1b90759dbfd5f329e89cdcd56.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Six Structural Flaws — Diagnostic Diagram&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;what-does-academia-say-february-2026-research-review&#34;&gt;What Does Academia Say? (February 2026 Research Review)
&lt;/h3&gt;&lt;p&gt;In February 2026, agent memory suddenly became a hot academic battleground — 10+ papers published in a single month. One survey paper with 59 co-authors proposed a three-dimensional taxonomy for memory systems.&lt;/p&gt;
&lt;p&gt;Let me highlight the key ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A-MEM&lt;/strong&gt; (NeurIPS 2025): Borrows from the Zettelkasten note-taking method — new memories auto-generate keywords and associative links, building an interconnected knowledge network. A fascinating approach.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;xMemory&lt;/strong&gt; (ICML 2026): Decouples memory into semantic components, organizes them hierarchically, and supports top-down retrieval, dramatically reducing retrieval noise.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BudgetMem&lt;/strong&gt;: Three-layer budget structure + RL router that prioritizes retrieval resources for the most important memories.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;InfMem&lt;/strong&gt;: PreThink-Retrieve-Write protocol — the agent &amp;ldquo;thinks about what to look for&amp;rdquo; before retrieval, boosting accuracy by 10–12%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But what&amp;rsquo;s even more worth noting are two &lt;strong&gt;industry warnings&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Serial Collapse&lt;/strong&gt; (Dark Side of the Moon paper): Agents may gradually degenerate into not using memory at all — even when the memory system is running perfectly. Memory existing ≠ Agent using it.&lt;/p&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Memory Misevolution&lt;/strong&gt; (TAME paper): Accumulation of &amp;ldquo;toxic shortcuts&amp;rdquo; during normal iteration — memory strategies that appear efficient but violate constraints.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;These two warnings are extremely common in practice. You&amp;rsquo;ve probably noticed it yourself: sometimes the agent has memory files right there but simply never queries them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/03/523749e958151f2da7d8c8f77a2a493b.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Agent Memory Research Taxonomy (February 2026)&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;the-solution-three-layer-memory-architecture&#34;&gt;The Solution: Three-Layer Memory Architecture
&lt;/h3&gt;&lt;p&gt;Synthesizing all the research above plus my own hands-on experience, here&amp;rsquo;s a &lt;strong&gt;deterministic, zero-cost architecture&lt;/strong&gt; for individual users.&lt;/p&gt;
&lt;p&gt;First, let me show you my own memory system directory structure:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root@ubuntu-4gb-openclaw:~/.openclaw/workspace/memory# tree
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── daily
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── 2026-03-01.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── episodic
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── hotspots_2026-02-18.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── hot-topics-2026-02-17.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── hot-trends-2026-02-18.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── INDEX.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── keywords_20260217_1600.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── lessons
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── api-guide.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── mistakes.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── system-deployment.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── NOW.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── people
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── 老板.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── rules
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── storage-routing.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── scripts
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── archive-stale.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── daily_digest.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── semantic
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ├── golang-patterns.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ├── writing-frameworks.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    └── writing-style-guide-huizhou92.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s walk through each layer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Short-term layer: &lt;code&gt;NOW.md&lt;/code&gt; (the most overlooked design)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NOW.md&lt;/code&gt; is the &lt;strong&gt;highest information-density&lt;/strong&gt; file in the entire architecture.&lt;/p&gt;
&lt;p&gt;The core idea is straightforward: after every restart, the agent&amp;rsquo;s first action should be reading &lt;code&gt;NOW.md&lt;/code&gt; — not searching through a massive memory library. It&amp;rsquo;s the essence extractor, the &amp;ldquo;where did I leave off&amp;rdquo; quick-recovery tool, the life raft after compaction.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# NOW.md — Workspace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;&lt;/span&gt;Updated: YYYY-MM-DD HH:MM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Today&amp;#39;s Focus
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; ✅ Completed items
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## In Progress
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 🔄 Unfinished tasks (including blockers)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Current Priorities
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;&lt;/span&gt;| Priority | Task | Status |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|----------|------|--------|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| P0 | Most important thing | In progress |
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Key rule&lt;/strong&gt;: &lt;code&gt;NOW.md&lt;/code&gt; is the &lt;strong&gt;only file allowed to be overwritten&lt;/strong&gt;. All other memory files are append-only.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Medium-term layer: Daily logs&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Filename: &lt;code&gt;memory/YYYY-MM-DD.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Write mode: &lt;strong&gt;Append-only, never overwrite&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Format suggestion: &lt;code&gt;### HH:MM — Event title + content description&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Principle: Better too much than too little. Logs are raw material; distillation happens through nightly automation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Long-term layer: Structured subdirectories&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Knowledge files use a standardized YAML frontmatter:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;File Title&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ld&#34;&gt;2026-02-28&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;lessons&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;priority&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;🔴         &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 🔴 Core | 🟡 Important | 🟢 Reference&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;active       &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# active | stale | superseded | conflict&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;last_verified&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ld&#34;&gt;2026-02-28&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;relevant tags]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Entries with &lt;code&gt;last_verified&lt;/code&gt; older than 30 days are auto-flagged as ⚠️ &lt;code&gt;stale&lt;/code&gt;, prompting manual review.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;INDEX.md&lt;/code&gt;: Knowledge base health dashboard&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| File | Priority | Status | Last Verified | Description |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|------|----------|--------|---------------|-------------|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| tools | 🔴 | ✅ active | 2026-02-28 | Verified tool list |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| api-guide | 🟡 | ⚠️ stale | 2026-01-10 | Possibly outdated, needs review |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| old-workflow | ⚪ | &lt;span class=&#34;gd&#34;&gt;~~superseded~~&lt;/span&gt; | 2025-12-01 | Replaced by new approach |
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;On startup, the agent glances at &lt;code&gt;INDEX.md&lt;/code&gt; and knows the health status of the entire knowledge base in seconds.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/03/def61d6ad3edb44d3f17ebfef951f1f4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Three-Layer Memory Architecture&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;lightweight-knowledge-graph-sqlite-triple-table&#34;&gt;Lightweight Knowledge Graph: SQLite Triple Table
&lt;/h3&gt;&lt;p&gt;This is the most complex of the six flaws, and the fundamental limitation that pure Markdown cannot break through.&lt;/p&gt;
&lt;h4 id=&#34;why-do-we-need-a-knowledge-graph&#34;&gt;Why Do We Need a Knowledge Graph?
&lt;/h4&gt;&lt;p&gt;Markdown files can only store &lt;strong&gt;flat facts&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Brian prefers concise communication. Project X uses PostgreSQL. Tool Y requires an API Key.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;But real-world knowledge has &lt;strong&gt;relationships&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Brian → responsible for → Project X → depends on → Tool Y → requires → API Key (stored in secrets/)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;When the agent is asked &amp;ldquo;What API Key does Brian&amp;rsquo;s project need?&amp;rdquo;, pure vector search simply cannot complete this three-hop inference.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The solution: a SQLite triple table.&lt;/strong&gt; No external dependencies, no deployment overhead — perfectly sufficient for personal knowledge relationship management:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;triples&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Entity (e.g., &amp;#34;Brian&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;predicate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Relationship (e.g., &amp;#34;responsible for&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Object (e.g., &amp;#34;Project Alpha&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;added_date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;confidence&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;REAL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DEFAULT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Use Python or Node for reads, writes, and queries. The entire database is a single &lt;code&gt;.db&lt;/code&gt; file sitting alongside your Markdown memory — portable and trivially easy to back up.&lt;/p&gt;
&lt;h4 id=&#34;when-to-write-to-the-knowledge-graph&#34;&gt;When to Write to the Knowledge Graph
&lt;/h4&gt;&lt;p&gt;Not all information deserves graphing. My recommendation is to limit it to these scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;System dependencies&lt;/strong&gt;: Project A depends on tool B, which requires configuration C&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resource locations&lt;/strong&gt;: Where credentials / files / APIs are stored&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Historical associations&lt;/strong&gt;: Decision X was made because of event Y&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Daily facts (preferences, operation logs) are fine in Markdown — don&amp;rsquo;t over-graph.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;file:///Users/hxzhouh/lobsterai/project/illustrations/ai-agent-memory-architecture/05-framework-knowledge-graph.png?lastModify=1772375639&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Knowledge Graph Example — Multi-hop Relational Reasoning&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;forgetting-mechanism-active-forgetting-matters-more-than-passive-retention&#34;&gt;Forgetting Mechanism: Active Forgetting Matters More Than Passive Retention
&lt;/h3&gt;&lt;p&gt;This might sound counterintuitive, but &lt;strong&gt;forgetting is one of the most critical capabilities of a memory system&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Each memory entry is tagged with priority and expiration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; [🟢LOW][CONTEXT] added:2026-02-01 expires:2026-03-01 · Context for a temporary task
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The retention policy is simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 🔴 HIGH — Core knowledge, never expires, never archives
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 🟡 MED — Important knowledge, long-term retention, manually evaluate for staleness
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 🟢 LOW — Reference information, proactively add &lt;span class=&#34;sb&#34;&gt;`expires:`&lt;/span&gt; field for system auto-cleanup
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;.archive/&lt;/code&gt; cold storage design&lt;/strong&gt;: Name the directory with a dot prefix. OpenClaw&amp;rsquo;s QMD vector engine automatically skips dot-prefixed directories, giving you zero-configuration hot/cold index separation. Archived files aren&amp;rsquo;t deleted — they remain directly accessible via the filesystem.&lt;/p&gt;
&lt;p&gt;A simple weekly cron script handles cleanup: scan for expired &lt;code&gt;expires:&lt;/code&gt; fields, move those entries into &lt;code&gt;.archive/&lt;/code&gt;, and update &lt;code&gt;INDEX.md&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/03/610af8262101fa80fbecdd43ea732d89.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Forgetting Mechanism — Expiration and Archiving Workflow&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;automatic-consolidation-teaching-your-memory-system-to-digest&#34;&gt;Automatic Consolidation: Teaching Your Memory System to Digest
&lt;/h3&gt;&lt;p&gt;Good storage structure alone isn&amp;rsquo;t enough — if memories can&amp;rsquo;t auto-consolidate, it&amp;rsquo;s just a manually maintained folder.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Temporal annotation is key.&lt;/strong&gt; Every memory entry must include time-relationship markers, solving the &amp;ldquo;no temporal reasoning&amp;rdquo; problem mentioned earlier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;First appeared: …&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Following previous X, today completed Y&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;N days since first discussion, status: completed&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Nightly consolidation (via cron)&lt;/strong&gt;: Set up a nightly cron job that calls your existing LLM API to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Read today&amp;rsquo;s daily log (&lt;code&gt;memory/YYYY-MM-DD.md&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Extract key decisions, lessons learned, and status changes&lt;/li&gt;
&lt;li&gt;Promote important entries to long-term knowledge files (with proper YAML frontmatter)&lt;/li&gt;
&lt;li&gt;Update &lt;code&gt;NOW.md&lt;/code&gt; with tomorrow&amp;rsquo;s priorities&lt;/li&gt;
&lt;li&gt;Update &lt;code&gt;INDEX.md&lt;/code&gt; health dashboard&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One easy pitfall here: &lt;strong&gt;always read the target file before writing&lt;/strong&gt;, check whether similar content already exists, and avoid duplicate entries and memory conflicts (a.k.a. the HaluMem problem).&lt;/p&gt;
&lt;h3 id=&#34;the-setup-checklist&#34;&gt;The Setup Checklist
&lt;/h3&gt;&lt;p&gt;Here&amp;rsquo;s everything you need to implement this architecture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Three-layer file structure&lt;/strong&gt;: &lt;code&gt;NOW.md&lt;/code&gt; + &lt;code&gt;memory/YYYY-MM-DD.md&lt;/code&gt; + structured subdirectories (&lt;code&gt;lessons/&lt;/code&gt;, &lt;code&gt;tools/&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;INDEX.md&lt;/code&gt;&lt;/strong&gt;: Knowledge base health dashboard, read on startup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nightly cron job&lt;/strong&gt;: Calls your existing LLM API for auto-consolidation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;expires&lt;/code&gt; field + weekly cleanup script&lt;/strong&gt;: Active forgetting mechanism&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in vector search&lt;/strong&gt;: No extra deployment (OpenClaw ships with it)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQLite triple table&lt;/strong&gt; (optional): Only add if you genuinely need multi-hop relational reasoning&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;No extra resources needed&lt;/strong&gt; — everything runs on what you already have.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/03/ac15bda116079c89680fa5a7daf01b44.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Memory Configuration Recommendations — Scenario Comparison&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;three-common-misconceptions&#34;&gt;Three Common Misconceptions
&lt;/h3&gt;&lt;p&gt;In practice, I&amp;rsquo;ve seen plenty of people stumble into these traps. Here are the three most common:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception #1: More memory is always better.&lt;/strong&gt; Quite the opposite — stale, low-quality memories are more dangerous than no memory at all. They masquerade as &amp;ldquo;facts&amp;rdquo; and skew the agent&amp;rsquo;s judgment. Forgetting mechanisms are just as important as writing mechanisms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception #2: Write-only, never read.&lt;/strong&gt; Writing information into memory doesn&amp;rsquo;t mean the agent will use it. Serial Collapse — where agents gradually stop querying memory — is a real phenomenon. Regularly verifying that the agent actually uses its memory is as critical as building the memory system itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misconception #3: Everything belongs in the knowledge graph.&lt;/strong&gt; The value of a knowledge graph lies in relational reasoning, not storage. Daily preferences and operation logs are perfectly fine in Markdown — only knowledge that genuinely requires multi-hop reasoning deserves to be graphed.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;A good memory system isn&amp;rsquo;t the one that stores the most — it&amp;rsquo;s the one that &lt;strong&gt;delivers the right information, in the right form, at the right moment&lt;/strong&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Start with the three-layer architecture (&lt;code&gt;NOW.md&lt;/code&gt; + daily logs + structured long-term files), add nightly auto-consolidation and a simple forgetting mechanism — for any individual user, this is more than enough, and it costs nothing beyond your existing LLM API. Add a SQLite triple table only when you genuinely need multi-hop relational reasoning.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t overcomplicate it. The architecture above addresses all six fundamental flaws — and you can set it up in an afternoon.&lt;/p&gt;
&lt;p&gt;You can also just copy this article to OpenClaw and let it set everything up for you.&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/why-your-ai-agent-keeps-forgetting-a-practical-memory-architecture-for-individual-users/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>五年了， JSON/V2 还是没有转正</title>
        <link>https://huizhou92.com/p/%E4%BA%94%E5%B9%B4%E4%BA%86-json/v2-%E8%BF%98%E6%98%AF%E6%B2%A1%E6%9C%89%E8%BD%AC%E6%AD%A3/</link>
        <pubDate>Fri, 27 Feb 2026 21:50:53 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/%E4%BA%94%E5%B9%B4%E4%BA%86-json/v2-%E8%BF%98%E6%98%AF%E6%B2%A1%E6%9C%89%E8%BD%AC%E6%AD%A3/</guid>
        <description>&lt;!-- more--&gt;
&lt;h1 id=&#34;五年了-jsonv2-还是没有转正&#34;&gt;五年了， JSON/V2 还是没有转正
&lt;/h1&gt;&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/02/605cdeab11eca0ae50d948387214af5b.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;cover&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;2026 年 2 月 10 日，Go 1.26 重磅发布。&lt;strong&gt;Green Tea&lt;/strong&gt; 垃圾回收器正式成为默认选项。&lt;code&gt;go fix&lt;/code&gt; 工具经历了全面的现代化改造。cgo 调用开销降低了 &lt;strong&gt;30%&lt;/strong&gt;。64 位平台迎来了堆地址随机化（Heap Address Randomization）安全增强。无论从哪个角度看，这都是一个里程碑式的版本。&lt;/p&gt;
&lt;p&gt;然而，许多开发者翘首以盼的功能——&lt;code&gt;encoding/json/v2&lt;/code&gt;——却明显缺席于稳定 API 之中。它依然躲在 &lt;code&gt;GOEXPERIMENT=jsonv2&lt;/code&gt; 的实验性标志背后，尚未就绪。&lt;/p&gt;
&lt;p&gt;我从Golang 1.25 就开始期待&lt;code&gt;JSON/v2&lt;/code&gt; 了。&lt;strong&gt;五年&lt;/strong&gt;的开发，居然还没完成？但如果你深入研究核心追踪议题 &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/76406&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#76406&lt;/a&gt; 和相关提案 &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/71497&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#71497&lt;/a&gt;，画面就变得清晰了：这种延迟不是工程效率的问题。它源于对 &lt;strong&gt;API 完美主义&lt;/strong&gt;的执着追求、一场艰苦卓绝的&lt;strong&gt;向后兼容性&lt;/strong&gt;攻坚战，以及一个几乎让整个项目脱轨的&lt;strong&gt;内存回退&lt;/strong&gt;问题。&lt;/p&gt;
&lt;p&gt;我们逐一拆解。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/02/e17a40bcd89d60d0337cfb1ab11085bd.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20260212150624&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;宏观视角为什么-json-v2-如此重要&#34;&gt;宏观视角：为什么 JSON V2 如此重要
&lt;/h3&gt;&lt;p&gt;当前的 &lt;code&gt;encoding/json&lt;/code&gt;（我们姑且称之为 v1）已经忠实服务 Go 开发者超过十年。但它的设计缺陷一直在累积，就像一个从不重构的创业公司的技术债务。以下是主要问题清单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它会&lt;strong&gt;默默接受无效的 UTF-8&lt;/strong&gt; JSON 字符串&lt;/li&gt;
&lt;li&gt;它&lt;strong&gt;允许重复键名&lt;/strong&gt;而毫无怨言&lt;/li&gt;
&lt;li&gt;自定义 &lt;code&gt;Marshaler&lt;/code&gt; 实现&lt;strong&gt;无法访问配置选项&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;没有办法&lt;strong&gt;拒绝有效 JSON 文档之后的多余数据&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;所谓的&amp;quot;流式&amp;quot;API 基本上是个幌子——底层实际上会缓冲所有内容&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些绝非小问题。在生产环境中，它们是&lt;strong&gt;安全攻击向量&lt;/strong&gt;和&lt;strong&gt;静默数据损坏&lt;/strong&gt;的风险源。符合 RFC 8259 标准？差得远呢。&lt;/p&gt;
&lt;p&gt;由 &lt;strong&gt;Joe Tsai&lt;/strong&gt; 和 &lt;strong&gt;Daniel Martí&lt;/strong&gt; 领导的 JSON v2，是自泛型（Generics）落地以来最具雄心的标准库重写。它旨在修复上述所有问题——同时带来巨大的性能提升。&lt;/p&gt;
&lt;h3 id=&#34;全新架构语法层与语义层的分离&#34;&gt;全新架构：语法层与语义层的分离
&lt;/h3&gt;&lt;p&gt;v2 最精妙的设计决策之一，是将 JSON 处理&lt;strong&gt;严格拆分&lt;/strong&gt;为两层：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;encoding/json/jsontext&lt;/code&gt;&lt;/strong&gt; —— 语法层（Syntactic Layer）。负责纯粹的 JSON 标记化（Tokenizing）、解析和编码。无反射，不涉及 Go 类型。你可以把它理解为一个高性能 JSON 扫描器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;encoding/json/v2&lt;/code&gt;&lt;/strong&gt; —— 语义层（Semantic Layer）。基于 &lt;code&gt;jsontext&lt;/code&gt; 构建，实现 Go 类型与 JSON 数据之间的映射。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种分离的威力在于：如果你只需要验证或转换原始 JSON 而不涉及 Go 结构体，可以直接使用 &lt;code&gt;jsontext&lt;/code&gt;——零反射开销、真正的流式处理、最小化内存分配。&lt;/p&gt;
&lt;p&gt;以下是两个版本的对比：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;encoding/json (v1)&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;encoding/json/v2 (实验性)&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;架构&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;语法与语义耦合，重度依赖反射&lt;/td&gt;
          &lt;td&gt;清晰分离：&lt;code&gt;jsontext&lt;/code&gt;（语法） + &lt;code&gt;v2&lt;/code&gt;（语义）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;流式处理&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;伪流式；底层往往需要全量缓冲&lt;/td&gt;
          &lt;td&gt;真正的流式编码与解码&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;默认安全性&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;接受无效 UTF-8，允许重复键名&lt;/td&gt;
          &lt;td&gt;拒绝无效 UTF-8，拒绝重复键名（符合 RFC 8259）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;基准&lt;/td&gt;
          &lt;td&gt;Unmarshal 最高提升 &lt;strong&gt;10 倍&lt;/strong&gt;；Marshal 提升 &lt;strong&gt;1.6–3.6 倍&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;unsafe 使用&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;无&lt;/td&gt;
          &lt;td&gt;无——在不使用 &lt;code&gt;unsafe&lt;/code&gt; 的前提下达到第三方库级别的性能&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最后一行值得着重强调。像 &lt;strong&gt;Sonic&lt;/strong&gt;（字节跳动）这样的库通过大量使用 &lt;code&gt;unsafe&lt;/code&gt; 来实现极致速度。而 JSON v2 在&lt;strong&gt;不牺牲内存安全&lt;/strong&gt;的前提下达到了同等性能水平。这就是标准库的承诺：你不需要用正确性换取速度。
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/02/1823afa2454141bdb6436bfa9bd64c14.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20260212150646&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;为什么没有随-126-发布四大阻碍&#34;&gt;为什么没有随 1.26 发布：四大阻碍
&lt;/h3&gt;&lt;p&gt;既然 v2 这么好，为什么不在 Go 1.26 中发布？追踪议题 &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/76406&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#76406&lt;/a&gt; 揭示了四个截然不同的战场。&lt;/p&gt;
&lt;h4 id=&#34;1-永久-api-约束&#34;&gt;1. &amp;ldquo;永久 API&amp;rdquo; 约束
&lt;/h4&gt;&lt;p&gt;在 Go 的标准库哲学中，一旦 API 脱离实验阶段进入 &lt;code&gt;encoding/json&lt;/code&gt; 路径，它就必须受到 &lt;strong&gt;Go 1 兼容性承诺&lt;/strong&gt;的保护。永远如此，不可撤回。&lt;/p&gt;
&lt;p&gt;Joe Tsai 对此态度明确：性能问题可以后续通过优化来解决，但 &lt;strong&gt;API 设计缺陷一旦固化，就会成为未来几十年的技术债务&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;目前的审计重点集中在 &lt;code&gt;jsontext&lt;/code&gt; 的公共接口。作为基础层，它的设计需要在高性能与易用性之间取得平衡——尤其是在 Token 处理以及与 &lt;code&gt;io.Reader&lt;/code&gt;/&lt;code&gt;io.Writer&lt;/code&gt; 的最佳交互模式上。&lt;/p&gt;
&lt;p&gt;此外还有关于 &lt;code&gt;time.Duration&lt;/code&gt; 的激烈争论。v1 将持续时间序列化为&lt;strong&gt;纳秒整数&lt;/strong&gt;——虽然广泛使用，但跨语言互操作性极差。v2 倾向于采用 Go 风格的字符串如 &lt;code&gt;&amp;quot;1h2m3s&amp;quot;&lt;/code&gt;，但这引发了关于标准化程度的热烈讨论。双方各执己见，API 签名悬而未决。&lt;/p&gt;
&lt;h4 id=&#34;2-完美兼容-jsonv1&#34;&gt;2. &amp;ldquo;完美兼容 json/v1
&lt;/h4&gt;&lt;p&gt;以下是 Go 团队的雄心壮志：一旦 v2 落地，他们希望&lt;strong&gt;只维护一套代码库&lt;/strong&gt;。现有的 &lt;code&gt;encoding/json&lt;/code&gt; 将变成 v2 引擎的一个薄包装层（Shim）。&lt;/p&gt;
&lt;p&gt;问题在于：v2 引擎必须完美复刻 v1 的&lt;strong&gt;所有行为&lt;/strong&gt;——包括 bug、未文档化的怪癖，以及成千上万生产应用无意中依赖的边缘情况。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;例如，v1 在处理非寻址值（Non-addressable Values）的指针接收者 Marshaler 时存在特定的不一致性。许多现有应用在不知情的情况下已经依赖了这种行为。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;在一个架构完全不同的引擎中复刻这些细微的、难以文档化的行为偏差，是一项极其艰巨的工程挑战。团队目前正在通过大规模测试逐步&amp;quot;烧除&amp;rdquo;（Burning Down）发现的每一个微小行为差异。进展稳步推进，但长尾效应依然明显。&lt;/p&gt;
&lt;h4 id=&#34;3-内存回退问题issue-75026&#34;&gt;3. 内存回退问题：Issue #75026
&lt;/h4&gt;&lt;p&gt;这是最令人警醒的阻碍。在 Go 1.25 和 1.26 的实验周期中，Issue &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/75026&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#75026&lt;/a&gt; 报告了在特定 Map 序列化场景下&lt;strong&gt;灾难性的内存分配回退&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;strong&gt;场景（Map 编码）&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;内存分配 (B/op) — v1 原生&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;内存分配 (B/op) — v2 实验&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;增幅&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;KeyCount: 10, ValLength: 1000&lt;/td&gt;
          &lt;td&gt;832&lt;/td&gt;
          &lt;td&gt;33,139&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;+3,883%&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;没有看错。一个常见的 Map 编码模式，内存分配量增加了 &lt;strong&gt;39 倍&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;性能分析显示，&lt;strong&gt;92.98%&lt;/strong&gt; 的内存分配集中在 &lt;code&gt;bytes.growSlice&lt;/code&gt; 中，这表明新架构在处理复杂对象树或特定 Map 结构时存在严重的缓冲区管理缺陷。虽然总的分配次数（&lt;code&gt;Allocs/op&lt;/code&gt;）实际上有所下降，但单次分配的体积暴增，给 GC 带来了巨大压力。&lt;/p&gt;
&lt;p&gt;如果这种回退作为 v1 用户的默认行为发布，后果将是灾难性的。修复这些极端场景下的分配逻辑是目前&lt;strong&gt;最高优先级&lt;/strong&gt;的工作。&lt;/p&gt;
&lt;h4 id=&#34;4-生态成熟度与联合类型之争&#34;&gt;4. 生态成熟度与联合类型之争
&lt;/h4&gt;&lt;p&gt;JSON v2 项目已经开发了&lt;strong&gt;五年&lt;/strong&gt;。虽然已在许多生产环境中得到验证，但在成为默认标准之前，仍需经历更广泛的生态系统压力测试。Project 50 的追踪显示，44 个子任务中仍有约 &lt;strong&gt;18 个处于开放状态&lt;/strong&gt;或需要进一步审计。&lt;/p&gt;
&lt;p&gt;此外，关于 v2 是否应该支持 JSON 反序列化中的&lt;strong&gt;联合类型&lt;/strong&gt;（Union Types / Sum Types），也引发了设计上的分歧。部分开发者认为这是现代 JSON 处理的标配功能。Go 团队的立场？等待语言层面的&lt;strong&gt;总和类型提案&lt;/strong&gt;（如 &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/57644&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#57644&lt;/a&gt;）成熟后再做集成，而不是在 JSON 包中塞入一个临时的、不兼容的实现。&lt;/p&gt;
&lt;p&gt;这就是典型的 Go 式实用主义：不在库层面解决语言层面的问题。&lt;/p&gt;
&lt;h3 id=&#34;值得等待的核心特性&#34;&gt;值得等待的核心特性
&lt;/h3&gt;&lt;p&gt;尽管发布延迟，v2 的实验性版本已经展示了多项将从根本上改变 Go JSON 处理模式的特性。&lt;/p&gt;
&lt;h4 id=&#34;omitzero--终于有了合理的省略逻辑&#34;&gt;&lt;code&gt;omitzero&lt;/code&gt; —— 终于有了合理的省略逻辑
&lt;/h4&gt;&lt;p&gt;v1 的 &lt;code&gt;omitempty&lt;/code&gt; 让开发者困惑了多年。&lt;code&gt;time.Time{}&lt;/code&gt; 算空吗？&lt;code&gt;false&lt;/code&gt; 算空吗？答案是不一致的，而且常常出人意料。&lt;/p&gt;
&lt;p&gt;v2 引入了 &lt;code&gt;omitzero&lt;/code&gt;，它严格按照 Go 的&lt;strong&gt;零值&lt;/strong&gt;语义进行判断，并支持自定义 &lt;code&gt;IsZero() bool&lt;/code&gt; 接口：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Event&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;      &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;    &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;StartTime&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Time&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;start_time,omitzero&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;EndTime&lt;/span&gt;   &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Time&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;end_time,omitzero&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这对于 &lt;strong&gt;PATCH 风格的 API&lt;/strong&gt; 尤其有用——你只需序列化那些被明确修改过的字段，而不会因为字段恰好持有类型的默认零值而意外忽略它们。&lt;/p&gt;
&lt;h4 id=&#34;inline-和-unknown--灵活的数据建模&#34;&gt;&lt;code&gt;inline&lt;/code&gt; 和 &lt;code&gt;unknown&lt;/code&gt; —— 灵活的数据建模
&lt;/h4&gt;&lt;p&gt;两个新的结构体标签解决了长期存在的痛点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;inline&lt;/code&gt;&lt;/strong&gt;：将嵌套结构体或 Map 的内容&amp;quot;平铺&amp;quot;到父 JSON 对象中——无需匿名嵌入。对于包含动态键值对的 API 来说，这是一个巨大的改进。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;unknown&lt;/code&gt;&lt;/strong&gt;：指定一个字段（通常是 &lt;code&gt;map[string]jsontext.Value&lt;/code&gt;）来捕获结构体中未定义的所有 JSON 成员。彻底告别&amp;quot;二次反序列化&amp;quot;的开销。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Config&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Version&lt;/span&gt;  &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;                          &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;version&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;     &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;                       &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;name&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Extra&lt;/span&gt;    &lt;span class=&#34;kd&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;jsontext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Value&lt;/span&gt;    &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;,unknown&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id=&#34;format--内置编码定制&#34;&gt;&lt;code&gt;format&lt;/code&gt; —— 内置编码定制
&lt;/h4&gt;&lt;p&gt;&lt;code&gt;format&lt;/code&gt; 选项支持按字段定制编码方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为 &lt;code&gt;[]byte&lt;/code&gt; 字段定制 Base64 或 Hex 编码&lt;/li&gt;
&lt;li&gt;为 &lt;code&gt;time.Time&lt;/code&gt; 使用自定义布局字符串&lt;/li&gt;
&lt;li&gt;不再需要为常见格式化需求编写自定义 Marshaler/Unmarshaler 实现&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;性能benchmark-数据说话&#34;&gt;性能：Benchmark 数据说话
&lt;/h3&gt;&lt;p&gt;基于 &lt;code&gt;jsonbench&lt;/code&gt; 评估套件，以下是 v2 与竞品的对比：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;strong&gt;库&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Marshal 速度&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Unmarshal 速度&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;内存安全性&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;JSON v1&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;基准&lt;/td&gt;
          &lt;td&gt;基准&lt;/td&gt;
          &lt;td&gt;高（无 unsafe）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;JSON v2&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;提升 1.6–3.6 倍&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;提升 2.7–10.2 倍&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;高（无 unsafe）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Sonic（字节跳动）&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;与 v2 相当&lt;/td&gt;
          &lt;td&gt;极快（部分使用 unsafe）&lt;/td&gt;
          &lt;td&gt;中（大量使用 unsafe）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;JSON-Iterator&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;慢于 v2&lt;/td&gt;
          &lt;td&gt;慢于 v2&lt;/td&gt;
          &lt;td&gt;中&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关键洞察：v2 通过&lt;strong&gt;迭代式线性解析&lt;/strong&gt;实现性能飞跃，而非 v1 的逐字节虚函数扫描模式。而且它没有使用一个 &lt;code&gt;unsafe.Pointer&lt;/code&gt;。这不仅仅是快——这是&lt;strong&gt;负责任地快&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;前路v2-何时落地&#34;&gt;前路：v2 何时落地？
&lt;/h3&gt;&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/02/44e7b95ea138d8dd9d69c62bc2139da6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20260212150729&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;基于当前的任务处理速度和 &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/76406&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#76406&lt;/a&gt; 上的开发者活跃度，以下是务实的时间线：
&lt;strong&gt;2026 年上半年：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;修复 Issue #75026&lt;/strong&gt; —— 解决 Map 编码的内存回退问题。这是脱离实验阶段的唯一最关键前提。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API 定稿&lt;/strong&gt; —— 完成 &lt;code&gt;jsontext&lt;/code&gt; 中所有公共函数的审计，特别是 &lt;code&gt;Encoder&lt;/code&gt;/&lt;code&gt;Decoder&lt;/code&gt; 在流式场景中的状态机健壮性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;v1 兼容层完善&lt;/strong&gt; —— 确保所有已知的 v1 行为（包括那些&amp;quot;有 bug 的&amp;quot;行为）在 v2 引擎中都有对应的配置选项支持。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Go 1.27（预计 2026 年 8 月）：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这被广泛认为是 JSON v2 移除实验性标签、进入稳定标准库的&lt;strong&gt;最早也是最可能的窗口&lt;/strong&gt;。1.27 开发周期中代码树（Tree）的重新开放将是需要密切关注的关键信号。&lt;/p&gt;
&lt;p&gt;Go 团队还计划在 v2 正式发布时同步推出&lt;strong&gt;现代化迁移工具&lt;/strong&gt;。重新设计的 &lt;code&gt;go fix&lt;/code&gt; 将支持从 v1 到 v2 默认配置的一键迁移——不只是简单的字符串替换，而是感知类型信息的智能转换。例如，它能检测到手动实现的 Base64 转换逻辑，并建议替换为 v2 的 &lt;code&gt;format:base64&lt;/code&gt; 结构体标签。&lt;/p&gt;
&lt;h3 id=&#34;总结&#34;&gt;总结
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;JSON v2 的延迟不是失败——而是纪律。&lt;/strong&gt; Go 团队拒绝发布一个存在设计缺陷的 API，因为在 Go 1 兼容性保证下，这些缺陷将永久存在。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;架构设计是扎实的。&lt;/strong&gt; 通过 &lt;code&gt;jsontext&lt;/code&gt; 和 &lt;code&gt;v2&lt;/code&gt; 实现的语法/语义分离是一种精妙且面向未来的设计。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能已经得到验证。&lt;/strong&gt; Unmarshal 最高提升 10 倍，Marshal 提升 3.6 倍——全程不使用 &lt;code&gt;unsafe&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存回退（#75026）是关键阻碍。&lt;/strong&gt; Map 编码中 39 倍的分配增长必须在 v2 成为默认之前解决。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go 1.27（2026 年 8 月）是目标。&lt;/strong&gt; 社区应据此做好规划。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;对开发者的实用建议：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内部工具&lt;/strong&gt;：放心在非核心系统中尝试 &lt;code&gt;GOEXPERIMENT=jsonv2&lt;/code&gt;。仅 &lt;code&gt;omitzero&lt;/code&gt; 和 &lt;code&gt;unknown&lt;/code&gt; 特性就能显著简化你的代码。提交 Bug 报告——团队需要它们。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能敏感型应用&lt;/strong&gt;：如果 JSON 反序列化是你的 CPU 瓶颈，v2 的实验版本可能已经优于 v1——而且比第三方 &lt;code&gt;unsafe&lt;/code&gt; 库更安全。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公共组件库&lt;/strong&gt;：目前继续使用 &lt;code&gt;encoding/json&lt;/code&gt;（v1）。v2 的 API 仍有可能发生破坏性变更，你的用户不会欣赏这种不稳定性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;JSON v2 将是 Go 语言自泛型以来最重要的库级演进。它不仅让速度更快——更补全了 Go 在现代数据交换标准合规性上长达十年的缺口。随着阻碍一个接一个地被清除，一个更安全、更快速、更灵活的 JSON 处理时代即将随 Go 1.27 到来。&lt;/p&gt;
&lt;p&gt;等待即将结束。而且，值得。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参考资料：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go Issue &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/76406&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#76406&lt;/a&gt; — JSON v2 追踪议题&lt;/li&gt;
&lt;li&gt;Go Proposal &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/71497&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#71497&lt;/a&gt; — encoding/json/v2 提案&lt;/li&gt;
&lt;li&gt;Go Issue &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/75026&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#75026&lt;/a&gt; — jsonv2 实验中的内存分配回退&lt;/li&gt;
&lt;li&gt;Go Issue &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/57644&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#57644&lt;/a&gt; — 总和类型语言提案&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://go.dev/doc/go1.26&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Go 1.26 Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>10 Quiet Side Projects Making Real Money in 2025</title>
        <link>https://huizhou92.com/p/10-quiet-side-projects-making-real-money-in-2025/</link>
        <pubDate>Thu, 25 Dec 2025 09:53:08 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/10-quiet-side-projects-making-real-money-in-2025/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2025/12/e12f373d8b6bc29b61eca52a61feacc1.png" alt="Featured image of post 10 Quiet Side Projects Making Real Money in 2025" /&gt;&lt;p&gt;While everyone on Twitter is chasing the next AI wrapper or prompt marketplace, a post on &lt;strong&gt;Hacker News&lt;/strong&gt; asked a much more grounded question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you’re making more than $500/month from a side project in 2025, what are you building?&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The answers were refreshing.&lt;/p&gt;
&lt;p&gt;No hype.&lt;br&gt;
No “AI will change everything” slogans.&lt;br&gt;
Just &lt;strong&gt;small, specific problems solved well&lt;/strong&gt;—often in niches most of us never think about.&lt;/p&gt;
&lt;p&gt;I picked &lt;strong&gt;10 of the most interesting projects&lt;/strong&gt; from that thread.&lt;br&gt;
If you’re feeling burned out by endless AI discourse, this might help reset your brain.&lt;/p&gt;
&lt;!-- more--&gt;
&lt;h2 id=&#34;1-a-printable-escape-room-you-can-play-at-home&#34;&gt;1. A Printable “Escape Room” You Can Play at Home
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://www.escape-team.com/media/pages/free-escape-room-diy-kit/b9b14b0aec-1714919456/cursor-and-instant-escape-room-kit-pdf-33-33-cmyk-preview.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/12/c6356e4f549a9ccf01fc210f49373dcd.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20251224224319&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Instead of building a physical escape room, this project sells &lt;strong&gt;downloadable PDF escape games&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Users buy a script, print it, cut it out, and use a companion app to play puzzles at home—perfect for parties or family gatherings.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRR:&lt;/strong&gt; ~$1,000&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.escape-team.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.escape-team.com/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
Digital distribution + physical interaction = low cost, high perceived value.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2-managing-xbox-consoles-in-childrens-hospitals&#34;&gt;2. Managing Xbox Consoles in Children’s Hospitals
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://i0.wp.com/childlifemommy.com/wp-content/uploads/2020/01/FullyLoaded1.png?ssl=1&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://coplay.io/content/images/size/w2000/2024/07/CoPlay-Dashboard-1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;A children’s hospital wanted an Xbox in every room—but managing dozens of consoles manually was a nightmare.&lt;br&gt;
This project built a &lt;strong&gt;centralized admin system&lt;/strong&gt; to configure, update, and manage all consoles remotely.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRR:&lt;/strong&gt; ~$6,000&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://coplay.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://coplay.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
A painfully specific enterprise problem, with a buyer who &lt;em&gt;really&lt;/em&gt; needs a solution.&lt;/p&gt;
&lt;h2 id=&#34;3-one-off-online-fax-yes-fax&#34;&gt;3. One-Off Online Fax (Yes, Fax)
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://www.ifaxapp.com/wp-content/uploads/2023/10/send-and-receive-online-faxes.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.ctfassets.net/r6vlh4dr9f5y/7ML5CSf1sJF2wGS6iFPijX/7cde22c140d74f1802df95e29f9be91a/Screenshot_of_sending_fax_in_Dialpad.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Sometimes you just need to send &lt;strong&gt;one fax&lt;/strong&gt;. Not a subscription. Not an account.&lt;/p&gt;
&lt;p&gt;This service does exactly that: upload → pay → send.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MRR:&lt;/strong&gt; ~$500&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://justfaxonline.com/en/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://justfaxonline.com/en/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
It monetizes inconvenience. And faxing is still inconvenient.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;4-duplicate-photo-finder-for-macos&#34;&gt;4. Duplicate Photo Finder for macOS
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/12/475b81c89de6057592ca579d910698a1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20251224224418&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://eclecticlight.co/wp-content/uploads/2015/11/prefsresedit.png?w=640&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;A macOS app that detects &lt;strong&gt;duplicate and visually similar images&lt;/strong&gt;—handy for photographers with massive local libraries.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Paid users:&lt;/strong&gt; 100+&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://maheepk.net/projects/dedupx/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://maheepk.net/projects/dedupx/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
Local storage is exploding. Cleanup tools age &lt;em&gt;very&lt;/em&gt; well.&lt;/p&gt;
&lt;h2 id=&#34;5-gps-based-check-in-for-teams-and-classes&#34;&gt;5. GPS-Based Check-In for Teams and Classes
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://serialio.com/wp-content/uploads/2024/01/GeoFence_Automatic_Check-in_Based_On_Location_iPhone_353x600.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.youhere.org/assets/Options/yh_start.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Teachers, coaches, or team leads set a location and time. Participants must physically be there to check in—verified by GPS.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRR:&lt;/strong&gt; ~€500&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.youhere.org/index.php/start/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.youhere.org/index.php/start/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
It replaces paper sign-ins with proof, not trust.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;6-practicing-cold-calls-by-actually-making-calls&#34;&gt;6. Practicing Cold Calls by Actually Making Calls
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/12/9fb7b51dc6146e05585629c78ac83375.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20251224224614&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cdn.prod.website-files.com/64f44392bca35ec50e5d2397/6884f312150f03a43ec3ffdb_Heading%20%2864%29.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Most sales practice tools simulate calls on screen.&lt;/p&gt;
&lt;p&gt;This one &lt;strong&gt;actually dials your phone&lt;/strong&gt; and connects you to an AI, forcing you to practice under real conditions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRR:&lt;/strong&gt; ~$500&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://coldcallgym.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://coldcallgym.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
Fear reduction through exposure—not theory.&lt;/p&gt;
&lt;h2 id=&#34;7-paying-your-kids-to-save-on-taxes&#34;&gt;7. Paying Your Kids to Save on Taxes
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://www.livablesolutions.com/wp-content/uploads/2023/01/Small-Business-File-System-Photo-1-9-2.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Parents log their kids’ work (filing, photos, admin tasks), treat it as a legitimate business expense, and route income into tax-advantaged accounts like a Roth IRA.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRR:&lt;/strong&gt; ~$500&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://trypixie.com/#how-it-works&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://trypixie.com/#how-it-works&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
It turns tax optimization into a family financial strategy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;8-turn-photos-into-printable-coloring-pages&#34;&gt;8. Turn Photos Into Printable Coloring Pages
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://colorifyai.art/wp-content/uploads/sites/8/2025/06/coloting-page-for-kids.webp&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.etsystatic.com/23190174/r/il/657ec0/4703647124/il_570xN.4703647124_a5yg.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Upload a photo of your pet, child, or vacation—get a clean black-and-white coloring page ready to print.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://dreamandcolor.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://dreamandcolor.com/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
Personalization beats stock content every time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;9-tracking-hard-drive-prices-on-ebay&#34;&gt;9. Tracking Hard Drive Prices on eBay
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://i.ebayimg.com/images/g/TjoAAOSwId1nx6x5/s-l1200.webp&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://monday.com/blog/wp-content/uploads/2022/03/Untitled-233.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;This project scrapes eBay listings for disks and memory cards, parsing titles with &lt;strong&gt;200+ regex rules&lt;/strong&gt;, then monetizes via affiliate links.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MRR:&lt;/strong&gt; $400–$600&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Websites:&lt;/strong&gt;&lt;br&gt;
&lt;a class=&#34;link&#34; href=&#34;https://unli.xyz/digitalfilmstock/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://unli.xyz/digitalfilmstock/&lt;/a&gt;&lt;br&gt;
&lt;a class=&#34;link&#34; href=&#34;https://unli.xyz/diskprices/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://unli.xyz/diskprices/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
Data cleaning is painful. If you do it once, others will pay.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;10-a-daily-logic-puzzle-no-ads&#34;&gt;10. A Daily Logic Puzzle (No Ads)
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://m.media-amazon.com/images/I/81TGAvXf-HL._AC_UF894%2C1000_QL80_.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Image&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Each day has a new puzzle: easy on Monday, brutal on Sunday. Revenue comes from &lt;strong&gt;selling puzzle packs&lt;/strong&gt;, not ads.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://cluesbysam.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://cluesbysam.com/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;
Habit + ownership beats ad-driven distraction.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-real-pattern-here&#34;&gt;The Real Pattern Here
&lt;/h2&gt;&lt;p&gt;None of these projects are “sexy”.&lt;br&gt;
But they all share something powerful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;very specific audience&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;clear, painful problem&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Simple pricing&lt;/li&gt;
&lt;li&gt;No dependence on hype cycles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a world obsessed with AI, these projects quietly remind us:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Making money is often about reducing friction, not inventing the future.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If you want to build something sustainable, maybe don’t ask&lt;br&gt;
&lt;em&gt;“What’s the next big thing?”&lt;/em&gt;&lt;br&gt;
Ask instead:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“What’s an annoying problem people already tolerate?”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source discussion:&lt;/em&gt;&lt;br&gt;
&lt;a class=&#34;link&#34; href=&#34;https://news.ycombinator.com/item?id=46307973&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://news.ycombinator.com/item?id=46307973&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Why the Flask Creator Ditched Python for Go in His AI Startup</title>
        <link>https://huizhou92.com/p/why-the-flask-creator-ditched-python-for-go-in-his-ai-startup/</link>
        <pubDate>Fri, 24 Oct 2025 00:00:00 +0000</pubDate>
        
        <guid>https://huizhou92.com/p/why-the-flask-creator-ditched-python-for-go-in-his-ai-startup/</guid>
        <description>&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/40a7d4d3d475ac4b8a9fa89c620bdfff.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;cover-en&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;introduction-a-python-icons-betrayal&#34;&gt;Introduction: A Python Icon&amp;rsquo;s &amp;ldquo;Betrayal&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;Armin Ronacher, creator of Flask—one of Python&amp;rsquo;s most beloved web frameworks—is a household name in the Python community. For years, he&amp;rsquo;s been a standout contributor to Python&amp;rsquo;s ecosystem, with his career deeply intertwined with the language. Yet when launching his AI startup, he made a surprising decision: the company&amp;rsquo;s core backend services wouldn&amp;rsquo;t use Python, the reigning champion of AI, but Go instead.&lt;/p&gt;
&lt;p&gt;This choice raises a fundamental question: Why would a top-tier Python expert &amp;ldquo;betray&amp;rdquo; his preferred language in an AI project where Python should dominate? This isn&amp;rsquo;t just a technical decision—it&amp;rsquo;s the result of an internal struggle between two identities: the &amp;ldquo;Swiss watchmaker&amp;rdquo; who pursues code perfection and the pragmatic founder focused on shipping products. This article explores how Armin Ronacher balances these personas and how AI-era tech companies should rethink their technology stack decisions.&lt;/p&gt;
&lt;h3 id=&#34;1-reconsidering-python-ais-king-with-hidden-concerns&#34;&gt;1. Reconsidering Python: AI&amp;rsquo;s King with Hidden Concerns
&lt;/h3&gt;&lt;p&gt;Python&amp;rsquo;s dominance in today&amp;rsquo;s tech landscape seems unshakeable, especially in AI. However, every technology choice involves tradeoffs, and even Python isn&amp;rsquo;t the best answer in every scenario.&lt;/p&gt;
&lt;h4 id=&#34;pythons-absolute-strengths&#34;&gt;Python&amp;rsquo;s Absolute Strengths
&lt;/h4&gt;&lt;p&gt;First, we must acknowledge that no company can completely avoid Python. Armin Ronacher explicitly states that whether you like it or not, Python will be part of your stack. Its position in these domains is irreplaceable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Machine Learning (ML)&lt;/strong&gt;: Core for AI inference and data processing tasks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Processing&lt;/strong&gt;: Unmatched data science ecosystem.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Infrastructure Management&lt;/strong&gt;: For example, Armin uses Pulumi with Python to build his company&amp;rsquo;s infrastructure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the &amp;ldquo;glue&amp;rdquo; in the ecosystem and the data science engine, Python&amp;rsquo;s value is undeniable. Even for network-intensive tasks like AI inference, performance bottlenecks typically lie in networking rather than the language itself, making Python an excellent choice.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/2cc384ce04fdb5b0a68c827009ae1601.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Python Ecosystem&#34;
	
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;the-tradeoff-for-core-services&#34;&gt;The Tradeoff for Core Services
&lt;/h4&gt;&lt;p&gt;Despite Python&amp;rsquo;s ubiquity, Armin believes it shouldn&amp;rsquo;t be used to build his new company&amp;rsquo;s &lt;em&gt;primary services&lt;/em&gt;. This consideration isn&amp;rsquo;t rooted in performance bias but stems from deeper insights into language complexity and ecosystem strengths.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Growing Complexity&lt;/strong&gt;: Armin observes that Python itself is becoming increasingly complex. In contrast, Go has maintained relative simplicity since inception. This matters because for an engineering team that needs rapid iteration and collaboration, Go might be &amp;ldquo;an easier language to write.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ecosystem Specialization&lt;/strong&gt;: Technology choices aren&amp;rsquo;t just about what a language &lt;em&gt;can&lt;/em&gt; do, but what its ecosystem is &lt;em&gt;good at&lt;/em&gt;. Armin explicitly states he&amp;rsquo;s abandoning Python not for performance reasons, but because of &amp;ldquo;what the ecosystem is good at.&amp;rdquo; While Python is fully capable of handling email parsing (one of Armin&amp;rsquo;s company&amp;rsquo;s core businesses), this isn&amp;rsquo;t where its ecosystem naturally excels. Compared to Go, it&amp;rsquo;s not the &amp;ldquo;chosen one&amp;rdquo; for building this type of scaled core service.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These nuanced considerations led Armin to look toward another language, naturally bringing us to the discussion of Go.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;2-embracing-go-the-pragmatists-victory&#34;&gt;2. Embracing Go: The Pragmatist&amp;rsquo;s Victory
&lt;/h3&gt;&lt;p&gt;If choosing technology is an art, then for startups, the core of this art is pragmatism. Armin Ronacher&amp;rsquo;s choice of Go perfectly embodies this philosophy. Go isn&amp;rsquo;t the most &amp;ldquo;sexy&amp;rdquo; or feature-rich language, but in specific scenarios, it&amp;rsquo;s the most pragmatic, most suitable tool.&lt;/p&gt;
&lt;p&gt;Here are Go&amp;rsquo;s core advantages that made it stand out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Built for Web Services&lt;/strong&gt;: Go is clearly positioned as &amp;ldquo;an excellent language for building web services&amp;rdquo; with intense focus (&amp;ldquo;really kind of only web services&amp;rdquo;), plus some CLI tool building capability. This focus makes it exceptionally performant in its target domain.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extreme Pragmatism&lt;/strong&gt;: This is Armin&amp;rsquo;s primary reason for choosing Go. He emphasizes Go&amp;rsquo;s &amp;ldquo;very pragmatic language features,&amp;rdquo; a crucial quality for startups that need to focus on products, ship quickly, and reduce unnecessary technical friction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ecosystem Stability&lt;/strong&gt;: For long-term projects, technology longevity is a key consideration. Armin believes Go can be &amp;ldquo;expected to stick around.&amp;rdquo; Even if Google stopped maintaining it someday, the massive community and industry users have enough strength and willingness to sustain its vitality, providing solid guarantees for projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Pragmatic Landing Point After Avoiding Python Scaling Concerns and Rust Development Friction&lt;/strong&gt;: After weighing options, Go became an ideal pragmatic choice. It avoids both Python&amp;rsquo;s ecosystem fit issues when building certain types of core services and Rust&amp;rsquo;s steep learning curve and high development &amp;ldquo;friction,&amp;rdquo; making it the best choice for a &amp;ldquo;founder.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/54a81456afadaf6b501ea505e1ec9d55.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Go Pragmatism&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;To understand this decision more clearly, we need a horizontal comparison of these languages to see their roles in different scenarios.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;3-horizontal-comparison-go-vs-rust-vs-python-use-cases&#34;&gt;3. Horizontal Comparison: Go vs. Rust vs. Python Use Cases
&lt;/h3&gt;&lt;p&gt;Armin Ronacher houses &amp;ldquo;two programmers&amp;rdquo; within himself: one is the &amp;ldquo;Swiss watchmaker&amp;rdquo; pursuing code perfection, usually thriving in the open-source world; the other is the company founder focused on product delivery, making all decisions with pragmatism first. From the latter&amp;rsquo;s perspective, he made a clear distinction between Go, Rust, and Python&amp;rsquo;s applicable scenarios.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/84880d7026e4419aba54ae9c59db2cf7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Language Comparison&#34;
	
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;python-the-ubiquitous-glue-and-data-science-engine&#34;&gt;Python: The Ubiquitous &amp;ldquo;Glue&amp;rdquo; and Data Science Engine
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: Python is the universal &amp;ldquo;glue&amp;rdquo; in the ecosystem and the undisputed default choice for data processing and machine learning.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advantages&lt;/strong&gt;: Most powerful library ecosystem, supports rapid prototyping and iteration. In network-intensive tasks like AI inference, the language&amp;rsquo;s performance bottleneck isn&amp;rsquo;t prominent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tradeoffs&lt;/strong&gt;: The language&amp;rsquo;s inherent complexity is increasing, and for certain types of core services, it may not be the most natural, direct choice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;rust-the-swiss-watch-for-rust-shaped-problems&#34;&gt;Rust: The &amp;ldquo;Swiss Watch&amp;rdquo; for &amp;ldquo;Rust-Shaped Problems&amp;rdquo;
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: Rust is the expert-level language for solving specific &amp;ldquo;Rust-shaped problems,&amp;rdquo; such as handling binary data, building databases, load balancers, or high-performance Python extension modules.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advantages&lt;/strong&gt;: Memory safety, predictable performance without garbage collection (GC), excellent as Python extensions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tradeoffs (for Startups)&lt;/strong&gt;: Extremely high development &amp;ldquo;friction.&amp;rdquo; This includes &amp;ldquo;incredibly slow&amp;rdquo; compilation speeds and the steep learning curve of ownership and borrow checking. This makes it highly unsuitable for environments requiring rapid iteration and flexible adjustments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;go-the-pragmatic-focused-web-service-builder&#34;&gt;Go: The Pragmatic, Focused Web Service Builder
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: Go is the pragmatic choice for building web services and CLI tools, a focused service-building specialist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advantages&lt;/strong&gt;: Simple language, easy for teams to learn and master, stable ecosystem, excellent performance in high-concurrency service scenarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tradeoffs&lt;/strong&gt;: Its applicable domain is relatively focused, lacking Python&amp;rsquo;s &amp;ldquo;jack-of-all-trades&amp;rdquo; versatility.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notably, Armin also explicitly ruled out using TypeScript/JavaScript for core backend services. Despite its increasingly mature language environment, he&amp;rsquo;s reserved about the &lt;code&gt;npm&lt;/code&gt; ecosystem, stating bluntly: &amp;ldquo;I feel like in the JavaScript ecosystem, I can barely build efficiently without introducing 500+ dependencies, which makes me uncomfortable.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Traditional language selection considerations are now very clear. However, AI&amp;rsquo;s rise introduces a new, potentially disruptive decision dimension.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;4-the-new-deciding-factor-ai-agent-code-generation-quality&#34;&gt;4. The New Deciding Factor: AI Agent Code Generation Quality
&lt;/h3&gt;&lt;p&gt;The rise of AI programming assistants is fundamentally changing software development paradigms, and the underlying logic of technology selection is shifting accordingly. Armin Ronacher, as an entrepreneur heavily relying on AI-assisted coding (which he calls his &amp;ldquo;army of interns&amp;rdquo;), discovered a striking fact: &lt;strong&gt;AI Agent code generation quality has become an unavoidable consideration.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;He reached a clear conclusion from practice:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I did actual testing&amp;hellip; I found that AI Agents perform much better on Go than on Python.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Why? The reason lies in the language&amp;rsquo;s design philosophy. Armin explains: &amp;ldquo;&lt;strong&gt;Because the abstractions are very thin, it (AI) can understand the code better.&lt;/strong&gt;&amp;rdquo; Go&amp;rsquo;s simplicity and directness make its structure easier for large language models to understand and generate, resulting in more reliable, more correct code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/dd66f7b1a8e1ae2f60f892111fad65fd.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;AI Code Generation Quality&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;This discovery is significant for a team heavily dependent on AI. When your &amp;ldquo;army of interns&amp;rdquo; is more efficient and makes fewer errors with a particular language, choosing that language isn&amp;rsquo;t just a technical preference—it directly impacts the entire team&amp;rsquo;s productivity.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;conclusion-no-best-language-only-the-right-choice&#34;&gt;Conclusion: No Best Language, Only the Right Choice
&lt;/h3&gt;&lt;p&gt;Armin Ronacher&amp;rsquo;s abandonment of Python for Go isn&amp;rsquo;t a rejection of Python, but rather a highly pragmatic tradeoff made in a new technical paradigm, based on a specific startup context (AI company, rapid iteration, small team collaboration).&lt;/p&gt;
&lt;p&gt;His decision logic can be summarized as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pragmatism Above All&lt;/strong&gt;: For startups, product success matters far more than &amp;ldquo;meticulously crafted&amp;rdquo; code. Choosing tools with less friction and more focus on solving core problems is wise.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Art of Tradeoffs&lt;/strong&gt;: Among language simplicity (easy for teams to master), ecosystem maturity, performance, and development efficiency, Go provides an excellent balance point.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embracing New Paradigms&lt;/strong&gt;: Incorporating AI code generation quality into core technology selection considerations reflects adaptation to changing times. A language&amp;rsquo;s friendliness to AI is becoming a new, critical productivity metric.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ultimately, Armin&amp;rsquo;s story brings a profound insight to all technical decision-makers: we must continuously reevaluate our toolbox and courageously make the most suitable, most pragmatic choices based on current project needs and emerging technology waves.&lt;/p&gt;
&lt;h3 id=&#34;article-summary&#34;&gt;Article Summary
&lt;/h3&gt;&lt;p&gt;Flask creator Armin Ronacher chose Go over Python for core services in his new AI startup. This decision doesn&amp;rsquo;t negate Python but stems from a startup&amp;rsquo;s extreme pursuit of pragmatism, simplicity, and team efficiency. He views Go as the pragmatic choice after avoiding Rust&amp;rsquo;s development friction and Python&amp;rsquo;s ecosystem specialization limitations. More critically, he discovered that AI Agents generate far better Go code than Python—a decisive new factor in the AI-assisted programming era.&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/why-the-flask-creator-ditched-python-for-go-in-his-ai-startup/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Playing Snake in Your Browser&#39;s Address Bar: When the Internet Was Still Fun</title>
        <link>https://huizhou92.com/p/playing-snake-in-your-browsers-address-bar-when-the-internet-was-still-fun/</link>
        <pubDate>Thu, 02 Oct 2025 17:21:30 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/playing-snake-in-your-browsers-address-bar-when-the-internet-was-still-fun/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2025/10/c61a3f89ebd38ec64ecc25f6232db78b.png" alt="Featured image of post Playing Snake in Your Browser&#39;s Address Bar: When the Internet Was Still Fun" /&gt;&lt;p&gt;Open Chrome, type &lt;code&gt;https://demian.ferrei.ro/snake#&lt;/code&gt; into the address bar, and you&amp;rsquo;ll suddenly see a string of strange characters.&lt;br&gt;
Yes, you read that right. Keep your eyes on the address bar and control the direction with the arrow keys or WASD.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll see a little snake made of odd-looking symbols (░░░░░░░⠠⠤⠄⡀░░) crawling around inside the address bar, eating food, and growing longer. The entire game plays out inside that thin text field you usually only use to type URLs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/5ea3b9a9457de17c348e4a8631605888.gif&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Area&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That&amp;rsquo;s right — this is a fully functional Snake game running entirely inside the browser&amp;rsquo;s URL bar.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Last week, this decade-old project suddenly blew up on Hacker News, racking up 840 upvotes and hundreds of comments. The first reaction from many people was: &lt;em&gt;&amp;ldquo;This is insane. How did you even come up with this?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But the story behind this game is even crazier — and it reveals something important about what the modern internet has lost.&lt;/p&gt;
&lt;h2 id=&#34;a-random-curiosity-sparks-a-technical-adventure&#34;&gt;A Random Curiosity Sparks a Technical Adventure
&lt;/h2&gt;&lt;p&gt;The creator, Francisco Uzo, recalls the project&amp;rsquo;s origins: &lt;em&gt;&amp;ldquo;I just wanted to understand how the Braille system worked.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the essence of hacker culture — &lt;strong&gt;not solving a problem, but chasing pure curiosity.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As he dug into Braille, he noticed something fascinating: each Braille symbol is a 2x4 dot matrix, eight positions in total, each either &amp;ldquo;raised&amp;rdquo; or &amp;ldquo;flat.&amp;rdquo; That gives 2^8 = 256 possible combinations. And Unicode happens to support all 256 Braille characters.&lt;/p&gt;
&lt;p&gt;One night around 3 a.m., it hit him: &lt;strong&gt;&amp;ldquo;Wait, this is basically an 8-bit pixel character set!&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That spark — when two unrelated ideas suddenly connect — is exactly the kind of joy hackers live for.&lt;/p&gt;
&lt;p&gt;And then came the classic hacker instinct: &lt;strong&gt;don&amp;rsquo;t ask whether it&amp;rsquo;s useful — just build it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The implementation was full of clever hacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mapping the game world onto Braille character grids, each character acting as a 2x4 pixel block&lt;/li&gt;
&lt;li&gt;Using solid dots (⣿) for the snake&amp;rsquo;s body and blank Braille (⠀) for empty space&lt;/li&gt;
&lt;li&gt;Leveraging JavaScript&amp;rsquo;s &lt;code&gt;history.replaceState()&lt;/code&gt; API to update the URL in real time without polluting the history&lt;/li&gt;
&lt;li&gt;Refreshing the entire frame each tick so the game animates smoothly inside the address bar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Francisco&amp;rsquo;s openness was just as &amp;ldquo;hacker-ish&amp;rdquo;: &lt;em&gt;&amp;ldquo;The source code isn&amp;rsquo;t minified or obfuscated. Just hit Ctrl+U and you&amp;rsquo;ll see everything.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The whole thing was only a few hundred lines of JavaScript — concise, readable, and elegant. &lt;strong&gt;In the hacker mindset, code isn&amp;rsquo;t just for execution — it should also be legible, learnable, and inspiring.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;wait-why-does-my-game-look-broken&#34;&gt;Wait… Why Does My Game Look Broken?
&lt;/h2&gt;&lt;p&gt;If you try the game today, you might just see a mess of &lt;code&gt;%20&lt;/code&gt;, backslashes, and gibberish. The snake barely moves — or sometimes the game doesn&amp;rsquo;t run at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It&amp;rsquo;s not your fault. It&amp;rsquo;s not even the code&amp;rsquo;s fault. The browser has changed.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Francisco admitted, &lt;em&gt;&amp;ldquo;This project was written for browsers ten years ago. Since then, browsers have made certain &amp;lsquo;security improvements&amp;rsquo; that severely limit what&amp;rsquo;s possible in the URL bar.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The most critical change? &lt;strong&gt;Modern browsers now forcefully escape all spaces in URLs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the game&amp;rsquo;s design, the blank Braille character (⠀) represented empty space. However, browsers now escape those characters as &lt;code&gt;%20&lt;/code&gt; or something else, which ruins the visual output.&lt;/p&gt;
&lt;p&gt;Francisco even built a fallback system that measured text widths via Canvas and replaced escaped characters on the fly — but it only worked partially.&lt;/p&gt;
&lt;p&gt;He appealed to browser bug trackers. Developers sympathized but ultimately concluded: &lt;strong&gt;&amp;ldquo;As always, security outweighs fun.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a result, users&amp;rsquo; experiences varied wildly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some people on Chrome scored over 2,000 points.&lt;/li&gt;
&lt;li&gt;Others saw a screen full of garbage in Firefox.&lt;/li&gt;
&lt;li&gt;On iOS Safari, the game sometimes didn&amp;rsquo;t even render&lt;/li&gt;
&lt;li&gt;Some users found their browsing history polluted with every single game frame.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The same code, drastically different behavior across browsers. That&amp;rsquo;s just the reality of modern web development.&lt;/p&gt;
&lt;h2 id=&#34;the-golden-age-of-weird-browser-games&#34;&gt;The Golden Age of &amp;ldquo;Weird Browser Games&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Snake in the address bar wasn&amp;rsquo;t the only project of its kind. The Hacker News discussion turned into a nostalgia trip, with people recalling a whole wave of unconventional browser experiments.&lt;/p&gt;
&lt;h3 id=&#34;2048-in-the-url&#34;&gt;&lt;strong&gt;2048 In the URL&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Someone linked to &lt;a class=&#34;link&#34; href=&#34;https://aquova.net/games/2048/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://aquova.net/games/2048/&lt;/a&gt; — a port of the once-famous puzzle game, implemented entirely inside the address bar using the same Braille and URL-refresh trick.&lt;/p&gt;
&lt;h3 id=&#34;snake-in-the-browser-tab-title&#34;&gt;&lt;strong&gt;Snake In the Browser Tab Title&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Francisco mentioned that someone on Reddit made a version that runs inside the tab&amp;rsquo;s title instead. It was basically a compromise — no longer in the address bar, but safe from URL escaping.&lt;/p&gt;
&lt;h3 id=&#34;tinyjs-snake&#34;&gt;&lt;strong&gt;TinyJS Snake&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;In 2023, another developer built &lt;a class=&#34;link&#34; href=&#34;https://danielgjackson.github.io/tinyjs#snake&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a similar Snake clone&lt;/a&gt; using a different technique. At the time, browser restrictions weren&amp;rsquo;t as strict.&lt;/p&gt;
&lt;h3 id=&#34;3d-worlds-in-the-url&#34;&gt;&lt;strong&gt;3D Worlds in the URL&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Another project took things further: &lt;a class=&#34;link&#34; href=&#34;https://matthew.rayfield.world/articles/games-and-graphics-in-popup-url-bars/#:~:text=The%203D%20Room&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;an interactive 3D environment rendered through unconventional browser features&lt;/a&gt;.&lt;br&gt;
One commenter joked: &lt;em&gt;&amp;ldquo;It&amp;rsquo;s not Doom, but you can walk around in 3D.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What do all these have in common? &lt;strong&gt;They were built for fun, out of curiosity, with no concern for practicality.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No commercial value. No business use case. Not even &amp;ldquo;best practices.&amp;rdquo;&lt;br&gt;
But they embodied the spirit of the early web: &lt;strong&gt;a playground where people could experiment, push boundaries, and have fun.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;why-are-projects-like-this-so-hard-now&#34;&gt;Why Are Projects Like This So Hard Now?
&lt;/h2&gt;&lt;p&gt;It&amp;rsquo;s not just the space escaping problem. Over the past decade, browsers have introduced countless so-called &lt;strong&gt;security improvements&lt;/strong&gt;:&lt;/p&gt;
&lt;h3 id=&#34;history-api-limits&#34;&gt;&lt;strong&gt;History API Limits&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Francisco originally used &lt;code&gt;history.replaceState()&lt;/code&gt; to update the URL without spamming history entries. Modern browsers now throttle calls to this API, forcing fallback to &lt;code&gt;location.hash&lt;/code&gt; — which clutters your browsing history with every frame of gameplay.&lt;/p&gt;
&lt;h3 id=&#34;url-length-restrictions&#34;&gt;&lt;strong&gt;URL Length Restrictions&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Different browsers cap URL length anywhere from 2,000 to tens of thousands of characters. Encoding game state into URLs quickly hits those ceilings.&lt;/p&gt;
&lt;h3 id=&#34;character-set-restrictions&#34;&gt;&lt;strong&gt;Character Set Restrictions&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;More and more Unicode characters are marked as &amp;ldquo;unsafe&amp;rdquo; for URLs. Browsers escape or block them, killing Unicode art projects outright.&lt;/p&gt;
&lt;h3 id=&#34;mobile-compatibility&#34;&gt;&lt;strong&gt;Mobile Compatibility&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Many mobile browsers hide the URL bar entirely while scrolling — making address-bar games literally unplayable.&lt;/p&gt;
&lt;p&gt;Francisco summed it up: &lt;em&gt;&amp;ldquo;Every browser change since then has made projects like this harder. I got some sympathy in bug trackers, but security always wins.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;when-security-kills-the-fun&#34;&gt;When Security Kills the Fun
&lt;/h2&gt;&lt;p&gt;Here&amp;rsquo;s the fundamental tension:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nobody disputes the importance of browser security.&lt;/strong&gt;&lt;br&gt;
URL injection attacks, XSS vulnerabilities, phishing — these are real threats affecting billions of users. Browser developers have a duty to protect people.&lt;/p&gt;
&lt;p&gt;But every &amp;ldquo;security improvement&amp;rdquo; quietly closes off a door to creativity.&lt;/p&gt;
&lt;p&gt;Francisco&amp;rsquo;s code worked flawlessly a decade ago. Today, it&amp;rsquo;s broken not because it was bad, but because the browser &amp;ldquo;evolved.&amp;rdquo; That evolution made the web safer — but also more controlled, more uniform, and frankly… more boring.&lt;/p&gt;
&lt;h3 id=&#34;it&#34;&gt;&lt;strong&gt;It&amp;rsquo;s Not Just About Games&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;One Hacker News commenter sneered: &lt;em&gt;&amp;ldquo;Why don&amp;rsquo;t people build something useful instead of abusing the internet?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The community overwhelmingly pushed back:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;The learning value from projects like this is massive.&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Creative play matters for skill development too.&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;This is exactly why I come to HN — 100% hacker spirit.&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;ChatGPT couldn&amp;rsquo;t have come up with this. I love the creativity.&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best response was simple:&lt;br&gt;
&lt;em&gt;&amp;ldquo;To most people, this is nothing. To me, it&amp;rsquo;s insane. How did you even think of this?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That&amp;rsquo;s the point.&lt;/strong&gt; The value of projects like this isn&amp;rsquo;t in utility, but in pure human creativity — driven by curiosity, joy, and the urge to ask &lt;em&gt;&amp;ldquo;why not?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And every time we &amp;ldquo;tighten security,&amp;rdquo; we don&amp;rsquo;t just close loopholes. We also close off avenues for wonder.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;trade-offs-are-necessary-but-we-should-acknowledge-the-cost&#34;&gt;&lt;strong&gt;Trade-offs Are Necessary, But We Should Acknowledge the Cost&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;This isn&amp;rsquo;t about blaming browser developers. They face incredibly difficult trade-offs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow flexible URL encoding vs. prevent injection attacks&lt;/li&gt;
&lt;li&gt;Support high-frequency API calls vs. avoid performance issues&lt;/li&gt;
&lt;li&gt;Display arbitrary Unicode characters vs. prevent phishing scams&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;There&amp;rsquo;s no perfect answer.&lt;/strong&gt; Every decision has its cost.&lt;/p&gt;
&lt;p&gt;But we should at least be aware of and discuss these costs. When we say &amp;ldquo;security first,&amp;rdquo; we should ask: &amp;ldquo;What are we losing because of this?&amp;rdquo; When we say &amp;ldquo;user experience optimization,&amp;rdquo; we should ask: &amp;ldquo;Whose experience are we optimizing for?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Francisco&amp;rsquo;s response from browser bug trackers was typical: &amp;ldquo;I understand your frustration, but security must come first.&amp;rdquo; This answer is technically unassailable, but it also represents a broader trend: &lt;strong&gt;on the modern internet, control and security are systematically overwhelming creativity and fun.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;in-the-age-of-ai-human-creativity-matters-more&#34;&gt;In the Age of AI, Human Creativity Matters More
&lt;/h2&gt;&lt;p&gt;When asked about AI, Francisco said something striking:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;This game has been online for ten years. It&amp;rsquo;s probably in AI training data. A robot might be able to replicate it, but it could never enjoy it. (At least not yet.)&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That gets to the heart of our cultural anxiety today. In an era where ChatGPT can generate code in seconds and Copilot can autocomplete whole functions — what projects are still worth building by hand?&lt;/p&gt;
&lt;p&gt;The answer might just lie in this Snake game.&lt;/p&gt;
&lt;p&gt;AI can parse Braille characters, understand Unicode, and spit out JavaScript. But AI can&amp;rsquo;t feel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 3 a.m. epiphany that &amp;ldquo;Braille could be pixels&amp;rdquo;&lt;/li&gt;
&lt;li&gt;the giddy surprise of watching a snake slither inside a URL bar for the first time&lt;/li&gt;
&lt;li&gt;The stubborn joy of debugging escape sequences for hours&lt;/li&gt;
&lt;li&gt;The quiet pride of seeing strangers enjoy your work a decade later&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are &lt;strong&gt;uniquely human creative experiences.&lt;/strong&gt;&lt;br&gt;
In a world where AI can replicate almost all code, that human spark is more precious than ever.&lt;/p&gt;
&lt;p&gt;Francisco&amp;rsquo;s project wasn&amp;rsquo;t created to solve a problem — it was created for exploration and fun. That motivation, that process, that pure creative joy — &lt;strong&gt;that&amp;rsquo;s something AI can never truly possess.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;we-need-more-projects-like-this&#34;&gt;We Need More Projects Like This
&lt;/h2&gt;&lt;p&gt;Snake in the URL bar went viral, not because it&amp;rsquo;s useful or profitable, but because it reminded us of something essential:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The internet shouldn&amp;rsquo;t just be efficient, safe, and standardized. It should also be surprising, playful, and experimental.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When Francisco asked himself, &amp;ldquo;How does Braille work?&amp;rdquo; ten years ago, he wasn&amp;rsquo;t solving a business problem or optimizing UX. He was just curious. That curiosity created something that made thousands of strangers smile.&lt;/p&gt;
&lt;p&gt;In today&amp;rsquo;s increasingly homogeneous, &amp;ldquo;safe,&amp;rdquo; and algorithmically optimized internet, we need more of this. Not because it&amp;rsquo;s useful, but because it reminds us:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Technology isn&amp;rsquo;t only about efficiency and safety — it should also be about wonder and joy.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, how many points can &lt;em&gt;you&lt;/em&gt; score? Does your browser even support it?&lt;/p&gt;
&lt;p&gt;Or maybe the real question is: &lt;strong&gt;what&amp;rsquo;s the last &amp;ldquo;useless but fun&amp;rdquo; project you built?&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/playing-snake-in-your-browsers-address-bar-when-the-internet-was-still-fun/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Playing Snake in Your Browser’s Address Bar: When the Internet Was Still Fun</title>
        <link>https://huizhou92.com/p/playing-snake-in-your-browsers-address-bar-when-the-internet-was-still-fun/</link>
        <pubDate>Thu, 02 Oct 2025 17:21:30 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/playing-snake-in-your-browsers-address-bar-when-the-internet-was-still-fun/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2025/10/c61a3f89ebd38ec64ecc25f6232db78b.png" alt="Featured image of post Playing Snake in Your Browser’s Address Bar: When the Internet Was Still Fun" /&gt;&lt;p&gt;Open Chrome, type &lt;code&gt;https://demian.ferrei.ro/snake#&lt;/code&gt; into the address bar, and you’ll suddenly see a string of strange characters.&lt;br&gt;
Yes, you read that right. Keep your eyes on the address bar and control the direction with the arrow keys or WASD.&lt;/p&gt;
&lt;p&gt;You’ll see a little snake made of odd-looking symbols (░░░░░░░⠠⠤⠄⡀░░) crawling around inside the address bar, eating food, and growing longer. The entire game plays out inside that thin text field you usually only use to type URLs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/10/5ea3b9a9457de17c348e4a8631605888.gif&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Area&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That’s right — this is a fully functional Snake game running entirely inside the browser’s URL bar.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Last week, this decade-old project suddenly blew up on Hacker News, racking up 840 upvotes and hundreds of comments. The first reaction from many people was: &lt;em&gt;“This is insane. How did you even come up with this?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But the story behind this game is even crazier — and it reveals something important about what the modern internet has lost.&lt;/p&gt;
&lt;h2 id=&#34;a-random-curiosity-sparks-a-technical-adventure&#34;&gt;A Random Curiosity Sparks a Technical Adventure
&lt;/h2&gt;&lt;p&gt;The creator, Francisco Uzo, recalls the project’s origins: &lt;em&gt;“I just wanted to understand how the Braille system worked.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That’s the essence of hacker culture — &lt;strong&gt;not solving a problem, but chasing pure curiosity.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As he dug into Braille, he noticed something fascinating: each Braille symbol is a 2x4 dot matrix, eight positions in total, each either “raised” or “flat.” That gives 2^8 = 256 possible combinations. And Unicode happens to support all 256 Braille characters.&lt;/p&gt;
&lt;p&gt;One night around 3 a.m., it hit him: &lt;strong&gt;“Wait, this is basically an 8-bit pixel character set!”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That spark — when two unrelated ideas suddenly connect — is exactly the kind of joy hackers live for.&lt;/p&gt;
&lt;p&gt;And then came the classic hacker instinct: &lt;strong&gt;don’t ask whether it’s useful — just build it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The implementation was full of clever hacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mapping the game world onto Braille character grids, each character acting as a 2x4 pixel block&lt;/li&gt;
&lt;li&gt;Using solid dots (⣿) for the snake’s body and blank Braille (⠀) for empty space&lt;/li&gt;
&lt;li&gt;Leveraging JavaScript’s &lt;code&gt;history.replaceState()&lt;/code&gt; API to update the URL in real time without polluting the history&lt;/li&gt;
&lt;li&gt;Refreshing the entire frame each tick so the game animates smoothly inside the address bar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Francisco’s openness was just as “hacker-ish”: &lt;em&gt;“The source code isn’t minified or obfuscated. Just hit Ctrl+U and you’ll see everything.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The whole thing was only a few hundred lines of JavaScript — concise, readable, and elegant. &lt;strong&gt;In the hacker mindset, code isn’t just for execution — it should also be legible, learnable, and inspiring.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;wait-why-does-my-game-look-broken&#34;&gt;Wait… Why Does My Game Look Broken?
&lt;/h2&gt;&lt;p&gt;If you try the game today, you might just see a mess of &lt;code&gt;%20&lt;/code&gt;, backslashes, and gibberish. The snake barely moves — or sometimes the game doesn’t run at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It’s not your fault. It’s not even the code’s fault. The browser has changed.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Francisco admitted, &lt;em&gt;“This project was written for browsers ten years ago. Since then, browsers have made certain ‘security improvements’ that severely limit what’s possible in the URL bar.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The most critical change? &lt;strong&gt;Modern browsers now forcefully escape all spaces in URLs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the game’s design, the blank Braille character (⠀) represented empty space. However, browsers now escape those characters as &lt;code&gt;%20&lt;/code&gt; or something else, which ruins the visual output.&lt;/p&gt;
&lt;p&gt;Francisco even built a fallback system that measured text widths via Canvas and replaced escaped characters on the fly — but it only worked partially.&lt;/p&gt;
&lt;p&gt;He appealed to browser bug trackers. Developers sympathized but ultimately concluded: &lt;strong&gt;“As always, security outweighs fun.”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a result, users’ experiences varied wildly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some people on Chrome scored over 2,000 points.&lt;/li&gt;
&lt;li&gt;Others saw a screen full of garbage in Firefox.&lt;/li&gt;
&lt;li&gt;On iOS Safari, the game sometimes didn’t even render&lt;/li&gt;
&lt;li&gt;Some users found their browsing history polluted with every single game frame.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The same code, drastically different behavior across browsers. That’s just the reality of modern web development.&lt;/p&gt;
&lt;h2 id=&#34;the-golden-age-of-weird-browser-games&#34;&gt;The Golden Age of “Weird Browser Games”
&lt;/h2&gt;&lt;p&gt;Snake in the address bar wasn’t the only project of its kind. The Hacker News discussion turned into a nostalgia trip, with people recalling a whole wave of unconventional browser experiments.&lt;/p&gt;
&lt;h3 id=&#34;2048-in-the-url&#34;&gt;&lt;strong&gt;2048 In the URL&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Someone linked to &lt;a class=&#34;link&#34; href=&#34;https://aquova.net/games/2048/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://aquova.net/games/2048/&lt;/a&gt; — a port of the once-famous puzzle game, implemented entirely inside the address bar using the same Braille and URL-refresh trick.&lt;/p&gt;
&lt;h3 id=&#34;snake-in-the-browser-tab-title&#34;&gt;&lt;strong&gt;Snake In the Browser Tab Title&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Francisco mentioned that someone on Reddit made a version that runs inside the tab’s title instead. It was basically a compromise — no longer in the address bar, but safe from URL escaping.&lt;/p&gt;
&lt;h3 id=&#34;tinyjs-snake&#34;&gt;&lt;strong&gt;TinyJS Snake&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;In 2023, another developer built &lt;a class=&#34;link&#34; href=&#34;https://danielgjackson.github.io/tinyjs#snake&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a similar Snake clone&lt;/a&gt; using a different technique. At the time, browser restrictions weren’t as strict.&lt;/p&gt;
&lt;h3 id=&#34;3d-worlds-in-the-url&#34;&gt;&lt;strong&gt;3D Worlds in the URL&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Another project took things further: &lt;a class=&#34;link&#34; href=&#34;https://matthew.rayfield.world/articles/games-and-graphics-in-popup-url-bars/#:~:text=The%203D%20Room&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;an interactive 3D environment rendered through unconventional browser features&lt;/a&gt;.&lt;br&gt;
One commenter joked: &lt;em&gt;“It’s not Doom, but you can walk around in 3D.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What do all these have in common? &lt;strong&gt;They were built for fun, out of curiosity, with no concern for practicality.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No commercial value. No business use case. Not even “best practices.”&lt;br&gt;
But they embodied the spirit of the early web: &lt;strong&gt;a playground where people could experiment, push boundaries, and have fun.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;why-are-projects-like-this-so-hard-now&#34;&gt;Why Are Projects Like This So Hard Now?
&lt;/h2&gt;&lt;p&gt;It’s not just the space escaping problem. Over the past decade, browsers have introduced countless so-called &lt;strong&gt;security improvements&lt;/strong&gt;:&lt;/p&gt;
&lt;h3 id=&#34;history-api-limits&#34;&gt;&lt;strong&gt;History API Limits&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Francisco originally used &lt;code&gt;history.replaceState()&lt;/code&gt; to update the URL without spamming history entries. Modern browsers now throttle calls to this API, forcing fallback to &lt;code&gt;location.hash&lt;/code&gt; — which clutters your browsing history with every frame of gameplay.&lt;/p&gt;
&lt;h3 id=&#34;url-length-restrictions&#34;&gt;&lt;strong&gt;URL Length Restrictions&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Different browsers cap URL length anywhere from 2,000 to tens of thousands of characters. Encoding game state into URLs quickly hits those ceilings.&lt;/p&gt;
&lt;h3 id=&#34;character-set-restrictions&#34;&gt;&lt;strong&gt;Character Set Restrictions&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;More and more Unicode characters are marked as “unsafe” for URLs. Browsers escape or block them, killing Unicode art projects outright.&lt;/p&gt;
&lt;h3 id=&#34;mobile-compatibility&#34;&gt;&lt;strong&gt;Mobile Compatibility&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;Many mobile browsers hide the URL bar entirely while scrolling — making address-bar games literally unplayable.&lt;/p&gt;
&lt;p&gt;Francisco summed it up: &lt;em&gt;“Every browser change since then has made projects like this harder. I got some sympathy in bug trackers, but security always wins.”&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;when-security-kills-the-fun&#34;&gt;When Security Kills the Fun
&lt;/h2&gt;&lt;p&gt;Here’s the fundamental tension:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nobody disputes the importance of browser security.&lt;/strong&gt;&lt;br&gt;
URL injection attacks, XSS vulnerabilities, phishing — these are real threats affecting billions of users. Browser developers have a duty to protect people.&lt;/p&gt;
&lt;p&gt;But every “security improvement” quietly closes off a door to creativity.&lt;/p&gt;
&lt;p&gt;Francisco’s code worked flawlessly a decade ago. Today, it’s broken not because it was bad, but because the browser “evolved.” That evolution made the web safer — but also more controlled, more uniform, and frankly… more boring.&lt;/p&gt;
&lt;h3 id=&#34;its-not-just-about-games&#34;&gt;&lt;strong&gt;It’s Not Just About Games&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;One Hacker News commenter sneered: &lt;em&gt;“Why don’t people build something useful instead of abusing the internet?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The community overwhelmingly pushed back:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;“The learning value from projects like this is massive.”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“Creative play matters for skill development too.”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“This is exactly why I come to HN — 100% hacker spirit.”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“ChatGPT couldn’t have come up with this. I love the creativity.”&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best response was simple:&lt;br&gt;
&lt;em&gt;“To most people, this is nothing. To me, it’s insane. How did you even think of this?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That’s the point.&lt;/strong&gt; The value of projects like this isn’t in utility, but in pure human creativity — driven by curiosity, joy, and the urge to ask &lt;em&gt;“why not?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And every time we “tighten security,” we don’t just close loopholes. We also close off avenues for wonder.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;in-the-age-of-ai-human-creativity-matters-more&#34;&gt;In the Age of AI, Human Creativity Matters More
&lt;/h2&gt;&lt;p&gt;When asked about AI, Francisco said something striking:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“This game has been online for ten years. It’s probably in AI training data. A robot might be able to replicate it, but it could never enjoy it. (At least not yet.)”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That gets to the heart of our cultural anxiety today. In an era where ChatGPT can generate code in seconds and Copilot can autocomplete whole functions — what projects are still worth building by hand?&lt;/p&gt;
&lt;p&gt;The answer might just lie in this Snake game.&lt;/p&gt;
&lt;p&gt;AI can parse Braille characters, understand Unicode, and spit out JavaScript. But AI can’t feel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 3 a.m. epiphany that “Braille could be pixels”&lt;/li&gt;
&lt;li&gt;the giddy surprise of watching a snake slither inside a URL bar for the first time&lt;/li&gt;
&lt;li&gt;The stubborn joy of debugging escape sequences for hours&lt;/li&gt;
&lt;li&gt;The quiet pride of seeing strangers enjoy your work a decade later&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are &lt;strong&gt;uniquely human creative experiences.&lt;/strong&gt;&lt;br&gt;
In a world where AI can replicate almost all code, that human spark is more precious than ever.&lt;/p&gt;
&lt;h2 id=&#34;we-need-more-projects-like-this&#34;&gt;We Need More Projects Like This
&lt;/h2&gt;&lt;p&gt;Snake in the URL bar went viral, not because it’s useful or profitable, but because it reminded us of something essential:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The internet shouldn’t just be efficient, safe, and standardized. It should also be surprising, playful, and experimental.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When Francisco asked himself, “How does Braille work?” ten years ago, he wasn’t solving a business problem or optimizing UX. He was just curious. That curiosity created something that made thousands of strangers smile.&lt;/p&gt;
&lt;p&gt;In today’s increasingly homogeneous, “safe,” and algorithmically optimized internet, we need more of this. Not because it’s useful, but because it reminds us:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Technology isn’t only about efficiency and safety — it should also be about wonder and joy.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, how many points can &lt;em&gt;you&lt;/em&gt; score? Does your browser even support it?&lt;/p&gt;
&lt;p&gt;Or maybe the real question is: &lt;strong&gt;what’s the last “useless but fun” project you built?&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/playing-snake-in-your-browsers-address-bar-when-the-internet-was-still-fun/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Official discussions readdress error handling: Why has the new syntax been delayed?</title>
        <link>https://huizhou92.com/p/official-discussions-readdress-error-handling-why-has-the-new-syntax-been-delayed/</link>
        <pubDate>Wed, 04 Jun 2025 20:34:41 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/official-discussions-readdress-error-handling-why-has-the-new-syntax-been-delayed/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2025/06/19d137fd979f2645bc026a4c08113aed.png" alt="Featured image of post Official discussions readdress error handling: Why has the new syntax been delayed?" /&gt;&lt;h1 id=&#34;go-officials-revisit-error-handling--why-the-new-syntax-is-still-stuck&#34;&gt;Go Officials Revisit Error Handling — Why the New Syntax Is Still Stuck
&lt;/h1&gt;&lt;p&gt;Recently, the official Go blog published a post titled &lt;a class=&#34;link&#34; href=&#34;https://go.dev/blog/error-syntax&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;em&gt;On | No syntactic support for error handling&lt;/em&gt;&lt;/a&gt;. Contrary to the community’s anticipation for a breakthrough in syntax, the article took a step back—revisiting Go’s long and rocky history of failed attempts to simplify error handling.&lt;/p&gt;
&lt;p&gt;So, why did the Go team choose to publish this now?&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;why-does-the-go-team-keep-revisiting-error-handling&#34;&gt;Why Does the Go Team Keep Revisiting Error Handling?
&lt;/h2&gt;&lt;p&gt;Since its inception, Go has been celebrated for its simplicity and clarity. But one area has always stood out as a sore spot: &lt;strong&gt;error handling is verbose and repetitive.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the familiar Go pattern we’ve all seen:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;result:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The repeated &lt;code&gt;if err != nil&lt;/code&gt; blocks often feel &lt;strong&gt;mechanical and boilerplate&lt;/strong&gt;. Over the years, the Go team has made multiple attempts to design a cleaner syntax—but each one has failed to gain enough traction for implementation.&lt;/p&gt;
&lt;h2 id=&#34;failed-attempts-that-once-held-promise&#34;&gt;Failed Attempts That Once Held Promise
&lt;/h2&gt;&lt;p&gt;Here are a few notable proposals that stirred hope but never made it into the language:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2018: &lt;a class=&#34;link&#34; href=&#34;https://go.googlesource.com/proposal/&amp;#43;/master/design/go2draft-error-handling.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;check&lt;/code&gt; and &lt;code&gt;handle&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Introduced new keywords to reduce error handling verbosity, but were eventually rejected due to concerns about added complexity.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2019: &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/32437&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;try&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Proposed a built-in &lt;code&gt;try()&lt;/code&gt; function to handle errors more concisely. The community pushed back, citing it as “too implicit” and against Go’s design philosophy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2024: The &lt;code&gt;?&lt;/code&gt; Operator Inspired by Rust&lt;/strong&gt;&lt;br&gt;
Ian Lance Taylor suggested borrowing Rust’s &lt;code&gt;?&lt;/code&gt; operator to reduce boilerplate (&lt;a class=&#34;link&#34; href=&#34;https://go.dev/issue/71203&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;proposal #71203&lt;/a&gt;). Once again, the community responded with strong opposition.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also wrote a blog post about it.&lt;/p&gt;
&lt;p&gt;Each failed proposal reveals more than just technical challenges. They reflect a deep-rooted cultural norm in the Go community:&lt;br&gt;
&lt;strong&gt;“Clarity is better than cleverness.”&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;whats-the-real-message-behind-this-blog-post&#34;&gt;What’s The Real Message Behind This Blog Post?
&lt;/h2&gt;&lt;p&gt;If you read between the lines, you’ll see this blog isn’t just a retrospective—it’s a &lt;strong&gt;strategic response&lt;/strong&gt; to the growing noise in the community:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Do we need new syntax for error handling?”&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The post sends a subtle but critical signal:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The question isn’t just about syntax. It’s about the philosophy of the language itself.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Go’s team isn’t aiming to push a new solution just yet. Instead, they want to steer the community back to first principles—asking:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What kind of language do we truly want Go to be?&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;explicit-is-better-than-implicit--a-principle-go-wont-let-go&#34;&gt;“Explicit Is Better Than Implicit” — A Principle Go Won’t Let Go
&lt;/h2&gt;&lt;p&gt;Go&amp;rsquo;s strength lies in its &lt;strong&gt;unambiguous, explicit&lt;/strong&gt; nature. Every new syntax proposal must pass a rigorous checklist:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does it preserve clarity?&lt;/li&gt;
&lt;li&gt;Does the benefit justify the added complexity?&lt;/li&gt;
&lt;li&gt;What unintended side effects might it introduce?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These principles make every proposal an uphill battle—and explain why so many attempts have been shut down before reaching their intended conclusion.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;so-where-does-this-leave-us&#34;&gt;So, Where Does This Leave Us?
&lt;/h2&gt;&lt;p&gt;Another key takeaway from the blog post is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Go team has come to terms with the reality that a new error-handling syntax isn’t coming anytime soon.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;That doesn’t mean it’s impossible—just that the right solution hasn’t been found. The Go team is signaling: the door remains open, but more experimentation, real-world feedback, and reflection are needed.&lt;/p&gt;
&lt;p&gt;In the meantime, Go developers will need to live with the existing pattern. But that also means Go will continue to be what it’s always been: &lt;strong&gt;explicit, transparent, and devoid of magic.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This blog post might look like a historical reflection, even an admission of past failures—but it’s really a catalyst. A challenge to the community:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;What do we truly want Go to become?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;How much clarity are we willing to trade for convenience?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may disagree with the current state of affairs. But it’s hard to deny that this kind of introspection is essential for the health of any programming language.&lt;/p&gt;
&lt;p&gt;Yes, the following proposal might fail again.&lt;br&gt;
Or the community may one day strike the perfect balance.&lt;/p&gt;
&lt;p&gt;What’s certain is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Go community is still thinking, still debating—and still evolving.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://go.dev/blog/error-syntax&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Original blog post →&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/official-discussions-readdress-error-handling-why-has-the-new-syntax-been-delayed/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Go Action Managing Go Application Lifecycles in Kubernetes</title>
        <link>https://huizhou92.com/p/go-action-managing-go-application-lifecycles-in-kubernetes/</link>
        <pubDate>Mon, 02 Jun 2025 17:45:34 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/go-action-managing-go-application-lifecycles-in-kubernetes/</guid>
        <description>&lt;p&gt;This article explores best practices for developing Go applications in Kubernetes, focusing on the different stages of a Pod’s lifecycle and the role of Kubernetes termination signals. Properly managing these phases ensures smooth application shutdowns, preventing data loss or disruptions to user experience. By mastering lifecycle management, teams can efficiently handle updates and workload adjustments.&lt;/p&gt;
&lt;!-- more--&gt;
&lt;h2 id=&#34;the-three-phases-of-an-applications-lifecycle&#34;&gt;The Three Phases of an Application’s Lifecycle
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Application Startup&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application Runtime&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application Shutdown&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each phase requires careful attention to ensure everything proceeds as expected. While most teams focus solely on runtime, managing all three phases in Kubernetes is equally critical.&lt;/p&gt;
&lt;h3 id=&#34;1-application-startup&#34;&gt;1. Application Startup
&lt;/h3&gt;&lt;p&gt;In Kubernetes, a Pod is considered ready when all its containers are prepared to accept requests. This readiness is determined using &lt;strong&gt;readiness probes&lt;/strong&gt; and &lt;strong&gt;readiness gates&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 id=&#34;the-role-of-readiness-probes&#34;&gt;The Role of Readiness Probes
&lt;/h4&gt;&lt;p&gt;A readiness probe signals whether a service is ready to handle traffic. It periodically checks the application’s state to confirm availability. Here’s an example of a readiness probe definition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;readinessProbe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;httpGet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scheme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/ready&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeoutSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;periodSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Key Parameters:&lt;/strong&gt;&lt;br&gt;
• &lt;code&gt;timeoutSeconds&lt;/code&gt;: Maximum time allowed for the probe to respond.&lt;br&gt;
• &lt;code&gt;periodSeconds&lt;/code&gt;: Frequency at which the probe is executed.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;2-application-runtime&#34;&gt;2. Application Runtime
&lt;/h3&gt;&lt;p&gt;During runtime, &lt;strong&gt;liveness&lt;/strong&gt; and &lt;strong&gt;readiness probes&lt;/strong&gt; monitor the service’s health. The liveness probe, in particular, detects deadlocks and determines whether a container should be restarted.&lt;/p&gt;
&lt;h4 id=&#34;example-liveness-probe&#34;&gt;Example Liveness Probe
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;livenessProbe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;httpGet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scheme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/health&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeoutSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;periodSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;initialDelaySeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Important Considerations:&lt;/strong&gt;&lt;br&gt;
• Ensure probes respond quickly to avoid unnecessary restarts due to temporary load spikes.&lt;br&gt;
• Avoid coupling probes with external service dependencies—a single failure shouldn’t trigger cascading restarts.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;3-application-shutdown&#34;&gt;3. Application Shutdown
&lt;/h3&gt;&lt;p&gt;The shutdown phase involves gracefully terminating a Pod. Kubernetes manages this by sending &lt;code&gt;SIGTERM&lt;/code&gt; followed by &lt;code&gt;SIGKILL&lt;/code&gt; if necessary.&lt;/p&gt;
&lt;h4 id=&#34;graceful-shutdown-in-go&#34;&gt;Graceful Shutdown in Go
&lt;/h4&gt;&lt;p&gt;Here’s an example of handling graceful shutdowns in a Go application:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Step 1: Startup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;startService&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;stop&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;signal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NotifyContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;syscall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;SIGINT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;syscall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;SIGTERM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;defer&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;zerolog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;With&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;service&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ServiceName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;NewConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Unable to setup config&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewServeMux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/health&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;healthHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/ready&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;readyHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/task&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;taskHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;server&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Addr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;         &lt;span class=&#34;s&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ServicePort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;      &lt;span class=&#34;nf&#34;&gt;recovery&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;TimeoutHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;HandlerTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Sprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;server timed out, request exceeded %s\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;HandlerTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;ErrorLog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;     &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;LstdFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;ReadTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ReadTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;WriteTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;WriteTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;waitGroup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;WaitGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Run HTTP server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;waitGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;go&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;defer&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;waitGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Done&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;errListen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Is&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errListen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ErrServerClosed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errListen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;server.ListenAndServe error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;go&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Done&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;HTTP server cancelled&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;timeoutCtx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;cancel&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;WithTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;defer&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cancel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;errShutdown&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Shutdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;timeoutCtx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;errShutdown&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errShutdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;server.Shutdown error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;waitGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;go&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;performTask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;waitGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Dur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Since&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;startService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Service started successfully&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;runningService&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Step 2: Runtime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Done&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Step 3: Shutdown&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Dur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Since&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;runningService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Gracefully shutting down service...&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;startGracefullyShuttingDown&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;waitGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Dur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Since&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;startGracefullyShuttingDown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Shutdown service complete&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;key-takeaways&#34;&gt;Key Takeaways
&lt;/h3&gt;&lt;p&gt;• &lt;strong&gt;Design for failure&lt;/strong&gt;—applications must withstand underlying software or hardware failures.&lt;br&gt;
• &lt;strong&gt;Graceful degradation&lt;/strong&gt; and &lt;strong&gt;eventual consistency&lt;/strong&gt; improve reliability and availability.&lt;br&gt;
• Proper use of probes and shutdown mechanisms ensures stable and efficient management of Go applications in Kubernetes.&lt;/p&gt;
&lt;p&gt;Developers can build resilient systems that handle disruptions seamlessly by implementing these best practices. 🚀&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/go-action-managing-go-application-lifecycles-in-kubernetes/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Why Did Go&#39;s Map Get Slower? Let&#39;s See How Go 1.25 Plans to Fix It</title>
        <link>https://huizhou92.com/p/why-did-gos-map-get-slower-lets-see-how-go-1.25-plans-to-fix-it/</link>
        <pubDate>Tue, 20 May 2025 22:22:53 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/why-did-gos-map-get-slower-lets-see-how-go-1.25-plans-to-fix-it/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;This article explains why your program might have gotten slower using maps in Go 1.24, and how the Go team plans to fix this issue.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The feature in Go 1.24 that excited me most was &lt;strong&gt;SwissMap&lt;/strong&gt;. Previously, some unofficial implementations showed up to 50% performance improvements in certain scenarios. The official implementation also provided noticeable gains. You can find more details in my earlier articles:&lt;/p&gt;
&lt;h2 id=&#34;swisstable-a-high-performance-hash-table-implementation&#34;&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/swisstable-a-high-performance-hash-table-implementation/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SwissTable: A High-Performance Hash Table Implementation&lt;/a&gt;
&lt;/h2&gt;&lt;h2 id=&#34;swiss-map-in-go-124-compatibility-extendible-hashing-and-legacy-issues&#34;&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/swiss-map-in-go-124-compatibility-extendible-hashing-and-legacy-issues/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Swiss Map in Go 1.24: Compatibility, Extendible Hashing, and Legacy Issues&lt;/a&gt;
&lt;/h2&gt;&lt;p&gt;However, you might have noticed that &lt;strong&gt;SwissMap&lt;/strong&gt; in Go 1.24 doesn&amp;rsquo;t perform as expected and might even slow down your programs, especially with large maps. This isn&amp;rsquo;t your imagination—it’s a real issue.&lt;br&gt;
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/05/585b320bdb723bc6aa22e592aea367b0.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20250520225126&#34;
	
	
&gt;&lt;br&gt;
&lt;a class=&#34;link&#34; href=&#34;https://x.com/valyala/status/1879988053076504761&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://x.com/valyala/status/1879988053076504761&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The issue has been documented in &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/70835&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Issue #70835&lt;/a&gt;, and the developers are actively working to address it.&lt;/p&gt;
&lt;h2 id=&#34;whats-the-problem&#34;&gt;What&amp;rsquo;s the Problem?
&lt;/h2&gt;&lt;p&gt;Go&amp;rsquo;s maps in the latest version use a Swiss Table structure, which is very fast for small maps and highly concurrent scenarios. However, performance degrades significantly when maps become large and data isn&amp;rsquo;t cached by the CPU (so-called &amp;ldquo;cold&amp;rdquo; data).&lt;/p&gt;
&lt;p&gt;Why does this happen?&lt;/p&gt;
&lt;p&gt;Because SwissMap has a relatively complex internal structure, it organizes data in multiple layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A header structure for the map.&lt;/li&gt;
&lt;li&gt;A directory pointing to a list of table pointers.&lt;/li&gt;
&lt;li&gt;Each table contains control information, keys, and values.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/01/784e3f6a0ff90601480a2da80f3cb9d0.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;When you look up a key, you might encounter &lt;strong&gt;4 to 6 memory jumps&lt;/strong&gt;, each potentially resulting in a cache miss. This causes the CPU to frequently fetch data from slower main memory, significantly reducing speed.&lt;/p&gt;
&lt;p&gt;Large projects like Prometheus noticed this issue clearly after upgrading to Go 1.24, where CPU usage increased dramatically. Upon investigation, it turned out to be due to slower map lookups.&lt;/p&gt;
&lt;h2 id=&#34;how-was-it-discovered&#34;&gt;How Was It Discovered?
&lt;/h2&gt;&lt;p&gt;Test cases didn&amp;rsquo;t detect this issue but instead surfaced in real-world scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using huge maps (several megabytes in size).&lt;/li&gt;
&lt;li&gt;Frequent reads from the map.&lt;/li&gt;
&lt;li&gt;Data was not cached in the CPU’s fast cache.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Michael Pratt from the Go team conducted extensive testing to identify the cause of map access slowdown and detailed his findings in &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/70835&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Issue #70835&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-will-it-be-fixed&#34;&gt;How Will It Be Fixed?
&lt;/h2&gt;&lt;p&gt;To make maps faster, the Go team plans several key changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Simplify directory structure&lt;/strong&gt;: Replace pointer lists with direct structure storage, reducing one memory jump.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compact control information&lt;/strong&gt;: Organize control data more densely to enable more effortless CPU loading.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separate keys and values&lt;/strong&gt;: Change layout to &amp;ldquo;key-key-key + value-value-value&amp;rdquo; for optimized memory access.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Align control bytes&lt;/strong&gt;: Align control information to CPU cache lines to minimize cache misses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These changes are quite challenging since they impact Go’s runtime core:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Garbage collection must continue to work correctly.&lt;/li&gt;
&lt;li&gt;Map resizing logic needs updating.&lt;/li&gt;
&lt;li&gt;Performance for small maps must remain unaffected.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;where-can-you-follow-the-discussion&#34;&gt;Where Can You Follow the Discussion?
&lt;/h2&gt;&lt;p&gt;This issue is actively discussed and tracked. You can find more details in &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/70835&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Issue #70835&lt;/a&gt;. The &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/milestone/122&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Go Release Dashboard&lt;/a&gt; has already marked this issue for resolution in Go 1.25. Additionally, &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/71368&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Issue #71368&lt;/a&gt; discusses another related memory layout issue.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;The Go team consistently strives to enhance the language’s speed and reliability. &lt;code&gt;SwissMap&lt;/code&gt; is a significant improvement, but it has also brought new challenges, such as the recent performance degradation for cold caches.&lt;/p&gt;
&lt;p&gt;Issue #70835 demonstrates how Go continuously improves through community feedback. Thanks to open-source projects like Prometheus, their reports help make Go better.&lt;/p&gt;
&lt;p&gt;If all goes well, Go 1.25 will restore the balance between speed and stability.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look forward to it together!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>A Deep Dive into Go’s Garbage Collector: Bottlenecks, Benchmarks, and Green Tea GC Improvements</title>
        <link>https://huizhou92.com/p/a-deep-dive-into-gos-garbage-collector-bottlenecks-benchmarks-and-green-tea-gc-improvements/</link>
        <pubDate>Mon, 05 May 2025 16:32:57 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/a-deep-dive-into-gos-garbage-collector-bottlenecks-benchmarks-and-green-tea-gc-improvements/</guid>
        <description>&lt;p&gt;Although Go’s garbage collection (GC) mechanism has undergone multiple rounds of optimization in recent years, its performance bottlenecks — especially in high-concurrency and large-memory scenarios — remain a significant focus for developers. Recently, the official Go team stirred up a discussion on GitHub with their proposal for &lt;strong&gt;Green Tea GC&lt;/strong&gt; (#73581): can it further address the time cost of Go’s GC? This article dives deep into Go&amp;rsquo;s GC&amp;rsquo;s design, shortcomings, and real-world performance — and looks at the technical breakthroughs behind Green Tea GC.&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/golang/comments/173n28q/the_myth_of_go_garbage_collection_hindering/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.reddit.com/r/golang/comments/173n28q/the_myth_of_go_garbage_collection_hindering/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;-design-and-implementation-of-go-gc&#34;&gt;📦 Design and Implementation of Go GC
&lt;/h2&gt;&lt;p&gt;Since Go 1.5, Go has used a concurrent mark-sweep algorithm combined with the &lt;strong&gt;tri-color marking&lt;/strong&gt; model and &lt;strong&gt;yuasa-style&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In simple terms, Go’s GC runs in the background, concurrently traversing the heap, marking reachable objects, and gradually cleaning up unreferenced memory blocks. Throughout this process, Go aims for &lt;strong&gt;low latency and minimal pause times&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;✅ Concurrent marking and sweeping&lt;br&gt;
✅ No object movement (i.e., no compaction)&lt;br&gt;
✅ Batch sweeping by spans (memory blocks) to reduce the duration of each Stop-the-World (STW) phase&lt;/p&gt;
&lt;p&gt;This design&amp;rsquo;s direct benefit is that applications can mostly run in parallel with GC, keeping maximum pause times typically below the millisecond level.&lt;/p&gt;
&lt;h2 id=&#34;-known-issues-with-go-gc&#34;&gt;🚧 Known Issues with Go GC
&lt;/h2&gt;&lt;p&gt;While Go GC delivers excellent latency, it still has several hard-to-ignore issues when it comes to time consumption and scalability, particularly:&lt;/p&gt;
&lt;p&gt;1️⃣ &lt;strong&gt;Inefficient memory access&lt;/strong&gt;&lt;br&gt;
During the mark phase, GC jumps across objects, causing frequent CPU cache misses and memory waits — about 35% of GC’s CPU cycles are spent “waiting on memory.” This problem is especially pronounced on NUMA architectures or multi-core, large-memory machines.&lt;/p&gt;
&lt;p&gt;2️⃣ &lt;strong&gt;Lack of generational collection&lt;/strong&gt;&lt;br&gt;
Go GC has no generational mechanism; all objects are treated the same. This becomes cumbersome in high-allocation scenarios. Engineers at Pinterest have pointed out that GC’s CPU usage spikes when memory pressure rises, triggering latency surges.&lt;/p&gt;
&lt;p&gt;3️⃣ &lt;strong&gt;High CPU usage from frequent GCs&lt;/strong&gt;&lt;br&gt;
Twitch’s engineering team reported that even with small to medium heaps (&amp;lt;450 MiB), under steady-state conditions, the system triggers 8–10 GCs per second, up to 400–600 per minute, consuming roughly &lt;strong&gt;30% of CPU time&lt;/strong&gt;. This directly squeezes out the execution time for application threads.&lt;/p&gt;
&lt;h2 id=&#34;-performance-testing-how-gc-impacts-go-programs&#34;&gt;📊 Performance Testing: How GC Impacts Go Programs
&lt;/h2&gt;&lt;p&gt;Let’s look at some real-world benchmark changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go 1.3/1.4 (before concurrent GC)&lt;/strong&gt;&lt;br&gt;
On large heaps (10GB+), GC pauses were measured in seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go 1.5 (with concurrent GC introduced)&lt;/strong&gt;&lt;br&gt;
Under the same conditions, GC pauses shrank to &amp;lt;1ms.&lt;br&gt;
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/05/8d6a9563ad431b76e34d31077cbcd82b.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Pasted image 20250504161704&#34;
	
	
&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Go 1.6–1.8&lt;/strong&gt;&lt;br&gt;
With heaps up to 200GB, GC pauses stayed under 20ms, often around 1ms in normal operation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These improvements are impressive, but note:&lt;br&gt;
✅ Latency control is excellent&lt;br&gt;
⚠️ Total time spent and CPU consumption remain significant, especially under heavy load or high allocation rates.&lt;/p&gt;
&lt;h2 id=&#34;-green-tea-gc-a-new-optimization-approach&#34;&gt;🌿 Green Tea GC: A New Optimization Approach
&lt;/h2&gt;&lt;p&gt;To address these issues, the Go team has proposed Green Tea GC. Its core innovation is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Upgrading from per-object scanning to per-span (memory block) batch scanning.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Specifically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For small objects (≤512B), marking moves from per-object granularity to span-level granularity.&lt;/li&gt;
&lt;li&gt;Only the first marked object pushes the entire span into the scan queue within each span.&lt;/li&gt;
&lt;li&gt;During the GC scan phase, entire spans are batch-processed, significantly improving memory access locality.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, Green Tea improves parallel queue management, using a work-stealing mechanism similar to Go’s scheduler, further boosting multi-core scalability.&lt;/p&gt;
&lt;h2 id=&#34;-green-tea-gc-in-benchmark-tests&#34;&gt;⚡ Green Tea GC in Benchmark Tests
&lt;/h2&gt;&lt;p&gt;Initial benchmarks show that Green Tea GC delivers selective performance gains:&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;Tile38 benchmark (high-fanout tree structures)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GC overhead reduced by ~35%&lt;/li&gt;
&lt;li&gt;Throughput, latency, and memory usage all improved&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;⚠ &lt;strong&gt;bleve-index benchmark (low-fanout, highly mutating workloads)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Objects are scattered with poor memory locality.&lt;/li&gt;
&lt;li&gt;Green Tea’s performance is similar to, or sometimes slightly worse than, standard GC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Summary: Green Tea isn’t a “silver bullet,” but it shows clear advantages in workloads with good memory locality and heavy multi-core scaling — and lays the groundwork for future hardware optimizations like SIMD acceleration.&lt;/p&gt;
&lt;h2 id=&#34;-summary&#34;&gt;🏁 Summary
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Comparison Item&lt;/th&gt;
          &lt;th&gt;Current Go GC&lt;/th&gt;
          &lt;th&gt;Green Tea GC&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Marking granularity&lt;/td&gt;
          &lt;td&gt;Per object&lt;/td&gt;
          &lt;td&gt;Per span (batch)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Memory locality&lt;/td&gt;
          &lt;td&gt;Poor, random jumps&lt;/td&gt;
          &lt;td&gt;High, batches within the same span&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Multi-core scalability&lt;/td&gt;
          &lt;td&gt;Limited&lt;/td&gt;
          &lt;td&gt;Improved, using work-stealing queues&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Performance gains&lt;/td&gt;
          &lt;td&gt;Near low-latency limits&lt;/td&gt;
          &lt;td&gt;Up to 35% GC time reduction in some cases&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Suitable application&lt;/td&gt;
          &lt;td&gt;General workloads&lt;/td&gt;
          &lt;td&gt;Memory-locality-rich, allocation-heavy workloads&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For developers chasing extreme performance, Green Tea GC offers an exciting new direction. To try it out, you can enable the experimental flag in Go 1.25+.&lt;/p&gt;
&lt;p&gt;📝 &lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/73581&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Issue #73581&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/questions/31684862/how-fast-is-the-go-1-5-gc-with-terabytes-of-ram&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://stackoverflow.com/questions/31684862/how-fast-is-the-go-1-5-gc-with-terabytes-of-ram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/golang/comments/173n28q/the_myth_of_go_garbage_collection_hindering/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.reddit.com/r/golang/comments/173n28q/the_myth_of_go_garbage_collection_hindering/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/a-deep-dive-into-gos-garbage-collector-bottlenecks-benchmarks-and-green-tea-gc-improvements/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Long Time Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you find my blog helpful, please subscribe to me via &lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/index.xml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or follow me on &lt;a class=&#34;link&#34; href=&#34;https://x.com/@piaopiaopig&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you have a &lt;a class=&#34;link&#34; href=&#34;https://medium.huizhou92.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Medium&lt;/a&gt; account, follow me there. My articles will be published there as soon as possible.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
