<?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-us</language>
        <copyright>Copyright © 2023 huizhou92</copyright>
        <lastBuildDate>Mon, 09 Mar 2026 13:46:58 +0800</lastBuildDate><atom:link href="https://huizhou92.com/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>GPT-5 Upgrade Guide: Which ChatGPT Plan Should You Choose?</title>
        <link>https://huizhou92.com/p/gpt-5-upgrade-guide-which-chatgpt-plan-should-you-choose/</link>
        <pubDate>Mon, 09 Mar 2026 13:47:01 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/gpt-5-upgrade-guide-which-chatgpt-plan-should-you-choose/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2026/03/afc5f4fde16e624a8ea0aca36a1e8cee.png" alt="Featured image of post GPT-5 Upgrade Guide: Which ChatGPT Plan Should You Choose?" /&gt;&lt;h3 id=&#34;the-problem-with-gpt-5&#34;&gt;The Problem with GPT-5
&lt;/h3&gt;&lt;p&gt;OpenAI dropped &lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-gpt-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPT-5&lt;/a&gt; in August 2025. Eight months later, we&amp;rsquo;re at version 5.4. The model family has exploded from a simple two-tier system to a four-tier pricing structure with more variants than most people can keep track of.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not following AI news daily, figuring out which model to use — let alone which subscription tier — is genuinely confusing.&lt;/p&gt;
&lt;p&gt;This guide won&amp;rsquo;t bombard you with benchmark scores. Instead, I&amp;rsquo;ll tell you exactly what to do based on your actual work scenarios and budget.&lt;/p&gt;
&lt;!-- more--&gt;
&lt;h3 id=&#34;tldr&#34;&gt;TL;DR
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auto mode handles 80% of use cases&lt;/strong&gt; — you don&amp;rsquo;t need to manually select models&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plus is the sweet spot for most professionals&lt;/strong&gt;; Go works for lighter users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coding and long-document analysis got significantly better&lt;/strong&gt;, but casual writing and conversational tone actually degraded&lt;/li&gt;
&lt;li&gt;Agent Mode can handle research and organization tasks, but precision operations aren&amp;rsquo;t quite there yet&lt;/li&gt;
&lt;li&gt;If responses feel boring, it&amp;rsquo;s not you — use prompt techniques to fix it&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;understanding-gpt-5-models-what-each-version-actually-does&#34;&gt;Understanding GPT-5 Models: What Each Version Actually Does
&lt;/h3&gt;&lt;p&gt;Let&amp;rsquo;s be honest: &lt;a class=&#34;link&#34; href=&#34;https://openai.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI&lt;/a&gt; has the most confusing model naming scheme in the industry. GPT-5.2 Instant, GPT-5.3 Instant, GPT-5.4 Thinking, GPT-5.2-Codex — the names alone are enough to give anyone a headache.&lt;/p&gt;
&lt;p&gt;Forget the technical jargon. You only need to know three models:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Model&lt;/th&gt;
					&lt;th&gt;Plain English&lt;/th&gt;
					&lt;th&gt;Best For&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/gpt-5-3-instant/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPT-5.3 Instant&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;Fast, everyday assistant&lt;/td&gt;
					&lt;td&gt;Email replies, translation, summaries, general Q&amp;amp;A&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-gpt-5-4/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPT-5.4 Thinking&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;Deep-thinking analyst&lt;/td&gt;
					&lt;td&gt;Long document analysis, complex reasoning, financial report interpretation&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GPT-5.2-Codex&lt;/td&gt;
					&lt;td&gt;Code specialist&lt;/td&gt;
					&lt;td&gt;Programming, debugging, code review&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;How Auto mode works:&lt;/strong&gt; When you use &lt;a class=&#34;link&#34; href=&#34;https://chatgpt.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ChatGPT&lt;/a&gt;, the system automatically selects a model based on your question&amp;rsquo;s complexity. Simple questions go to 5.3 Instant (fast response), complex ones automatically switch to 5.4 Thinking (slower but deeper reasoning).&lt;/p&gt;
&lt;p&gt;From my experience, Auto mode makes reasonably good decisions most of the time. But if you&amp;rsquo;re processing long documents (financial reports, contracts) or need deep reasoning, manually switch to 5.4 Thinking to ensure the system doesn&amp;rsquo;t sacrifice quality for speed.&lt;/p&gt;
&lt;h3 id=&#34;free-go-plus-or-pro-a-scenario-based-decision-guide&#34;&gt;Free, Go, Plus, or Pro? A Scenario-Based Decision Guide
&lt;/h3&gt;&lt;p&gt;Skip the comparison tables. Ask yourself one question: &lt;strong&gt;How many times per day do you use ChatGPT?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fewer than 5 times daily, simple questions only&lt;/strong&gt; → &lt;strong&gt;Free&lt;/strong&gt;. You get 10 GPT-5.3 messages per 5 hours, 16K context window. Fine for short texts, email replies, and translations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5-20 times daily, occasional file uploads&lt;/strong&gt; → &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://chatgpt.com/pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Go ($8/month)&lt;/a&gt;&lt;/strong&gt;. GPT-5.3 quota jumps to 160 messages per 3 hours, 32K context window, handles longer documents.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;15+ times daily, frequent long documents or Agent Mode&lt;/strong&gt; → &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://chatgpt.com/pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Plus ($20/month)&lt;/a&gt;&lt;/strong&gt;. Same 160 messages per 3 hours for GPT-5.3, but the key difference is 5.4 Thinking quota increases dramatically to 3,000 messages per week, plus fuller Agent Mode access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI-dependent work, 100+ times daily&lt;/strong&gt; → &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://chatgpt.com/pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Pro ($200/month)&lt;/a&gt;&lt;/strong&gt;. No usage caps, full feature access.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 The hidden difference most people miss:&lt;/strong&gt; Free tier&amp;rsquo;s context window is only 16K tokens. Go and Plus get 32K, and manually selecting 5.4 Thinking gives you 256K. This means the free tier literally &amp;ldquo;can&amp;rsquo;t see&amp;rdquo; documents longer than a few pages, severely degrading response quality. This matters more than message limits for daily use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;five-real-world-scenarios-what-actually-got-better&#34;&gt;Five Real-World Scenarios: What Actually Got Better?
&lt;/h3&gt;&lt;h4 id=&#34;email-summaries-and-translation&#34;&gt;Email, Summaries, and Translation
&lt;/h4&gt;&lt;p&gt;Quality is stable, speed is faster. GPT-5.3 Instant performs similarly to GPT-4o on these tasks but responds noticeably quicker. The only caveat: tone leans formal. If you preferred GPT-4o&amp;rsquo;s more casual style, add tone instructions to your prompts.&lt;/p&gt;
&lt;h4 id=&#34;report-analysis-financial-documents-and-long-texts&#34;&gt;Report Analysis, Financial Documents, and Long Texts
&lt;/h4&gt;&lt;p&gt;This is where GPT-5 improved most dramatically. In my testing, 5.4 Thinking can process entire financial reports and catch hidden inconsistencies, with significantly reduced hallucination rates. If your work involves document analysis, this feature alone justifies upgrading to Plus.&lt;/p&gt;
&lt;h4 id=&#34;presentations-and-data-organization&#34;&gt;Presentations and Data Organization
&lt;/h4&gt;&lt;p&gt;Agent Mode can handle multi-step tasks like &amp;ldquo;research these products and organize findings into slides.&amp;rdquo; But it still needs explicit instructions — don&amp;rsquo;t expect it to interpret vague requirements. Treat it as a &amp;ldquo;research assistant that can browse the web.&amp;rdquo;&lt;/p&gt;
&lt;h4 id=&#34;programming-and-debugging&#34;&gt;Programming and Debugging
&lt;/h4&gt;&lt;p&gt;Developers will feel this upgrade the most. GPT-5 series shows major improvements on code-related tasks, generating more complete code and pinpointing bugs more accurately. For developers, 5.4 Thinking or &lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-gpt-5-2-codex/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codex&lt;/a&gt; are currently the strongest options.&lt;/p&gt;
&lt;h4 id=&#34;creative-writing-and-brainstorming&#34;&gt;Creative Writing and Brainstorming
&lt;/h4&gt;&lt;p&gt;Honestly, this is where GPT-5 &lt;strong&gt;regressed&lt;/strong&gt;. Many users report shorter, more formulaic responses lacking the creativity and personality of the GPT-4o era. &lt;a class=&#34;link&#34; href=&#34;https://winbuzzer.com/2026/03/04/chatgpt-gpt-53-instant-update-preachy-tone-hallucinations-xcxwbn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPT-5.3 has been adjusted to reduce &amp;ldquo;preachy&amp;rdquo; tone&lt;/a&gt;, but the overall style remains cooler.&lt;/p&gt;
&lt;p&gt;If you primarily use ChatGPT for creative work, manually select GPT-5.3 Instant and explicitly specify tone in your prompts: &amp;ldquo;respond in a casual conversational style&amp;rdquo; or &amp;ldquo;like chatting with a friend.&amp;rdquo; This noticeably improves output quality.&lt;/p&gt;
&lt;h3 id=&#34;agent-mode-a-realistic-assessment&#34;&gt;Agent Mode: A Realistic Assessment
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-chatgpt-agent/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Agent Mode&lt;/a&gt; represents GPT-5&amp;rsquo;s biggest functional leap, letting ChatGPT operate browsers and complete multi-step tasks. Sounds impressive, but how does it actually perform?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What it does well:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web research: &amp;ldquo;Compare these three products&amp;rsquo; specs and pricing.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Data organization: &amp;ldquo;Summarize this PDF&amp;rsquo;s key points into a table.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Booking and queries: &amp;ldquo;Check flights from Taipei to Tokyo next week.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What it struggles with:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Precise UI operations (button position judgment sometimes fails)&lt;/li&gt;
&lt;li&gt;Login-required operations (security restrictions)&lt;/li&gt;
&lt;li&gt;Multi-step complex workflows (tend to go off-track mid-process)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Practical advice:&lt;/strong&gt; Treat Agent Mode as a &amp;ldquo;research assistant that can browse the web&amp;rdquo; for collecting and organizing information. But for final decisions and precise operations, you&amp;rsquo;re still more reliable.&lt;/p&gt;
&lt;h3 id=&#34;caveats-and-gotchas&#34;&gt;Caveats and Gotchas
&lt;/h3&gt;&lt;h4 id=&#34;the-tone-shift-is-real&#34;&gt;The Tone Shift Is Real
&lt;/h4&gt;&lt;p&gt;This isn&amp;rsquo;t your imagination. When GPT-5 launched, users complained responses felt like &amp;ldquo;a lobotomized overworked secretary&amp;rdquo; — lacking personality and warmth. &lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/gpt-5-3-instant/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPT-5.3 has been tuned to reduce preachiness&lt;/a&gt;, but it&amp;rsquo;s still cooler than GPT-4o overall.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Add tone instructions at the start of your prompts, like &amp;ldquo;respond in a relaxed but professional tone&amp;rdquo; or &amp;ldquo;like an experienced colleague chatting at the water cooler.&amp;rdquo; In my testing, this significantly improves output style.&lt;/p&gt;
&lt;h4 id=&#34;model-deprecation-timeline&#34;&gt;Model Deprecation Timeline
&lt;/h4&gt;&lt;p&gt;GPT-5.2 Instant retires on &lt;strong&gt;June 3, 2026&lt;/strong&gt;. &lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11909943-gpt-52-in-chatgpt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GPT-5.2 Thinking follows on June 5&lt;/a&gt;. Before retirement, they&amp;rsquo;ll move to Legacy Models for paid users. Your conversation history and custom GPTs remain unaffected, but you won&amp;rsquo;t be able to specify these models after retirement.&lt;/p&gt;
&lt;h4 id=&#34;the-auto-mode-black-box&#34;&gt;The Auto Mode Black Box
&lt;/h4&gt;&lt;p&gt;You can&amp;rsquo;t tell which model Auto mode selected. For important work tasks (contract analysis, formal report writing), manually specify 5.4 Thinking to ensure you&amp;rsquo;re using the right tool for the job.&lt;/p&gt;
&lt;h4 id=&#34;privacy-reminder&#34;&gt;Privacy Reminder
&lt;/h4&gt;&lt;p&gt;Agent Mode operates browsers and accesses websites on your behalf. Review authorization scopes before use, and avoid letting it handle tasks involving sensitive information.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary
&lt;/h3&gt;&lt;p&gt;GPT-5 delivers genuine improvements in professional tasks, especially for long document analysis and coding. But casual conversation and creative writing actually got worse. Rather than blindly upgrading, first clarify your primary use cases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My recommendation:&lt;/strong&gt; Start with the free tier to experience GPT-5.3 Instant. Track your usage for a week or two. If you find yourself hitting the &amp;ldquo;10 messages per 5 hours&amp;rdquo; limit daily or need to process long documents, upgrade to Go or Plus. Pro is only worth it if you literally make money with AI.&lt;/p&gt;
&lt;h3 id=&#34;faq&#34;&gt;FAQ
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Will my conversation history and custom GPTs disappear when GPT-5.2 retires?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No. Conversation history and custom GPTs are preserved. You just won&amp;rsquo;t be able to specify GPT-5.2 models after retirement. GPT-5.2 Instant retires June 3, 2026; GPT-5.2 Thinking on June 5. Before retirement, they&amp;rsquo;ll move to Legacy Models for paid users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I manually select models, or am I stuck with Auto mode?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can manually select. Use the model dropdown above the chat interface to switch between models. Auto mode automatically assigns models based on question complexity, which works fine for most daily use. Manually switch to 5.4 Thinking for long documents, coding, or deep reasoning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What&amp;rsquo;s the ChatGPT Go plan? How does it differ from Plus?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Go is a mid-tier option added in early 2026, cheaper than Plus. Both offer the same GPT-5.3 message quota (160 per 3 hours). The main differences: Plus provides significantly more 5.4 Thinking quota (3,000 per week) and fuller access to Agent Mode. If you primarily use GPT-5.3 for daily tasks, Go is sufficient.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you found this guide helpful, feel free to follow me for more practical AI insights. Questions or different experiences? Drop them in the comments — I&amp;rsquo;d love to hear how GPT-5 is working (or not working) for you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; GPT-5, ChatGPT, AI Tools, Productivity, OpenAI, Technology Guide&lt;/p&gt;
</description>
        </item>
        <item>
        <title>go-lambdas-medium</title>
        <link>https://huizhou92.com/p/go-lambdas-medium/</link>
        <pubDate>Sat, 07 Mar 2026 10:07:14 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/go-lambdas-medium/</guid>
        <description>&lt;h1 id=&#34;go-is-finally-getting-lambdas--8-years-in-the-making&#34;&gt;Go Is Finally Getting Lambdas — 8 Years in the Making
&lt;/h1&gt;&lt;h3 id=&#34;how-a-single-proposal-with-900-comments-is-quietly-reshaping-gos-syntax&#34;&gt;How a Single Proposal with 900+ Comments is Quietly Reshaping Go&amp;rsquo;s Syntax
&lt;/h3&gt;&lt;p&gt;&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2026/02/17d044c962a41c177b16c02fd0da6500.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Medium cover&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It started in August 2017. A developer opened issue &lt;a class=&#34;link&#34; href=&#34;https://github.com/golang/go/issues/21498&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;#21498&lt;/a&gt; on the Go repository with a modest title: &lt;em&gt;&amp;quot;&lt;strong&gt;proposal: spec: short function literals.&lt;/strong&gt;&amp;quot;&lt;/em&gt; Nobody could have predicted that eight years later, the discussion would stretch to &lt;strong&gt;915 comments&lt;/strong&gt;, involve Go&amp;rsquo;s core team, and still be searching for a final answer.&lt;/p&gt;
&lt;!-- more--&gt;
&lt;p&gt;But as of early 2026, we&amp;rsquo;re closer than ever.&lt;/p&gt;
&lt;h3 id=&#34;whats-the-problem&#34;&gt;What&amp;rsquo;s the Problem?
&lt;/h3&gt;&lt;p&gt;Go&amp;rsquo;s function literals are verbose. When you pass a callback to a function, you write this:&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-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;nx&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Slice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&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;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&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;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&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;kt&#34;&gt;bool&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;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&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;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;In languages with lambda syntax, the same intent takes far less ceremony:&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;/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;c1&#34;&gt;// What Go developers dream of&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;nx&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Slice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&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;nx&#34;&gt;i&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;nx&#34;&gt;j&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;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&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;The types of &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; are already known from &lt;code&gt;sort.Slice&lt;/code&gt;&amp;rsquo;s signature. The compiler can infer them. Yet Go forces you to spell them out every single time.&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t just an aesthetic complaint. In modern Go code with generics, higher-order functions, and functional patterns — callbacks appear everywhere. The verbosity adds up.&lt;/p&gt;
&lt;h3 id=&#34;eight-years-of-debate&#34;&gt;Eight Years of Debate
&lt;/h3&gt;&lt;p&gt;The proposal has gone through three distinct phases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 1 (2017–2020): &amp;ldquo;Do we even need this?&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The early reaction was skeptical. Dave Cheney captured the sentiment bluntly: &lt;em&gt;&amp;ldquo;Please no, clear is better than clever.&amp;rdquo;&lt;/em&gt; The Go philosophy has always favored explicitness. If the compiler can infer the types, should it?&lt;/p&gt;
&lt;p&gt;Robert Griesemer (one of Go&amp;rsquo;s original designers) was sympathetic but unconvinced by the early syntax proposals. Ian Lance Taylor suggested restricting it to expression bodies only — no block, no explicit &lt;code&gt;return&lt;/code&gt; — which made the tradeoff clearer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 2 (2020–2023): Syntax proliferation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Once generics arrived in Go 1.18, the callback problem became undeniable. Functional utilities like &lt;code&gt;slices.SortFunc&lt;/code&gt;, &lt;code&gt;maps.Keys&lt;/code&gt;, and iterator adapters made verbose function literals a daily friction point.&lt;/p&gt;
&lt;p&gt;Dozens of syntax variants were proposed:&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;/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;c1&#34;&gt;// Variant A: arrow syntax&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;p&#34;&gt;(&lt;/span&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;w&#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 class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;y&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&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;// Variant B: backslash (inspired by Haskell)&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;err&#34;&gt;\&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;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#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 class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;y&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&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;// Variant C: fn keyword&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;nf&#34;&gt;fn&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;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#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 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 class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;y&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&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;// Variant D: dot notation&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;p&#34;&gt;.(&lt;/span&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;w&#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 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 class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;y&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;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Each had vocal supporters and equally vocal critics. The thread became, as one commenter put it, &lt;em&gt;&amp;ldquo;an infinite loop with a new syntax proposed every 50 comments.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 3 (2024–present): Convergence&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In June 2024, a smaller working group reached a narrow consensus. The key insight from Griesemer crystallized the requirements:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;The primary benefit is leaving type annotations away in the signature&lt;/li&gt;
&lt;li&gt;Parameters should be enclosed in some form of bracketing&lt;/li&gt;
&lt;li&gt;Moving parameters inside the block is a non-starter&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The current frontrunner syntax:&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;c1&#34;&gt;// fn keyword with type inference&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;nx&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Slice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&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;nf&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&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;nx&#34;&gt;j&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;kt&#34;&gt;bool&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 class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&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&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;// Or with expression body&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;nx&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Slice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&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;nf&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&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;nx&#34;&gt;j&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;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;people&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Age&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;The &lt;code&gt;\()&lt;/code&gt; variant — inspired by Haskell&amp;rsquo;s lambda — also has strong support for its brevity, though readability concerns persist.&lt;/p&gt;
&lt;h3 id=&#34;why-this-is-hard&#34;&gt;Why This Is Hard
&lt;/h3&gt;&lt;p&gt;Go&amp;rsquo;s simplicity is not accidental. Every feature addition carries a cost: cognitive load for new developers, edge cases in the spec, tooling complexity, and the risk of inconsistency with existing idioms.&lt;/p&gt;
&lt;p&gt;The short function literal proposal exposes a genuine tension. The Go team must answer: &lt;strong&gt;at what point does brevity become obscurity?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Consider this real-world scenario with iterators (new in Go 1.23):&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;/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;c1&#34;&gt;// Current Go&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;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&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;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;slices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&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;nx&#34;&gt;yield&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &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;kt&#34;&gt;string&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;kt&#34;&gt;int&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;kt&#34;&gt;bool&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;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;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&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;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;m&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;nf&#34;&gt;yield&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&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;nx&#34;&gt;v&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;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;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;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;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;nx&#34;&gt;k&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;nx&#34;&gt;v&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;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&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;// With short function literals&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;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&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;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;slices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;yield&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;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;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&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;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;m&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 class=&#34;nf&#34;&gt;yield&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&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;nx&#34;&gt;v&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;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;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;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;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;nx&#34;&gt;k&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;nx&#34;&gt;v&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;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;The second version is shorter. But is it clearer? That depends entirely on whether Go developers internalize the new syntax — which takes years at the ecosystem level.&lt;/p&gt;
&lt;h3 id=&#34;what-happens-next&#34;&gt;What Happens Next
&lt;/h3&gt;&lt;p&gt;The proposal is not yet accepted. As of early 2026, the Go team is still evaluating the exact syntax. The most likely outcome is a conservative version: type inference for parameters, optional expression body, familiar bracketing.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s clear is that &lt;strong&gt;the &amp;ldquo;no&amp;rdquo; camp has lost the argument&lt;/strong&gt;. The combination of generics, iterators, and functional patterns has made verbose function literals a genuine ergonomic problem. The question is now &lt;em&gt;how&lt;/em&gt; to solve it, not &lt;em&gt;whether&lt;/em&gt; to.&lt;/p&gt;
&lt;p&gt;If Go 1.27 ships with short function literals, it will be one of the most significant syntax additions since generics. Eight years of debate, distilled into a few characters.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;Issue #21498 has been open since 2017, with 900+ comments — Go&amp;rsquo;s longest-running syntax debate&lt;/li&gt;
&lt;li&gt;The core problem: Go requires explicit types in function literals even when they can be inferred&lt;/li&gt;
&lt;li&gt;After years of proposals, the community is converging on &lt;code&gt;fn(params)&lt;/code&gt; or &lt;code&gt;\(params)&lt;/code&gt; syntax&lt;/li&gt;
&lt;li&gt;The Go team&amp;rsquo;s constraint: brevity must not come at the cost of readability and learnability&lt;/li&gt;
&lt;li&gt;A formal proposal is likely in 2026 — watch the issue&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;If this post helped you understand Go&amp;rsquo;s evolution, consider following for more deep dives into Go internals and language design.&lt;/em&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/go-lambdas-medium/&#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 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;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;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;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;| 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;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;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;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;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;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;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;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;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;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;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;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Event&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&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;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&amp;#34;name&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;nx&#34;&gt;StartTime&lt;/span&gt;&lt;span class=&#34;w&#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;Time&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&amp;#34;start_time,omitzero&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;nx&#34;&gt;EndTime&lt;/span&gt;&lt;span class=&#34;w&#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;Time&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&amp;#34;end_time,omitzero&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;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;这对于 &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;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&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;nx&#34;&gt;Version&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                          &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&amp;#34;version&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;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                       &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&amp;#34;name&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;nx&#34;&gt;Extra&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&amp;#34;,unknown&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;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;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>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;w&#34;&gt; &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;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&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;nx&#34;&gt;x&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;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&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;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&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;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;nx&#34;&gt;y&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;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&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;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&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;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;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;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#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 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;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&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;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;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;w&#34;&gt; &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;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;c1&#34;&gt;// Step 1: Startup&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;nx&#34;&gt;startService&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;nx&#34;&gt;ctx&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;nx&#34;&gt;stop&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#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 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;k&#34;&gt;defer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &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 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&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;nx&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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 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&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;nx&#34;&gt;config&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;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&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;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 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;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&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;nx&#34;&gt;mux&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;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;w&#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 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;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;w&#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 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;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;w&#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 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&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;nx&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;nx&#34;&gt;Addr&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;s&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#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 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;nx&#34;&gt;Handler&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;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;w&#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;w&#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;w&#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;w&#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;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;nx&#34;&gt;ErrorLog&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;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;w&#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;w&#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 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;nx&#34;&gt;ReadTimeout&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;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 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;nx&#34;&gt;WriteTimeout&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;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 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;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&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;nx&#34;&gt;waitGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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&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;c1&#34;&gt;// Run HTTP server&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;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 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;k&#34;&gt;go&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &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;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;k&#34;&gt;defer&lt;/span&gt;&lt;span class=&#34;w&#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;nf&#34;&gt;Done&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;nx&#34;&gt;errListen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&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;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;w&#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;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;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 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;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;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&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;k&#34;&gt;go&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &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;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;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 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;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 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;nx&#34;&gt;timeoutCtx&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;nx&#34;&gt;cancel&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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 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;k&#34;&gt;defer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &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 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;nx&#34;&gt;errShutdown&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errShutdown&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&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;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 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;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;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&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;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 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;k&#34;&gt;go&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &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;w&#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;w&#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;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&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;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;w&#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 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;nx&#34;&gt;runningService&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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&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;c1&#34;&gt;// Step 2: Runtime&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;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 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;nf&#34;&gt;stop&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&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;c1&#34;&gt;// Step 3: Shutdown&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;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;w&#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 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;nx&#34;&gt;startGracefullyShuttingDown&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#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 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;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 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;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;w&#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 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;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;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>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>
        <item>
        <title>The Importance of Website Icons (Favicon)</title>
        <link>https://huizhou92.com/p/the-importance-of-website-icons-favicon/</link>
        <pubDate>Tue, 18 Feb 2025 11:30:38 +0800</pubDate>
        
        <guid>https://huizhou92.com/p/the-importance-of-website-icons-favicon/</guid>
        <description>&lt;img src="https://images.hxzhouh.com/blog-images/2025/02/65e64661a046efca8dcbc39b98ae2b91.png" alt="Featured image of post The Importance of Website Icons (Favicon)" /&gt;&lt;p&gt;Recently, &lt;a class=&#34;link&#34; href=&#34;https://taoshu.in/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tao Shu&amp;rsquo;s Blog&lt;/a&gt; published an article about reciprocal links, and I took the initiative to request a link exchange. Tao Shu promptly responded and kindly reminded me that adding a &lt;code&gt;favicon (icon)&lt;/code&gt; to my blog would help RSS subscribers quickly identify it. At that moment, I wondered, &amp;ldquo;What is a &lt;code&gt;favicon&lt;/code&gt;?&amp;rdquo; (The struggles of a backend developer!)&lt;/p&gt;
&lt;p&gt;Later, I consulted DeepSeek:&lt;br&gt;
In web design, icons are small yet significant elements. They assist users in quickly identifying a website and enhancing the overall user experience.&lt;/p&gt;
&lt;h3 id=&#34;common-usage-scenarios&#34;&gt;Common Usage Scenarios:
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Browser Tab&lt;/strong&gt;: Displayed next to the webpage title.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bookmark Bar&lt;/strong&gt;: Shown when users save a webpage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Home Screen Icon&lt;/strong&gt;: Displayed when a webpage is added to the home screen on mobile devices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PWA (Progressive Web App)&lt;/strong&gt;: Used as the application icon.&lt;br&gt;
For example:&lt;br&gt;
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/02/6df56f22e8fad0c4fe55bffcab3ed090.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Icon displayed in the browser tab&#34;
	
	
&gt;&lt;br&gt;
Icon displayed in the browser tab.&lt;br&gt;
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/02/c2530b4f9491c01730c710dcd24a325f.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Icon displayed in the bookmark bar.&#34;
	
	
&gt;&lt;br&gt;
The icon displayed in the bookmark bar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The icon can be displayed even on Android devices, as the Chrome browser&amp;rsquo;s feature to add a webpage to the home screen allows this.&lt;br&gt;
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/02/861e9e820063fe4d7bbff32e9f8de05b.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Using Android Chrome to add a webpage to the phone’s home screen&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;how-to-set-up&#34;&gt;How to Set Up
&lt;/h2&gt;&lt;p&gt;The simplest way to set an icon is to add a line in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section of the webpage.&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-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;rel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;icon&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;image/png&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/favicon.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;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;If you are using Hugo or other tools, there may be specific settings for the favicon.&lt;br&gt;
Some large websites, such as &lt;code&gt;google.com&lt;/code&gt; and &lt;code&gt;apple.com&lt;/code&gt;, may have more considerations, and their setups may differ.&lt;/p&gt;
&lt;h2 id=&#34;important-considerations&#34;&gt;Important Considerations
&lt;/h2&gt;&lt;p&gt;The icon size is also essential to optimize the user experience and achieve the best display effect across various scenarios.&lt;/p&gt;
&lt;h3 id=&#34;common-sizes&#34;&gt;Common Sizes:
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;16x16&lt;/strong&gt;: Browser tab icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;32x32&lt;/strong&gt;: Bookmark bar icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;64x64&lt;/strong&gt;: High-resolution screen icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;180x180&lt;/strong&gt;: iOS device home screen icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;192x192&lt;/strong&gt; and &lt;strong&gt;512x512&lt;/strong&gt;: PWA icons.&lt;br&gt;
This is why we often see multiple icons set on some websites, such as the &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo website&lt;/a&gt;.&lt;br&gt;
&lt;img src=&#34;https://images.hxzhouh.com/blog-images/2025/02/4d83d2d0666f924072095b981ba2ff0e.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Hugo website has set two icons&#34;
	
	
&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Modern browsers support selecting different icon sizes based on various scenarios and screen PPI, striving to achieve the best display effect in all situations.&lt;/p&gt;
&lt;h3 id=&#34;choosing-icon-formats&#34;&gt;Choosing Icon Formats
&lt;/h3&gt;&lt;p&gt;Icons can be created in different image formats, specified by the type attribute. Standard icon formats include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ICO&lt;/strong&gt;: Traditional format, good compatibility, supports multiple sizes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PNG&lt;/strong&gt;: Modern format, supports transparent backgrounds, and is suitable for high-resolution screens.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SVG&lt;/strong&gt;: Vector format, infinitely scalable without losing quality, suitable for responsive design.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;multi-resolution-icons&#34;&gt;Multi-Resolution Icons
&lt;/h3&gt;&lt;p&gt;If maintaining multiple icon files seems cumbersome, you can use a multi-resolution icon (Multi-Resolution ICO or Multi-Size ICO), a single file containing various sizes and color depths. This allows multiple bitmaps (BMP or PNG format) to be stored in one file.&lt;br&gt;
An ICO file includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File Header&lt;/strong&gt;: Defines the ICO file type and the number of images it contains.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image Directory&lt;/strong&gt;: Describes the size, color depth, offset, and other information for each image.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image Data&lt;/strong&gt;: Contains the actual pixel data for the images.&lt;br&gt;
When a browser needs an icon, it selects the most appropriate size from the ICO file. The downside is that an ICO file containing multiple sizes may be larger than a file with a single size.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article does not delve deeper into topics such as the &lt;code&gt;manifest.json&lt;/code&gt; unique to Android Chrome or the &lt;code&gt;apple-mobile-web-app-capable&lt;/code&gt; for Apple devices. Interested readers are encouraged to explore further.&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huizhou92.com/p/the-importance-of-website-icons-favicon/&#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>
