<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel>
  <title>The shelf — 24k</title>
  <link>https://unclassi.fyi/blog/</link>
  <atom:link href="https://unclassi.fyi/50/rss.xml" rel="self" type="application/rss+xml" />
  <description>Sriram V&#039;s personal workshop: resilient systems, small useful software, field notes, and a deliberately handmade corner of the web.</description>
  <language>en</language>
  <lastBuildDate>Wed, 28 Oct 2026 00:00:00 GMT</lastBuildDate>
  <generator>24k's hand-built static generator</generator>
  <item>
    <title>Stop overoptimizing everything for economy</title>
    <link>https://unclassi.fyi/blog/notes/stop-overoptimizing-everything-for-economy/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/stop-overoptimizing-everything-for-economy/</guid>
    <pubDate>Wed, 28 Oct 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Will you question it or turn a blind eye? - to avoid getting hurt.&lt;/p&gt;&lt;p&gt;Imagine an ocean, brimming with full of marine life, and you see various class of predators, preys, plants coexist. Each animal has it’s own place in the ocean purely based on its nature. By that, corals have a permanent place on the ocean rocks, and rocks root onto the ocean floor. Nobody ordered them to live so low, beneath all the other creatures, forever. It is just what they are.&lt;/p&gt;
&lt;p&gt;Pretty cool. A fragile equilibrium guides their lives. No single creature on the ocean got the power to dictate where the others should live or what they should do with their lives. Everybody gets to live, based on what they perceive around them.&lt;/p&gt;
&lt;p&gt;Now, based on what I perceive around me, I feel we have been dictated how to live by a selected few monopolies. Over the years, their intentions have ultimately got biased around money and time Nothing wrong with that, and we can debate it is somewhat the same case with marine life too &lt;s&gt;(replace money with food)&lt;/s&gt;, I don’t deny that - but the problem I see is, on one side marine animals get to live with freedom to do whatever they feel like it. On the other side, humans lack options. Their choices have been heavily constricted by monopolies. It’s often the case where you don’t get to choose what you wanted to do with the fullest of your ability or, you simply don’t care anymore - coz you have been baptized by the monopolies. Monopolies optimize their choices for money &amp;amp; time - the two fundamental, intertwined commodities in human lives, and their choices are passed down to humans. Anytime a circle of community goes extinct, we reason “the market moved on”, or “nobody wants this anymore” - but think deeply, who decided that? who forced those seed of thoughts into you? and who else have been affected the same way? Did you choose to accept it or were you forced to turn a blind eye? Can you deny the fact that you’ve been enslaved against your true will?&lt;/p&gt;
&lt;p&gt;Think… draw the connections. See the truth for yourself. We have been conditioned in the name of pursuing greatness, often blindly and by not leaving enough power to the regulating bodies. Ah, but to no one’s surprise they join the party late and virtually powerless just like us.&lt;/p&gt;
&lt;p&gt;We pay with our lives for the betterment of a company, or a country - the pool of poured life energy is what further strengthens it. When they overoptimize that process, someone has to pay for the commodities. Coupled with monopolies in this game and lessening choices to extract commodities from, the structure collapses from within.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.apricitas.io/p/ai-and-the-fall-of-the-creative-class&quot;&gt;https://www.apricitas.io/p/ai-and-the-fall-of-the-creative-class&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://news.ycombinator.com/item?id=50226419&quot;&gt;https://news.ycombinator.com/item?id=50226419&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Moral of the story? nothing… I’m just making arm chair speculations.&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Named Colors</title>
    <link>https://unclassi.fyi/blog/notes/named-colors/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/named-colors/</guid>
    <pubDate>Fri, 23 Oct 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;List of all colors that were named in one cube.&lt;/p&gt;&lt;p&gt;Names like Larksurp boquet, King lime are okay, but “Alright Then I Became a Princess” what?! who names colors like that… I wonder whether pantone colors are listed here too.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://names.color.pizza/&quot;&gt;https://names.color.pizza/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>Frontier nerfbench</title>
    <link>https://unclassi.fyi/blog/notes/frontier-nerfbench/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/frontier-nerfbench/</guid>
    <pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Sometimes, the bitter day you had with your agents reflects here&lt;/p&gt;&lt;p&gt;see if models regress after release - &lt;a href=&quot;https://www.bridgebench.ai/nerf-bench&quot;&gt;https://www.bridgebench.ai/nerf-bench&lt;/a&gt;&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>Purelymail</title>
    <link>https://unclassi.fyi/blog/notes/purelymail/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/purelymail/</guid>
    <pubDate>Mon, 28 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;A email client for $10/yr (or even less). Supports custom domain, with good IP reputation and has a great team.&lt;/p&gt;&lt;p&gt;Purelymail, I just set up one and it’s really cool! time to update all my email links on LinkedIn and stuff.&lt;br&gt;
&lt;a href=&quot;https://www.emaildiscussions.com/showthread.php?t=77218&quot;&gt;https://www.emaildiscussions.com/showthread.php?t=77218&lt;/a&gt;&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>Breaking ties with google playstore</title>
    <link>https://unclassi.fyi/blog/notes/breaking-ties-with-google-playstore/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/breaking-ties-with-google-playstore/</guid>
    <pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;High friction app distribution for an indie&lt;/p&gt;&lt;p&gt;Having the worst search results, and terrible recommendations it has for their primary users, it also bothers small indie developers so much like described here &lt;a href=&quot;https://gultsch.de/posts/breaking-up-with-google-play/&quot;&gt;https://gultsch.de/posts/breaking-up-with-google-play/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;discussions: &lt;a href=&quot;https://news.ycombinator.com/item?id=49855315&quot;&gt;https://news.ycombinator.com/item?id=49855315&lt;/a&gt;&lt;/p&gt;
</description>
    <category>story</category>
  </item>
<item>
    <title>Keep scrolling, keep scrolling until you reach</title>
    <link>https://unclassi.fyi/blog/notes/keep-scrolling-keep-scrolling-until-you-reach/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/keep-scrolling-keep-scrolling-until-you-reach/</guid>
    <pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;I&amp;#039;ll oneday humbly steal this style someday&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://anoma.ly/notes/opencode-reloaded/&quot;&gt;https://anoma.ly/notes/opencode-reloaded/&lt;/a&gt; keep scrolling, keep scrolling… read read keep on scrolling… until you reach the end&lt;/p&gt;
</description>
    <category>presentation</category>
  </item>
<item>
    <title>Linux journey</title>
    <link>https://unclassi.fyi/blog/notes/linux-journey/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/linux-journey/</guid>
    <pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Interactive guide. Gotta check the site and learn a little everyday&lt;/p&gt;&lt;p&gt;Learn linux basics (interactively):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Диван, давай воркай&lt;br&gt;
&lt;a href=&quot;https://labex.io/linuxjourney&quot;&gt;https://labex.io/linuxjourney&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Throwing a wrench into model development</title>
    <link>https://unclassi.fyi/blog/notes/throwing-a-wrench-into-model-development/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/throwing-a-wrench-into-model-development/</guid>
    <pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;A necessary deed or a sin (from company&amp;#039;s pov) ?&lt;/p&gt;&lt;p&gt;Ah, another person fearing the growth of AI and quitting his job: &lt;a href=&quot;https://robert.ocallahan.org/2026/09/goodbye-google.html&quot;&gt;https://robert.ocallahan.org/2026/09/goodbye-google.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All his points had reasonable concern, but nothing is going to change.&lt;/p&gt;
</description>
    <category>story</category>
  </item>
<item>
    <title>Real reason behind layoffs and rehires</title>
    <link>https://unclassi.fyi/blog/notes/real-reason-behind-layoffs-and-rehires/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/real-reason-behind-layoffs-and-rehires/</guid>
    <pubDate>Mon, 14 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;rationalizing, poor organization efficiency, negative business ROI and misaligned incentives - all this calls for a reset&lt;/p&gt;&lt;p&gt;THE REAL REASON BEHIND LAYOFFS: &lt;a href=&quot;https://m.youtube.com/watch?v=fv8zpYI9n6s&quot;&gt;https://m.youtube.com/watch?v=fv8zpYI9n6s&lt;/a&gt; (absolute gem, must watch).&lt;/p&gt;
&lt;p&gt;Layoffs are too justified it makes me slightly angry… Ah but what can you do… AHHHH the upper echelons! Stop playing with economics like that…&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>The single main thread</title>
    <link>https://unclassi.fyi/blog/notes/the-single-main-thread/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/the-single-main-thread/</guid>
    <pubDate>Sat, 12 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Frontend optimizations should favour time over the amount&lt;/p&gt;&lt;p&gt;Webapp optimizations rarely has anything to do with your code, but more on what lands on main thread often. I see frontend frameworks in a new angle now…&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kciter.so/posts/the-expensive-main-thread/en/&quot;&gt;https://kciter.so/posts/the-expensive-main-thread/en/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Operating clickhouse at petabyte scale</title>
    <link>https://unclassi.fyi/blog/notes/operating-clickhouse-at-petabyte-scale/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/operating-clickhouse-at-petabyte-scale/</guid>
    <pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;He had operated petabyte-scale ClickHouse clusters for 5 years&lt;/p&gt;&lt;p&gt;Mostly about choosing the right storage (local / cloud), sharding vs replica with partitioning - based on latency or QPS requirement. Oh I forgot about choosing compression algorithm, problems during upgrades, injestion side-effects and handling backpressure. I could add part 2 finding here too (but more on this later).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.tinybird.co/blog/what-i-learned-operating-clickhouse&quot;&gt;https://www.tinybird.co/blog/what-i-learned-operating-clickhouse&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://www.tinybird.co/blog/what-i-learned-operating-clickhouse-part-ii&quot;&gt;https://www.tinybird.co/blog/what-i-learned-operating-clickhouse-part-ii&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Discussions:&lt;br&gt;
&lt;a href=&quot;https://news.ycombinator.com/item?id=49601138&quot;&gt;https://news.ycombinator.com/item?id=49601138&lt;/a&gt;&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Seagate fails twice as fast as WD</title>
    <link>https://unclassi.fyi/blog/notes/seagate-fails-twice-as-fast-as-wd/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/seagate-fails-twice-as-fast-as-wd/</guid>
    <pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Seagate drive failures are 2x compared to WD&lt;/p&gt;&lt;p&gt;Test setup and observations: &lt;a href=&quot;https://www.xda-developers.com/re-evaluating-all-of-the-hdds-in-my-nas/&quot;&gt;https://www.xda-developers.com/re-evaluating-all-of-the-hdds-in-my-nas/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’m about to crie.&lt;br&gt;
&lt;em&gt;[looking at my seagate external SSD]&lt;/em&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Transaction networks</title>
    <link>https://unclassi.fyi/blog/notes/transaction-networks/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/transaction-networks/</guid>
    <pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Visa, Mastercard, RuPay what do they do?&lt;/p&gt;&lt;p&gt;Authorization, Clearning, and settlement of funds over the wire. Also about disputes and arbitration. More on: &lt;a href=&quot;https://tautology.town/2026/06/01/card-networks.html&quot;&gt;https://tautology.town/2026/06/01/card-networks.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Discussion: &lt;a href=&quot;https://news.ycombinator.com/item?id=49614280&quot;&gt;https://news.ycombinator.com/item?id=49614280&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also, europe is now building European Payments Initiative, but that is similar to UPI in india (direct account to account transfer).&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Full E2E GPU rendered UI</title>
    <link>https://unclassi.fyi/blog/notes/full-e2e-gpu-rendered-ui/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/full-e2e-gpu-rendered-ui/</guid>
    <pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Please delete chromium and electron apps for me pls&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gpui.rs/&quot;&gt;https://gpui.rs/&lt;/a&gt; GPU rendering framework for UIs, a proper GPU UI&lt;/p&gt;
&lt;p&gt;tldr: To me, if this can replace electron apps, and chromium wrappers (like discord), then it is totally worth to check this project. And based on quick investigation, it is certainly possible! (excluding some annoying discord nitro and other collaborative activities).&lt;/p&gt;
&lt;p&gt;Detailed breakdown with method names: &lt;a href=&quot;https://chatgpt.com/share/6ac0be0e-c94c-83e8-90e1-c65388ed55a5&quot;&gt;Link to ChatGPT&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is also odin, and it’s own video editor (built entirely with odin). That is interesting to check out too &lt;a href=&quot;https://blickeditor.com/&quot;&gt;blick editor&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also check out GPU UI on neovim by teejdevries&lt;/p&gt;
&lt;p&gt;New: someone wrote telegram desktop in rust with GPUI &lt;a href=&quot;https://github.com/shinycake/quill&quot;&gt;https://github.com/shinycake/quill&lt;/a&gt;&lt;br&gt;
and rumours say discord is officially being rewritten under the codeword “phoenix”.&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>Most European pilled models for ya apps</title>
    <link>https://unclassi.fyi/blog/notes/most-european-pilled-models-for-ya-apps/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/most-european-pilled-models-for-ya-apps/</guid>
    <pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;They got iOS support primarily, then they support android. Got a macos cli too. The models are extremely lightweight, runs completely in local, so worth checking out.  Shoutout to the glorious GDPR&lt;/p&gt;&lt;p&gt;Most European pilled models. These guys are cooking…  &lt;s&gt;but I still don’t see how they make money.&lt;/s&gt;&lt;br&gt;
&lt;a href=&quot;https://desertant.com/blog/introducing-desert-ant-labs/&quot;&gt;https://desertant.com/blog/introducing-desert-ant-labs/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Okay, Every model is free up to 100k monthly active devices per SDK. Unlimited inference per user. Might copy this design style someday &lt;a href=&quot;https://news.ycombinator.com/item?id=49626960&quot;&gt;https://news.ycombinator.com/item?id=49626960&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Their site actually looks clean.&lt;/p&gt;
&lt;p&gt;discussion thread: &lt;a href=&quot;https://news.ycombinator.com/item?id=49625275&quot;&gt;https://news.ycombinator.com/item?id=49625275&lt;/a&gt;&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>No internet still means yes</title>
    <link>https://unclassi.fyi/blog/notes/no-internet-still-means-yes/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/no-internet-still-means-yes/</guid>
    <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;The push notifications, and in-app ads - sometimes they simply don&amp;#039;t care even when you have disabled internet access in app info. Now you know why.&lt;/p&gt;&lt;p&gt;Content taken from &lt;a href=&quot;https://t.me/AppManagerChannel/461&quot;&gt;https://t.me/AppManagerChannel/461&lt;/a&gt;&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Why do certain apps have no internet permissions while they apparently connect to the internet?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;They are using a separate provider application. This is true for a lot of applications that use FCM/UnifiedPush protocols to provide notifications (in which case they are either using Google Play Services or a UnifiedPush client). Large software vendors also do something similar: Gemini, for example, doesn’t have an internet permission because it does all the API calls via the Google app.&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Why do certain apps connecting to the internet despite blocking its internet permission?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Again, they might be using a different provider. This is especially true for push notifications for the exact same reason above. This might actually be a good thing if it is solely used for push notifications as you do not miss out on the notifications even after blocking the internet connection. However, this also means telemetry may also be delivered via another app (e.g., Google Play Services). This is why these UID-backed firewall are often not enough (and as some of you know, I often criticize these firewall technology). An effective firewall would be the one that blocks the tracker URLs altogether: personalDNSfilter is one such tool, which is also very lightweight.&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;How about other firewall technologies?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The backend I have developed to enable this “permission overlay” can be utilized to add traditional ip-tables style blocking (requires root), net policy-based blocking (supported by Lineage OS), and VPN-based blocking. VPN-based blocking is probably unsuitable for App Manager, and even if it is implemented, we need to take into account my own criticisms about the VPNs: URL based blocking alongside regular app-specific blocking and support for actual VPN configurations or proxies.&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>How to write the perfect function</title>
    <link>https://unclassi.fyi/blog/notes/how-to-write-the-perfect-function/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/how-to-write-the-perfect-function/</guid>
    <pubDate>Sun, 23 Aug 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;For humans, by humans. But honestly, his suggestions are really good. Try them out in your job.&lt;/p&gt;&lt;p&gt;No tl;dr, just watch: &lt;a href=&quot;https://m.youtube.com/watch?v=2OMRWPOSw9s&quot;&gt;https://m.youtube.com/watch?v=2OMRWPOSw9s&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A question for yourself after you finished watching it:&lt;/strong&gt;&lt;br&gt;
What type of function have you always written - honest or dishonest? And will you change it?&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Colors immune to night shift</title>
    <link>https://unclassi.fyi/blog/notes/night-shift-immune-colors/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/night-shift-immune-colors/</guid>
    <pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;A specially made colorscheme, that doesn&amp;#039;t bleed or fade even when you use extreme night shift  (the &amp;quot;warm&amp;quot; color tint you use).&lt;/p&gt;&lt;p&gt;Ember – Redshift safe color palettes: &lt;a href=&quot;https://github.com/carpdiem/ember&quot;&gt;https://github.com/carpdiem/ember&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That’s a… surprisingly deep question. I’m actually a physicist by background first, so I got my start doing waaayyy too many calculations with blackbody and emissions spectra.&lt;br&gt;
Then, back in 2010, when I was just getting into startups, I spent two weeks straight at Powell’s in Portland reading through their graphic design section.&lt;br&gt;
After that, I never got very far away from light or perception… AR/VR -&amp;gt; graphics -&amp;gt; silicon photonics -&amp;gt; physical AI (now).&lt;br&gt;
I’m still very much learning, but if you like this stuff and want to learn more yourself there’s a couple sources I can recommend:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Interaction of Color, by Josef Albers. Amazing book, but you really want to get a physical copy.&lt;/li&gt;
&lt;li&gt;I really like this talk from SciPy 2015 to get a sense of how people work with and talk about color maps in practice: &lt;a href=&quot;https://www.youtube.com/watch?v=xAoljeRJ3lU&quot;&gt;https://www.youtube.com/watch?v=xAoljeRJ3lU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;This is a really, really thorough (and beautifully illustrated) article on what color spaces are: &lt;a href=&quot;https://www.makingsoftware.com/chapters/color-spaces-models-and-gamuts&quot;&gt;https://www.makingsoftware.com/chapters/color-spaces-models-and-gamuts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And last, I wrote a very technical blog post a few years back, if you want to see some math on a bunch of this: &lt;a href=&quot;https://www.usuallypragmatic.com/projects/Generating-Color-Temperature-Equivalent-Light-with-RGB-LEDs.html&quot;&gt;https://www.usuallypragmatic.com/projects/Generating-Color-Temperature-Equivalent-Light-with-RGB-LEDs.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;discussion: &lt;a href=&quot;https://news.ycombinator.com/item?id=49307601&quot;&gt;https://news.ycombinator.com/item?id=49307601&lt;/a&gt;&lt;/p&gt;
</description>
    <category>customization</category>
  </item>
<item>
    <title>DRAM unlock nerd stuff</title>
    <link>https://unclassi.fyi/blog/notes/unscrambling-dram/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/unscrambling-dram/</guid>
    <pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Stripping out security layers behind DRAM memory allocation&lt;/p&gt;&lt;p&gt;Despite having all this, we still see exploits like &lt;code&gt;use after free&lt;/code&gt; in 2026. That raises a question - do they really matter or not?&lt;/p&gt;
&lt;p&gt;They do, but not when you pass an unsanitised string into &lt;code&gt;eval()&lt;/code&gt;, then nothing can save you. Typically those data pages have &lt;code&gt;NX&lt;/code&gt; (no execute), &lt;code&gt;W^X&lt;/code&gt; (either write or execute, not both) flags set, but copying it to &lt;code&gt;eval()&lt;/code&gt; means you’ll run the bytes anyway (command injection)…&lt;/p&gt;
&lt;p&gt;Broadly, security measures enable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;restricting access &amp;amp; execution of user land page files (&lt;code&gt;SMAP&lt;/code&gt;, &lt;code&gt;SMEP&lt;/code&gt; - supervisor mode access / execution prevention)&lt;/li&gt;
&lt;li&gt;concealing the actual mem addresses even to the same process running in the same memory space (to avoid copying of data through a compromised part from same process)&lt;/li&gt;
&lt;li&gt;isolation of memory resources &amp;amp; translation layers (the other party doesn’t even know whether a resource exists or not, let alone guess)&lt;/li&gt;
&lt;li&gt;prevent impersonation (like devices copying data through &lt;code&gt;DMA&lt;/code&gt; (direct memory access), by acting like one).&lt;/li&gt;
&lt;li&gt;more hardcore restrictions (data that is only visible to &lt;code&gt;ring -2&lt;/code&gt;, 2 level below kernel’s &lt;code&gt;ring 0&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;cryptographic trust (to prevent hw exploits, and runtime system tampering)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cache mechanisms in place before reading a single bit from the DRAM (ordered, assume everything misses) &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a aria-label=&quot;Read footnote 1&quot; href=&quot;https://unclassi.fyi/blog/notes/unscrambling-dram/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;TLB&lt;/code&gt; translation buffer (virtual address -&amp;gt; physical address mapping + permissions)&lt;/li&gt;
&lt;li&gt;walks 4 levels of pages (&lt;code&gt;PML4&lt;/code&gt;, &lt;code&gt;PDPT&lt;/code&gt;, &lt;code&gt;PD&lt;/code&gt;, &lt;code&gt;PT&lt;/code&gt;) &lt;span class=&quot;spoiler&quot; data-spoiler&gt;&lt;span class=&quot;spoiler-content&quot;&gt;+ &lt;code&gt;LA57&lt;/code&gt; (5th)&lt;/span&gt;&lt;/span&gt;, and finds a pointer to top-level page table addresses in (&lt;code&gt;CR3&lt;/code&gt;) register. And the corresponding frame in CPU’s &lt;code&gt;SRAM&lt;/code&gt; cache (dedicated &lt;code&gt;SRAM&lt;/code&gt; cache to store these page tables, not the same as the cache from next point).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;L1&lt;/code&gt;, &lt;code&gt;L2&lt;/code&gt;, &lt;code&gt;L3&lt;/code&gt;, &lt;code&gt;LLC&lt;/code&gt; (last level) caches&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you do not want any of that, and wish to have a straight conversation with DRAM directly, follow &lt;a href=&quot;https://github.com/xoreaxeaxeax/skitter-creek-bath-salts&quot;&gt;https://github.com/xoreaxeaxeax/skitter-creek-bath-salts&lt;/a&gt;&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; aria-label=&quot;Footnotes&quot;&gt;
&lt;h2 class=&quot;footnotes-title&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;based on my understanding, I’m not an expert in this topic so please cross check with actual resources. &lt;a aria-label=&quot;Return to reference for footnote 1&quot; href=&quot;https://unclassi.fyi/blog/notes/unscrambling-dram/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Best source to learn pathfinding</title>
    <link>https://unclassi.fyi/blog/notes/best-source-to-learn-pathfinding/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/best-source-to-learn-pathfinding/</guid>
    <pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;A set of interactive example, to learn path finding. Really well made resource.&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;I learned about this technique in 2007, then tried writing it up in 2015. I realized that I didn’t understand it enough to be able to explain it. I studied it off and on in 2016, 2018, 2019, 2022, 2024, and 2026. I abandoned and restarted this page many times. And by 2026 I think I understand it well enough to write this page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.redblobgames.com/pathfinding/heuristics/differential.html&quot;&gt;https://www.redblobgames.com/pathfinding/heuristics/differential.html&lt;/a&gt;&lt;/p&gt;
</description>
    <category>algorithm</category>
  </item>
<item>
    <title>Do this on your phone if you have root</title>
    <link>https://unclassi.fyi/blog/notes/andriod-better-ram-management/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/andriod-better-ram-management/</guid>
    <pubDate>Sun, 26 Jul 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Just prevent your android os from killing applications overnight.&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Do you have a completely satisfying amount of RAM on your Android device? And yet still experience losing your app state overnight, as it’s now missing in recents? Be it a photo editor or incognito mode in a browser?&lt;br&gt;
Turns out that in AOSP defaults, you’ll only be left with 5 tasks (or one less, if to trust some reports) after 6 hours of last use. If a TikToker commits to a test by clicking each app on home screen one by one, all of these tasks will stay in recents. But if you want to go back to something from a day or two ago, it can be missing. Now you know why.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The culprit has a simple name: &lt;code&gt;config_minNumVisibleRecentTasks&lt;/code&gt;. It’s set to 5. Set to it to 30 and you’ll live a happier life. A tiny bit of RAM will be used to keep the task state and its visual snapshot, while the processes will still be treated exactly the same. You’ll just get to keep the state. Works best if combined with LMO’s &lt;a href=&quot;https://t.me/TadiBlog/245&quot;&gt;transistor mode&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;source: &lt;a href=&quot;https://t.me/TadiBlog/997&quot;&gt;https://t.me/TadiBlog/997&lt;/a&gt;&lt;/p&gt;
</description>
    <category>customization</category>
  </item>
<item>
    <title>Pick a random book</title>
    <link>https://unclassi.fyi/blog/notes/pick-a-random-book/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/pick-a-random-book/</guid>
    <pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;A decent collection of non-fictional books, decently categorized too.&lt;/p&gt;&lt;p&gt;Author used to roam around in library and help people arranging the books in shelf. Super annoyed by this job, out of boredom one day he started randomly reading pages just before the moment he put them in rack. Suddenly it was fun to know a thing or two about random topics and genre: &lt;a href=&quot;https://resobscura.substack.com/p/quality-non-fiction-books-are-the&quot;&gt;https://resobscura.substack.com/p/quality-non-fiction-books-are-the&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My picks from &lt;a href=&quot;https://book-prize-index.vercel.app/&quot;&gt;book price index&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stay True&lt;/li&gt;
&lt;li&gt;How to Say Babylon&lt;/li&gt;
&lt;li&gt;Bad Blood&lt;/li&gt;
&lt;li&gt;Somewhere Towards the End&lt;/li&gt;
&lt;li&gt;The Travels of a T-Shirt in the Global Economy&lt;/li&gt;
&lt;li&gt;Far from the Tree&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Also check: &lt;a href=&quot;/blog/notes/book-recommendations/&quot;&gt;Book Recommendations&lt;/a&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Cashflow from your pockets</title>
    <link>https://unclassi.fyi/blog/notes/managing-finance-at-home/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/managing-finance-at-home/</guid>
    <pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Really interesting project, centralized hub to manage personal finance... gotta try it out.&lt;/p&gt;&lt;p&gt;Visualizations are looking really neat, I wish my banks are supported… sadly no first party integrations available yet… But still going to give it a shot, they support importing bank statements from pdfs and csvs. I can prepare that&lt;/p&gt;
&lt;p&gt;project: &lt;a href=&quot;https://github.com/we-promise/sure&quot;&gt;https://github.com/we-promise/sure&lt;/a&gt;&lt;/p&gt;
</description>
    <category>homelab</category>
  </item>
<item>
    <title>Learn x in y minutes</title>
    <link>https://unclassi.fyi/blog/notes/learn-x-in-y-minutes/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/learn-x-in-y-minutes/</guid>
    <pubDate>Mon, 15 Jun 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Learning javascripts in minutes, explore other topics too&lt;/p&gt;&lt;p&gt;Learn javascript in y minutes: &lt;a href=&quot;https://learnxinyminutes.com/javascript/&quot;&gt;https://learnxinyminutes.com/javascript/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Find public events</title>
    <link>https://unclassi.fyi/blog/notes/find-public-events/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/find-public-events/</guid>
    <pubDate>Wed, 10 Jun 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;I was always interesting in knowing what events happen inside the big buildings and holiday inns.&lt;/p&gt;&lt;p&gt;Site that aggregates public events happening in various places:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://allevents.in/&quot;&gt;https://allevents.in/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.eventbrite.com/&quot;&gt;https://www.eventbrite.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://10times.com/venues&quot;&gt;https://10times.com/venues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eventseeker.com/&quot;&gt;https://eventseeker.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;music specifically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bandsintown.com/&quot;&gt;https://www.bandsintown.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Navigate without mouse</title>
    <link>https://unclassi.fyi/blog/notes/no-mouse-navigation/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/no-mouse-navigation/</guid>
    <pubDate>Fri, 05 Jun 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;If you install this, use this for 2 weeks straight, no matter what. And then decide.&lt;/p&gt;&lt;p&gt;I assure you, please give it a try for 2 weeks. Just 2 weeks. Then you cannot stop. Navigating across screen becomes so natural and intuitive, it almost feels like muscle memory. Opening menu bars, selecting text, taking screenshots - you’ll be able to do everything in near instant. It is almost like the difference between talking and typing. You can talk to your computer through thoughts directly, without translating them to swipes and figuring out where the mouse pointer is.&lt;/p&gt;
&lt;p&gt;demo: &lt;a href=&quot;https://m.youtube.com/watch?v=kaizkf_lXPI&quot;&gt;https://m.youtube.com/watch?v=kaizkf_lXPI&lt;/a&gt;&lt;br&gt;
site: &lt;a href=&quot;https://mouseless.click/&quot;&gt;https://mouseless.click/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>customization</category>
  </item>
<item>
    <title>Envelope Encryption</title>
    <link>https://unclassi.fyi/blog/notes/envelope-encryption/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/envelope-encryption/</guid>
    <pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Learn about envelop encryption, data encryption at rest&lt;/p&gt;&lt;p&gt;Best resource I’ve read to understand how KEK (key encryption key), and DEK (data encryption key) work together. The site also explains some common pitfalls, key rotation best practices, and insights on certification requirements (like PCI DSS).&lt;/p&gt;
&lt;p&gt;site: &lt;a href=&quot;https://devsecopsschool.com/blog/envelope-encryption/#quick-definition-3060-words&quot;&gt;https://devsecopsschool.com/blog/envelope-encryption/#quick-definition-3060-words&lt;/a&gt;&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Interesting job listings from interesting companies</title>
    <link>https://unclassi.fyi/blog/notes/job-listing/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/job-listing/</guid>
    <pubDate>Fri, 29 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Companies that have unconventional ways of hiring, and you might like it.&lt;/p&gt;&lt;p&gt;Places to search interesting companies from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/poteto/hiring-without-whiteboards&quot;&gt;https://github.com/poteto/hiring-without-whiteboards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wellfound.com/candidates/overview&quot;&gt;https://wellfound.com/candidates/overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jobs.ashbyhq.com/g2i&quot;&gt;https://jobs.ashbyhq.com/g2i&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Wikipedia doomscroller</title>
    <link>https://unclassi.fyi/blog/notes/doomscroll-wikipedia/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/doomscroll-wikipedia/</guid>
    <pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Atleast this form of doomscrolling does not smelt your brain alive&lt;/p&gt;&lt;p&gt;Wikipedia Doomscroller: &lt;a href=&quot;https://xikipedia.org/&quot;&gt;https://xikipedia.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Takes around 40MB, works offline… Wait, actually why this is still a site? Why nobody had made an app yet? (If you make one pls lmk, I’d love to try it. Also would love to see what you’ve added on top of it!)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: Do not get scared of the loading screen that shows up everytime - some kind of indexing happening. It does not download wikipedia data everytime on launch. So, no need to worry.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Evaluation Criteria</title>
    <link>https://unclassi.fyi/blog/notes/vocal-evaluation-criteria/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/vocal-evaluation-criteria/</guid>
    <pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Take a transcript of your own voice and evaluate.&lt;/p&gt;&lt;p&gt;Use these items to create a prompt. it’s going to be nothing but a fun practice session.&lt;/p&gt;
&lt;h3&gt;Metaphor Mania&lt;/h3&gt;
&lt;p&gt;Tags: Lateral Thinking, Conciseness, Agility&lt;br&gt;
Quickly build analogies without letting the pressure get to you&lt;br&gt;
Button: Start Practising&lt;/p&gt;
&lt;h3&gt;Tell a Story&lt;/h3&gt;
&lt;p&gt;Tags: Articulation, Structure, Lateral Thinking&lt;br&gt;
Maintain your train of thought with plot twists along the way&lt;br&gt;
Button: Start Practising&lt;/p&gt;
&lt;h3&gt;No Filler&lt;/h3&gt;
&lt;p&gt;Tags: Filler Words, Articulation, Structure&lt;br&gt;
Speak without using filler words like ‘um’, ‘like’, and ‘so’&lt;br&gt;
Button: Start Practising&lt;/p&gt;
&lt;h3&gt;Storyteller&lt;/h3&gt;
&lt;p&gt;Tags: Articulation, Structure, Lateral Thinking&lt;br&gt;
Tell a creative story with the help of your AI co-author&lt;br&gt;
Button: Start Practising&lt;/p&gt;
&lt;p&gt;Source: &lt;a href=&quot;https://yoodli.ai/blog/5-public-speaking-games-to-try&quot;&gt;Yoodli.ai&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can use the meeting option from &lt;a href=&quot;https://github.com/peteonrails/voxtype/&quot;&gt;voxtype&lt;/a&gt; - best voice-to-text tool I’ve ever used in linux &amp;amp; mac.&lt;br&gt;
Also, checkout &lt;a href=&quot;https://github.com/nijuyonkadesu/emphasis&quot;&gt;stressmark&lt;/a&gt; - A terminal tool I created to practice speaking with proper intonation. (you can also export pdfs / html with all highlights)&lt;/p&gt;
</description>
    <category>presentation</category>
  </item>
<item>
    <title>LLM tokens speed simulator</title>
    <link>https://unclassi.fyi/blog/notes/llm-tokens-speed-simulator/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/llm-tokens-speed-simulator/</guid>
    <pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;LLM tok/s can cross 10k+ in near future, so just imagine&lt;/p&gt;&lt;p&gt;Looking forward to the day when Cerebras x OpenAI happens. Can’t wait to use agents at a wallet draining speed of ~1000tok/s…&lt;/p&gt;
&lt;p&gt;LLM token visualiser (speed): &lt;a href=&quot;https://mikeveerman.github.io/tokenspeed&quot;&gt;https://mikeveerman.github.io/tokenspeed&lt;/a&gt;&lt;/p&gt;
</description>
    <category>sneak</category>
  </item>
<item>
    <title>Creating redis</title>
    <link>https://unclassi.fyi/blog/notes/your-own-redis/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/your-own-redis/</guid>
    <pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Creating your own redis from scratch.&lt;/p&gt;&lt;p&gt;Typa stuff ppl ask in openai interview btw. &lt;a href=&quot;https://build-your-own.org/redis/&quot;&gt;https://build-your-own.org/redis/&lt;/a&gt; Do me a favour and build the same thing in another language. (Please never ever touch &lt;code&gt;C++&lt;/code&gt; ever again. Reason? look at their &lt;a href=&quot;https://www.reddit.com/r/196/comments/sur1ph/mascot/&quot;&gt;official mascot&lt;/a&gt;)&lt;/p&gt;
</description>
    <category>algorithm</category>
  </item>
<item>
    <title>Cheapest VPS?</title>
    <link>https://unclassi.fyi/blog/notes/found-a-cheap-vps/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/found-a-cheap-vps/</guid>
    <pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Maybe worth a try?&lt;/p&gt;&lt;p&gt;Cheapest VPS I found &lt;a href=&quot;https://tierhive.com/r/AD3AFC1F50FF&quot;&gt;https://tierhive.com/r/AD3AFC1F50FF&lt;/a&gt; &lt;s&gt;(yes affiliated link)&lt;/s&gt;.&lt;/p&gt;
</description>
    <category>sneak</category>
  </item>
<item>
    <title>Just fucking use go</title>
    <link>https://unclassi.fyi/blog/notes/just-fucking-use-go/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/just-fucking-use-go/</guid>
    <pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Just use golang. dot.&lt;/p&gt;&lt;p&gt;It is go today, but it will be soon become &lt;a href=&quot;https://jaiprogramming.com/&quot;&gt;Jai&lt;/a&gt; or &lt;a href=&quot;https://odin-lang.org/&quot;&gt;Odin&lt;/a&gt;. Please never ever touch &lt;code&gt;C++&lt;/code&gt;, I pray you.&lt;/p&gt;
&lt;p&gt;site: &lt;a href=&quot;https://blainsmith.com/articles/just-fucking-use-go/&quot;&gt;https://blainsmith.com/articles/just-fucking-use-go/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>Salary compensation insights</title>
    <link>https://unclassi.fyi/blog/notes/what-ppl-flaunting-in-leetcode/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/what-ppl-flaunting-in-leetcode/</guid>
    <pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Absurd numbers, yet companies do pay them.&lt;/p&gt;&lt;p&gt;Salary of devs scraped from leetcode discuss page:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://anugrahsinghal.github.io/LeetComp/&quot;&gt;https://anugrahsinghal.github.io/LeetComp/&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://0xku.github.io/leetcode-compensation/&quot;&gt;https://0xku.github.io/leetcode-compensation/&lt;/a&gt; (version 2, actively maintained)&lt;/p&gt;
&lt;p&gt;Now, use these numbers with tactics in &lt;a href=&quot;/blog/notes/10-rules-for-negotiating-offer/&quot;&gt;10 rules for negotiating offer&lt;/a&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Websockets 101</title>
    <link>https://unclassi.fyi/blog/notes/websockets-101/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/websockets-101/</guid>
    <pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;From bidirectional echoserver to building a robust multi-player game.&lt;/p&gt;&lt;p&gt;omg claude (I’ll share the link once it’s ready) &lt;a href=&quot;https://claude.ai/share/ede94c96-26f1-4c1e-872d-74ce5c09364f&quot;&gt;https://claude.ai/share/ede94c96-26f1-4c1e-872d-74ce5c09364f&lt;/a&gt;. if you can’t see it for somereason, here’s a breakdown:&lt;/p&gt;
&lt;h3&gt;Phase 1 — WebSocket Foundations (~5 hrs)&lt;/h3&gt;
&lt;h4&gt;1.1 How WebSockets work under the hood (1.5 hrs)&lt;/h4&gt;
&lt;p&gt;WebSocket is a full-duplex, persistent TCP connection initiated via an HTTP/1.1 Upgrade handshake. Understand the 101 Switching Protocols response, the Sec-WebSocket-Key/Accept handshake, and how frames are structured (FIN, RSV, opcode, MASK, payload length, masking key).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; core protocol&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; WebSocket has nothing to do with HTTP after the handshake. CORS does NOT apply — the server must validate the &lt;code&gt;Origin&lt;/code&gt; header manually.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6455&quot;&gt;RFC 6455 (the spec)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API&quot;&gt;MDN: WebSockets API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hpbn.co/websocket/&quot;&gt;High Performance Browser Networking ch.17 (free)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;1.2 Browser WebSocket API (1 hr)&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;new WebSocket(url)&lt;/code&gt;, &lt;code&gt;readyState&lt;/code&gt;, &lt;code&gt;onopen&lt;/code&gt;/&lt;code&gt;onmessage&lt;/code&gt;/&lt;code&gt;onerror&lt;/code&gt;/&lt;code&gt;onclose&lt;/code&gt; events, &lt;code&gt;send()&lt;/code&gt;, &lt;code&gt;close(code, reason)&lt;/code&gt;. Sending both text and binary (&lt;code&gt;ArrayBuffer&lt;/code&gt; / &lt;code&gt;Blob&lt;/code&gt;). Inspecting frames in DevTools Network tab.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; browser&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Always set &lt;code&gt;binaryType = &#039;arraybuffer&#039;&lt;/code&gt; if you’re sending binary — the default &lt;code&gt;&#039;blob&#039;&lt;/code&gt; is awkward to work with in game loops.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebSocket&quot;&gt;MDN WebSocket reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javascript.info/websocket&quot;&gt;javascript.info: WebSocket&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;1.3 Opcodes, frames &amp;amp; control frames (1 hr)&lt;/h4&gt;
&lt;p&gt;Text (&lt;code&gt;0x1&lt;/code&gt;) vs Binary (&lt;code&gt;0x2&lt;/code&gt;) vs Continuation (&lt;code&gt;0x0&lt;/code&gt;) frames. Control frames: Close (&lt;code&gt;0x8&lt;/code&gt;), Ping (&lt;code&gt;0x9&lt;/code&gt;), Pong (&lt;code&gt;0xA&lt;/code&gt;). Fragmentation — splitting large messages across multiple frames. Close codes: 1000 normal, 1001 going away, 1006 abnormal, 1011 server error.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; core protocol&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Client frames MUST be masked. Server frames must NOT be masked. Get this wrong and the peer drops the connection immediately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6455#section-5&quot;&gt;RFC 6455 §5 — Data Framing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc6455#section-7.4&quot;&gt;Close codes reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;1.4 ws vs wss — TLS in production (0.5 hrs)&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;wss://&lt;/code&gt; is WebSocket over TLS. Always use &lt;code&gt;wss&lt;/code&gt; in production. Your load balancer terminates TLS and forwards plain &lt;code&gt;ws://&lt;/code&gt; internally. Browsers block mixed content (&lt;code&gt;ws://&lt;/code&gt; on an &lt;code&gt;https://&lt;/code&gt; page).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; security&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Proxies that don’t understand WebSocket buffer the connection and break it. You MUST configure them to handle the &lt;code&gt;Upgrade&lt;/code&gt; header and disable request buffering.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nginx.org/en/docs/http/websocket.html&quot;&gt;nginx WebSocket proxying&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;1.5 Ping / Pong heartbeats (1 hr)&lt;/h4&gt;
&lt;p&gt;TCP connections silently die without data flow. The server should send Ping frames periodically (~30s) and disconnect clients that don’t Pong back within a timeout. Client-side application-level heartbeats are also common in game servers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; reliability&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; NATs, firewalls, and mobile networks silently kill idle connections. Without heartbeats you’ll have thousands of zombie connections that appear open server-side but are dead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/websockets/ws#how-to-detect-and-close-broken-connections&quot;&gt;ws: detecting broken connections&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 2 — Server-Side Implementation (~6 hrs)&lt;/h3&gt;
&lt;h4&gt;2.1 Choosing a WebSocket library (1 hr)&lt;/h4&gt;
&lt;p&gt;Node.js: &lt;code&gt;ws&lt;/code&gt; (bare, fast), &lt;code&gt;socket.io&lt;/code&gt; (batteries included), &lt;code&gt;uWebSockets.js&lt;/code&gt; (C++ backed, highest perf). Go: Gorilla WebSocket, nhooyr/websocket. Rust: tokio-tungstenite. For a game server, prefer raw &lt;code&gt;ws&lt;/code&gt; or &lt;code&gt;uWebSockets.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; Node.js, Go, Rust&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/websockets/ws&quot;&gt;ws (npm)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uNetworking/uWebSockets.js&quot;&gt;uWebSockets.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gorilla/websocket&quot;&gt;Gorilla WebSocket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://socket.io/docs/v4/&quot;&gt;socket.io docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;2.2 Connection lifecycle management (1 hr)&lt;/h4&gt;
&lt;p&gt;Tracking connected clients, associating metadata (user ID, room, session) with each connection object. Clean teardown on close — removing from maps, notifying other players. Handling the &lt;code&gt;error&lt;/code&gt; event (which precedes &lt;code&gt;close&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; server&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; If you store client state in a &lt;code&gt;Map&lt;/code&gt; and forget to delete on &lt;code&gt;close&lt;/code&gt;/&lt;code&gt;error&lt;/code&gt;, you have a memory leak that grows forever. Always clean up in BOTH &lt;code&gt;onclose&lt;/code&gt; and &lt;code&gt;onerror&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/websockets/ws#server-example&quot;&gt;ws server example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;2.3 Room / channel architecture (2 hrs)&lt;/h4&gt;
&lt;p&gt;Model rooms as &lt;code&gt;Set&lt;/code&gt;s of WebSocket connections keyed by room ID. Broadcast to a room by iterating the Set and sending to each client (checking &lt;code&gt;readyState === OPEN&lt;/code&gt;). Design a message protocol with a &lt;code&gt;type&lt;/code&gt; field, e.g. &lt;code&gt;{ type: &#039;PLAYER_MOVE&#039;, payload: {...} }&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; architecture&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use a discriminated union message protocol: &lt;code&gt;{ type: &#039;PLAYER_MOVE&#039;, payload: {...} }&lt;/code&gt;. This scales cleanly and lets you add message types without breaking existing handlers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://socket.io/docs/v4/rooms/&quot;&gt;socket.io rooms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://msgpack.org/&quot;&gt;MessagePack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://protobuf.dev/&quot;&gt;Protobuf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;2.4 Backpressure handling (1 hr)&lt;/h4&gt;
&lt;p&gt;If your server sends data faster than a slow client can consume, the send buffer fills up. Check &lt;code&gt;ws.bufferedAmount&lt;/code&gt; before sending, or handle the &lt;code&gt;drain&lt;/code&gt; event. &lt;code&gt;uWebSockets.js&lt;/code&gt; has explicit backpressure callbacks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; reliability&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Ignoring backpressure in a game server means slow clients get their receive buffer filled, causing lag and eventual disconnection.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uNetworking/uWebSockets.js/blob/master/examples/Backpressure.js&quot;&gt;uWebSockets backpressure example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;2.5 Message serialization strategies (1 hr)&lt;/h4&gt;
&lt;p&gt;JSON is easy but slow for high-frequency game messages. MessagePack is JSON-equivalent but binary and 2–3x smaller. FlatBuffers/Protobuf require schema compilation but are 5–10x faster. Benchmark early — serialization is often the bottleneck.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; performance&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://flatbuffers.dev/&quot;&gt;FlatBuffers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/protobufjs/protobuf.js&quot;&gt;Protobuf.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kawanet/msgpack-lite#benchmark&quot;&gt;msgpack-lite benchmarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 3 — Footguns &amp;amp; Security (~5 hrs)&lt;/h3&gt;
&lt;h4&gt;3.1 Origin validation (0.5 hrs)&lt;/h4&gt;
&lt;p&gt;WebSocket connections from any origin succeed by default — there is no CORS. Any website can connect to your &lt;code&gt;ws://&lt;/code&gt; server. Always validate the &lt;code&gt;Origin&lt;/code&gt; header during the handshake.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; security ⚠️&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; This is the #1 most missed WebSocket security issue. A malicious site can CSRF your WebSocket endpoint unless you validate &lt;code&gt;Origin&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/WebSockets_Cheat_Sheet.html&quot;&gt;OWASP WebSocket cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;3.2 Authentication over WebSocket (1 hr)&lt;/h4&gt;
&lt;p&gt;Cookies are sent on the initial HTTP Upgrade request, so cookie-based auth works. For token auth: send the JWT in the first message after connect (not as a query param — those appear in server logs). Validate auth before sending any game state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; security ⚠️&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Never trust anything from the client. Re-validate permissions on every sensitive action (joining rooms, game moves), not just on connect.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/WebSockets_Cheat_Sheet.html#authentication&quot;&gt;OWASP: WebSocket authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;3.3 Rate limiting &amp;amp; DoS protection (1 hr)&lt;/h4&gt;
&lt;p&gt;Limit connection rate per IP, max connections per user, and max message rate per connection. Track message counts in a sliding window. Disconnect violators. Set max message size (&lt;code&gt;ws&lt;/code&gt;: &lt;code&gt;maxPayload&lt;/code&gt; option).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; security ⚠️, reliability&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; A single client can open hundreds of connections or flood your server with millions of tiny messages. Without rate limiting, your server is trivially DoS-able.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback&quot;&gt;ws maxPayload option&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;3.4 Input validation &amp;amp; message schema (1 hr)&lt;/h4&gt;
&lt;p&gt;Every message from a client is untrusted user input. Validate message type, payload shape, and field ranges before acting. Use &lt;code&gt;zod&lt;/code&gt; or &lt;code&gt;ajv&lt;/code&gt; on the server. Reject and log malformed messages — don’t crash.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; security ⚠️&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Treat WebSocket messages exactly like HTTP request bodies: validate every field, sanitize strings, check numeric ranges, and never trust client-sent identifiers without server-side verification.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zod.dev/&quot;&gt;zod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ajv.js.org/&quot;&gt;ajv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;3.5 SSL termination &amp;amp; proxy pitfalls (1.5 hrs)&lt;/h4&gt;
&lt;p&gt;nginx must set &lt;code&gt;proxy_http_version 1.1&lt;/code&gt;, &lt;code&gt;proxy_set_header Upgrade&lt;/code&gt;, and &lt;code&gt;proxy_set_header Connection &#039;upgrade&#039;&lt;/code&gt;. Disable &lt;code&gt;proxy_buffering&lt;/code&gt; and raise &lt;code&gt;proxy_read_timeout&lt;/code&gt; above 60s. HAProxy needs correct tunnel mode on the WS backend.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ops&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; &lt;code&gt;proxy_read_timeout 60s&lt;/code&gt; is nginx’s default — it silently closes WebSocket connections after 60 seconds of no data. Set to &lt;code&gt;3600s&lt;/code&gt; or higher in production.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nginx.org/en/docs/http/websocket.html&quot;&gt;nginx WebSocket proxy config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy&quot;&gt;HAProxy WebSocket guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 4 — Reconnection Strategies (~4 hrs)&lt;/h3&gt;
&lt;h4&gt;4.1 Exponential backoff with jitter (1 hr)&lt;/h4&gt;
&lt;p&gt;On disconnect, wait before reconnecting. Start at 1s, double each failure, cap at ~30s. Add ±20% random jitter to prevent thundering herd — thousands of clients don’t all reconnect at the same instant after a server restart.&lt;/p&gt;
&lt;p&gt;Formula: &lt;code&gt;delay = min(cap, base × 2^attempt) × (0.8 + random() × 0.4)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; reliability&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Implement in a &lt;code&gt;useWebSocket&lt;/code&gt; hook or &lt;code&gt;ReconnectingWebSocket&lt;/code&gt; wrapper class so every feature doesn’t re-implement it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/&quot;&gt;Exponential backoff — AWS blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pladaria/reconnecting-websocket&quot;&gt;reconnecting-websocket library&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;4.2 Client-side message queue during disconnect (1 hr)&lt;/h4&gt;
&lt;p&gt;Buffer messages that arrive while disconnected. On reconnect, flush the queue or send a full state sync. Cap queue size to prevent OOM. For game state, a full state sync snapshot is usually simpler and more correct than replaying all buffered actions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; reliability&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Unbounded queues during long disconnects can OOM the browser tab. Cap queue size and drop or summarize old messages.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://javascript.info/websocket#reconnection&quot;&gt;javascript.info reconnect pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;4.3 Session resumption &amp;amp; state recovery (2 hrs)&lt;/h4&gt;
&lt;p&gt;Issue a short-lived reconnect token on connect. On reconnect: client sends token → server restores session (room, game state, player position). Design a ‘catch-up’ snapshot mechanism to send current world state to a reconnecting player.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; architecture&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Design reconnection and state recovery from day 1. A player who drops for 5 seconds should rejoin seamlessly — not restart from a lobby.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://socket.io/docs/v4/connection-state-recovery/&quot;&gt;socket.io connection state recovery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 5 — Scaling WebSockets (Stateless Architecture) (~10 hrs)&lt;/h3&gt;
&lt;h4&gt;5.1 The statefulness problem (1 hr)&lt;/h4&gt;
&lt;p&gt;A WebSocket connection lives on exactly one server process. When you scale horizontally to N servers, a message for “room 42” must reach all connections in that room — which may span all N servers. This is the core scaling challenge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; core concept&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Naive horizontal scaling silently breaks broadcasting — messages only reach players connected to the same server instance. This is almost always the first bug in a multiplayer implementation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://socket.io/docs/v4/adapter/&quot;&gt;socket.io: why you need an adapter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;5.2 Pub/Sub fan-out with Redis (3 hrs)&lt;/h4&gt;
&lt;p&gt;Each server subscribes to a Redis channel per room. When server A receives a message for room 42, it publishes to Redis channel &lt;code&gt;room:42&lt;/code&gt;. All servers receive it and forward to their local connections. Use Redis Pub/Sub or Redis Streams.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; scaling, Redis&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; This is the industry-standard approach. &lt;code&gt;socket.io&lt;/code&gt; has &lt;code&gt;@socket.io/redis-adapter&lt;/code&gt;. With raw &lt;code&gt;ws&lt;/code&gt;, implement it yourself — it’s ~50 lines with &lt;code&gt;ioredis&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://redis.io/docs/manual/pubsub/&quot;&gt;Redis Pub/Sub docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://socket.io/docs/v4/redis-adapter/&quot;&gt;socket.io Redis adapter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/redis/ioredis&quot;&gt;ioredis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redis.io/docs/data-types/streams/&quot;&gt;Redis Streams&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;5.3 NATS &amp;amp; Kafka as alternatives (1.5 hrs)&lt;/h4&gt;
&lt;p&gt;NATS is purpose-built for high-throughput messaging with lower latency than Redis Pub/Sub — ideal for real-time game state. Kafka adds durability and replay but adds latency; better for matchmaking queues and event sourcing than live game state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; scaling&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.nats.io/&quot;&gt;NATS.io docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nats.io/use-cases/real-time-systems/&quot;&gt;NATS for real-time systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.confluent.io/patterns/event-sourcing/event-sourcing/&quot;&gt;Kafka event sourcing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;5.4 Sticky sessions (and why to avoid them) (0.5 hrs)&lt;/h4&gt;
&lt;p&gt;Sticky sessions pin a client to one server via IP hash or cookie. This works but distributes load unevenly, makes deployments painful, and doesn’t solve the fan-out problem. Use pub/sub instead. Sticky sessions are a crutch, not a solution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ⚠️ anti-pattern&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://socket.io/docs/v4/using-multiple-nodes/&quot;&gt;socket.io: using multiple nodes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;5.5 Dedicated WebSocket gateway pattern (2 hrs)&lt;/h4&gt;
&lt;p&gt;Separate your connection-holding layer (WS gateway) from your business logic layer. The gateway only handles connections + pub/sub routing. Business logic runs in stateless HTTP microservices. This is the pattern used at scale by Slack, Discord, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; architecture&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; This lets you scale compute-heavy game logic independently from the connection-holding layer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://discord.com/blog/how-discord-scaled-elixir-to-5-000-000-concurrent-users&quot;&gt;Discord: scaling to 5M concurrent users&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server/&quot;&gt;Cloudflare Durable Objects for WebSockets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;5.6 WebSocket hibernation — Cloudflare Durable Objects (1 hr)&lt;/h4&gt;
&lt;p&gt;Cloudflare Durable Objects can hibernate WebSocket connections to zero CPU when idle — the connection stays open but the process is evicted. On the next message, the process restores in microseconds. Compelling for game lobbies and presence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; serverless&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server/&quot;&gt;CF Durable Objects WS hibernation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.partykit.io/&quot;&gt;Partykit (built on Durable Objects)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;5.7 Load balancer configuration (1 hr)&lt;/h4&gt;
&lt;p&gt;AWS ALB: natively supports WebSockets. AWS NLB: lower latency, better for long-lived connections. nginx: &lt;code&gt;proxy_http_version 1.1&lt;/code&gt;, disable buffering, set long timeouts. HAProxy: balance by source IP only if needed; prefer pub/sub instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ops&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html&quot;&gt;AWS ALB WebSocket support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nginx.org/en/docs/http/websocket.html&quot;&gt;nginx upstream WS guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 6 — Production &amp;amp; Observability (~5 hrs)&lt;/h3&gt;
&lt;h4&gt;6.1 Metrics to track (1 hr)&lt;/h4&gt;
&lt;p&gt;Active connections, connection rate (new/sec), message throughput (in/out per sec), message size distribution, error rate, close code distribution (watch for 1006 = abnormal), round-trip ping latency, backpressure events, reconnect rate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; observability&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/siimon/prom-client&quot;&gt;prom-client (Node.js)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/&quot;&gt;Grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;6.2 Graceful shutdown (1 hr)&lt;/h4&gt;
&lt;p&gt;On SIGTERM: stop accepting new connections, send Close 1001 (going away) to all clients, wait for acknowledgment, drain, then exit. Coordinate with your load balancer to drain before killing. Gives reconnect logic time to find a new server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ops&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Footgun:&lt;/strong&gt; Hard-killing a WS server sends TCP RST packets — clients see abnormal close (1006). A graceful close lets your backoff reconnect logic work properly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/websockets/ws#how-to-detect-and-close-broken-connections&quot;&gt;ws graceful shutdown pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;6.3 Connection limits &amp;amp; resource management (1 hr)&lt;/h4&gt;
&lt;p&gt;Each WS connection uses a file descriptor. Raise &lt;code&gt;ulimit&lt;/code&gt; to 100k+ in &lt;code&gt;/etc/security/limits.conf&lt;/code&gt; and tune &lt;code&gt;net.core.somaxconn&lt;/code&gt;. Each Node.js connection uses ~50–100KB RAM. &lt;code&gt;uWebSockets.js&lt;/code&gt; can hold 1M+ connections per GB; &lt;code&gt;ws&lt;/code&gt; is closer to 10–50k.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ops&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; &lt;code&gt;uWebSockets.js&lt;/code&gt; can hold 1M+ connections in ~1GB RAM. Node.js &lt;code&gt;ws&lt;/code&gt; is closer to 10k–50k per GB. Design your instance sizing accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.linuxjournal.com/article/10267&quot;&gt;Linux file descriptor limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uNetworking/uWebSockets.js#benchmarks&quot;&gt;uWebSockets.js benchmarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;6.4 Structured logging (0.5 hrs)&lt;/h4&gt;
&lt;p&gt;Log: connect (userId, IP, userAgent), disconnect (userId, code, reason, duration), auth failures, rate limit hits. Use structured JSON logs with correlation IDs. Don’t log every message in production — you’ll drown in noise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; observability&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pinojs/pino&quot;&gt;pino — fast Node.js logger&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;6.5 Testing WebSocket servers (1.5 hrs)&lt;/h4&gt;
&lt;p&gt;Unit test message handlers with mock WS objects. Integration test with a real &lt;code&gt;ws.WebSocket&lt;/code&gt; client in Jest/Vitest. Load test with k6 (native WS support). Chaos test: kill servers mid-game, simulate slow clients, test reconnect recovery.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; testing&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/docs/k6/latest/using-k6/protocols/websockets/&quot;&gt;k6 WebSocket load testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.artillery.io/docs/reference/engines/websocket&quot;&gt;Artillery WebSocket testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 7 — Multiplayer Game Architecture (~8 hrs)&lt;/h3&gt;
&lt;h4&gt;7.1 Authoritative server model (2 hrs)&lt;/h4&gt;
&lt;p&gt;The server is the single source of truth for game state. Clients send intents (&lt;code&gt;MOVE_LEFT&lt;/code&gt;, &lt;code&gt;FIRE&lt;/code&gt;), never positions. The server validates, computes new state, and broadcasts. Prevents cheating — a client cannot lie about its position.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; game architecture&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; This is non-negotiable for a competitive game. Client-authoritative games are trivially hackable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gafferongames.com/post/what_every_programmer_needs_to_know_about_game_networking/&quot;&gt;Gaffer on Games: What Every Programmer Needs To Know About Game Networking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gafferongames.com/post/networked_physics_2004/&quot;&gt;Gaffer on Games: Networked Physics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;7.2 Client-side prediction &amp;amp; server reconciliation (2 hrs)&lt;/h4&gt;
&lt;p&gt;Apply the player’s own input immediately (prediction) so movement feels responsive. Server processes input and sends authoritative state. If client and server diverge, the client snaps to server state (reconciliation). Hides network latency from the player.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; game architecture&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gabrielgambetta.com/client-server-game-architecture.html&quot;&gt;Gabriel Gambetta: Fast-Paced Multiplayer (4-part series)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gabrielgambetta.com/client-side-prediction-server-reconciliation.html&quot;&gt;Part 2: Client-Side Prediction &amp;amp; Server Reconciliation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;7.3 Entity interpolation &amp;amp; lag compensation (1.5 hrs)&lt;/h4&gt;
&lt;p&gt;For OTHER players, interpolate between the two most recent known positions (adds ~100ms delay but removes jitter). For hit detection, lag compensation rolls back world state to what the shooter saw when they fired.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; game architecture&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gabrielgambetta.com/entity-interpolation.html&quot;&gt;Gabriel Gambetta: Entity Interpolation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.valvesoftware.com/wiki/Lag_compensation&quot;&gt;Valve developer wiki: Lag compensation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;7.4 Delta compression for state updates (1 hr)&lt;/h4&gt;
&lt;p&gt;Instead of broadcasting full world state every tick, send only what changed since the last acknowledged state. Track per-client what they’ve seen (sequence numbers). Can reduce bandwidth by 80–95% in a large game world.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; performance&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gafferongames.com/post/state_synchronization/&quot;&gt;Gaffer on Games: State Synchronization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gabrielgambetta.com/client-side-prediction-live-demo.html&quot;&gt;Gabriel Gambetta: live demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;7.5 Tick rate &amp;amp; game loop design (1.5 hrs)&lt;/h4&gt;
&lt;p&gt;Server-side game loop runs at a fixed tick rate (20Hz–64Hz). Each tick: collect inputs, advance simulation, broadcast delta. Decoupled from client framerate. Higher tick rate = better responsiveness but more CPU and bandwidth. Start at 20Hz, tune up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; game architecture&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gafferongames.com/post/fix_your_timestep/&quot;&gt;Gaffer on Games: Fix Your Timestep&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gameprogrammingpatterns.com/game-loop.html&quot;&gt;Game Programming Patterns: Game Loop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 8 — Matchmaking System Design (~5 hrs)&lt;/h3&gt;
&lt;h4&gt;8.1 Matchmaking queue architecture (2 hrs)&lt;/h4&gt;
&lt;p&gt;Players enter a queue (Redis sorted set by ELO + timestamp). A matchmaker process polls the queue and groups compatible players. When a match is found: create a game session, notify players via WebSocket, move them to a game server. Dequeue on disconnect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; matchmaking&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://redis.io/docs/data-types/sorted-sets/&quot;&gt;Redis sorted sets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gamedeveloper.com/programming/designing-a-matchmaking-system&quot;&gt;Designing a matchmaking system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;8.2 ELO &amp;amp; skill-based matching (1 hr)&lt;/h4&gt;
&lt;p&gt;ELO for skill tracking. Expand match criteria over time: first try ±50 ELO, after 30s try ±200, after 2min try ±500. This ‘expanding window’ balances match quality vs wait time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; matchmaking&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Elo_rating_system&quot;&gt;ELO rating system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/project/trueskill-ranking-system/&quot;&gt;TrueSkill — Microsoft Research&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;8.3 Game session lifecycle (1 hr)&lt;/h4&gt;
&lt;p&gt;States: &lt;code&gt;WAITING → IN_PROGRESS → FINISHED&lt;/code&gt;. Store in Redis with TTL. Each state transition sends WebSocket events. Handle player abandonment (forfeit vs reconnect window). Post-game: update ELO, persist match history, send results.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; matchmaking&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://xstate.js.org/docs/&quot;&gt;XState — state machines in JS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;8.4 Presence &amp;amp; lobby system (1 hr)&lt;/h4&gt;
&lt;p&gt;Track online players in Redis with a TTL key refreshed by heartbeats. Expose a lobby list via WebSocket subscription. Players see who’s online, in queue, or in a game. Use Redis keyspace notifications or a dedicated heartbeat channel.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; matchmaking&lt;/p&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://redis.io/docs/manual/keyspace-notifications/&quot;&gt;Redis keyspace notifications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Phase 9 — Production Checklist &amp;amp; Best Practices (~2 hrs)&lt;/h3&gt;
&lt;h4&gt;9.1 Security checklist (0.5 hrs)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Always &lt;code&gt;wss://&lt;/code&gt; in production&lt;/li&gt;
&lt;li&gt;[ ] Validate &lt;code&gt;Origin&lt;/code&gt; header on every connection&lt;/li&gt;
&lt;li&gt;[ ] Authenticate before sending any game state&lt;/li&gt;
&lt;li&gt;[ ] Set &lt;code&gt;maxPayload&lt;/code&gt; to prevent OOM from large messages&lt;/li&gt;
&lt;li&gt;[ ] Rate limit connections per IP and messages per connection&lt;/li&gt;
&lt;li&gt;[ ] Validate and sanitize every message payload (zod / ajv)&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/WebSockets_Cheat_Sheet.html&quot;&gt;OWASP WebSocket cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;9.2 Reliability checklist (0.5 hrs)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Ping/pong heartbeats with disconnect timeout&lt;/li&gt;
&lt;li&gt;[ ] Exponential backoff with jitter on reconnect&lt;/li&gt;
&lt;li&gt;[ ] Clean up all listeners and Maps on disconnect&lt;/li&gt;
&lt;li&gt;[ ] Graceful shutdown with Close 1001&lt;/li&gt;
&lt;li&gt;[ ] Session resumption tokens issued on connect&lt;/li&gt;
&lt;li&gt;[ ] Message queue with cap during disconnect&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hpbn.co/websocket/&quot;&gt;High Performance Browser Networking ch.17 (free)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;9.3 Scaling checklist (0.5 hrs)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Pub/Sub via Redis or NATS for horizontal scaling — no sticky sessions&lt;/li&gt;
&lt;li&gt;[ ] WS gateway separated from business logic services&lt;/li&gt;
&lt;li&gt;[ ] Load test with k6 before launch&lt;/li&gt;
&lt;li&gt;[ ] Monitor connection count, close code distribution, message throughput&lt;/li&gt;
&lt;li&gt;[ ] Raise &lt;code&gt;ulimit&lt;/code&gt; (file descriptors) on all servers&lt;/li&gt;
&lt;li&gt;[ ] Disable &lt;code&gt;proxy_buffering&lt;/code&gt; and raise &lt;code&gt;proxy_read_timeout&lt;/code&gt; in nginx&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;prose-label&quot;&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/docs/k6/latest/using-k6/protocols/websockets/&quot;&gt;k6 WebSocket load testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;9.4 The essential reading list (0.5 hrs)&lt;/h4&gt;
&lt;p&gt;Three resources worth reading cover-to-cover — everything else is reference material:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://hpbn.co/websocket/&quot;&gt;High Performance Browser Networking ch.17&lt;/a&gt;&lt;/strong&gt; — free, authoritative, covers the protocol deeply&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://gafferongames.com/&quot;&gt;Gaffer on Games&lt;/a&gt;&lt;/strong&gt; — the multiplayer game networking bible; read the whole blog&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.gabrielgambetta.com/client-server-game-architecture.html&quot;&gt;Gabriel Gambetta: Fast-Paced Multiplayer (4 parts)&lt;/a&gt;&lt;/strong&gt; — the clearest explanation of prediction, reconciliation, and interpolation on the internet&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;websockets 101, I’m learning and trying them out here in &lt;a href=&quot;https://github.com/nijuyonkadesu/79-plus/tree/main/chat&quot;&gt;https://github.com/nijuyonkadesu/79-plus/tree/main/chat&lt;/a&gt; (no where near completion, but really interesting)&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>CN flash games</title>
    <link>https://unclassi.fyi/blog/notes/cn-flash-games/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/cn-flash-games/</guid>
    <pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Cartoon Network flash games from the bygone era&lt;/p&gt;&lt;p&gt;Flash Games (Archive): &lt;a href=&quot;https://www.webdesignmuseum.org/flash-game-exhibitions/cartoon-network-flash-games&quot;&gt;https://www.webdesignmuseum.org/flash-game-exhibitions/cartoon-network-flash-games&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Discussions: &lt;a href=&quot;https://news.ycombinator.com/item?id=48065360&quot;&gt;https://news.ycombinator.com/item?id=48065360&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Speaking of CartoonNetwork… &lt;strong&gt;I HATE ADVENTURE TIME!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Thankyou for listening.&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Spot larpers in workplace</title>
    <link>https://unclassi.fyi/blog/notes/spot-larpers-in-workplace/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/spot-larpers-in-workplace/</guid>
    <pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Identify and catch them. So you can be wary around them.&lt;/p&gt;&lt;p&gt;Appearing productive in the workplace (Ohh the sleepercells who kill an organization from the inside!!): &lt;a href=&quot;https://nooneshappy.com/article/appearing-productive-in-the-workplace/&quot;&gt;https://nooneshappy.com/article/appearing-productive-in-the-workplace/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Discussion: &lt;a href=&quot;https://news.ycombinator.com/item?id=48038001&quot;&gt;https://news.ycombinator.com/item?id=48038001&lt;/a&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Youtube updates in RSS feed</title>
    <link>https://unclassi.fyi/blog/notes/youtube-rss-feed/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/youtube-rss-feed/</guid>
    <pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;RSS feed for channel updates.&lt;/p&gt;&lt;p&gt;I had no idea YouTube has a official RSS feed: &lt;a href=&quot;https://news.ycombinator.com/item?id=48032508&quot;&gt;https://news.ycombinator.com/item?id=48032508&lt;/a&gt;&lt;/p&gt;
</description>
    <category>sneak</category>
  </item>
<item>
    <title>Talking to strangers at the gym</title>
    <link>https://unclassi.fyi/blog/notes/talking-to-strangers-at-the-gym/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/talking-to-strangers-at-the-gym/</guid>
    <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Try it out. See how things go.&lt;/p&gt;&lt;p&gt;Here’s a 5 week plan on how and what to talk to strangers at the gym: &lt;a href=&quot;https://web.archive.org/web/20261019201000/https://thienantran.com/talking-to-35-strangers-at-the-gym/&quot;&gt;https://web.archive.org/web/20261019201000/https://thienantran.com/talking-to-35-strangers-at-the-gym/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;discussions: &lt;a href=&quot;https://news.ycombinator.com/item?id=48007438&quot;&gt;https://news.ycombinator.com/item?id=48007438&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;s&gt;I didn’t try them, I spend more than 1hr in gym just working out… I don’t have the same luxury as him. Not because I’m scared or anything!! I wanted to make that distinction very clear!!&lt;/s&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Next steps for your career</title>
    <link>https://unclassi.fyi/blog/notes/career-roadmap/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/career-roadmap/</guid>
    <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Find what steps your next role demands&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://crackingwalnuts.com/&quot;&gt;https://crackingwalnuts.com/&lt;/a&gt; - A detailed roadmap for your next career. Worth checking once.&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>A collection of small cozy tools. You&#039;d love these.</title>
    <link>https://unclassi.fyi/blog/notes/cozy-handy-tools/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/cozy-handy-tools/</guid>
    <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Images, Video, Audio, Colors, QR, Social Media, Typography, Printing, Dev, Calculator&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://delphi.tools&quot;&gt;https://delphi.tools&lt;/a&gt; - Collection of amazing tools in browser.&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>Haskell teaches you a very important principle</title>
    <link>https://unclassi.fyi/blog/notes/the-root-of-some-evil/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/the-root-of-some-evil/</guid>
    <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Get rid of the untold rules your team writes every day, and cut down the untold rituals went into codebase, while documented nowhere.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blog.haskell.org/a-couple-million-lines-of-haskell/&quot;&gt;https://blog.haskell.org/a-couple-million-lines-of-haskell/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;“Remember to flush the audit log after every transaction.”&lt;/li&gt;
&lt;li&gt;“Always check the feature flag before calling this endpoint.”&lt;/li&gt;
&lt;li&gt;“Make sure to enqueue the notification inside the database transaction, not after it.”&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;These are the incantations of operational lore. They live in wiki pages, onboarding documents, half-forgotten design reviews, and the memories of senior engineers who are now three teams away and booked solid until Thursday.&lt;br&gt;
In a company that is hiring aggressively, the half-life of tribal knowledge is alarmingly short. When an engineer leaves, the incantations fade. When a deadline approaches, they are the first thing skipped. When a new engineer joins, they often have no way to know the incantation exists at all. Nothing says “robust system design” quite like a critical invariant living in a Slack thread from nine months ago.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>UK doesn&#039;t have copyright on recipes</title>
    <link>https://unclassi.fyi/blog/notes/stolen-recipies/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/stolen-recipies/</guid>
    <pubDate>Wed, 29 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Stashed copies of recipies from United Kingdom - and you cannot copyright them.&lt;/p&gt;&lt;p&gt;idk about cooking, but gordan ramsey’s recipies are here if you want to try em out &lt;a href=&quot;https://www.recipeninja.ai/&quot;&gt;https://www.recipeninja.ai/&lt;/a&gt;&lt;br&gt;
actualy I discovered it from this &lt;a href=&quot;https://youtu.be/O7joqcfy-eU&quot;&gt;https://youtu.be/O7joqcfy-eU&lt;/a&gt; - interview on Briish entrepreneurs&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Hierarchical state machines</title>
    <link>https://unclassi.fyi/blog/notes/hierarchical-state-machines/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/hierarchical-state-machines/</guid>
    <pubDate>Sun, 26 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;An executable statemachine representation (diagramatic)&lt;/p&gt;&lt;p&gt;Statecharts: Hierarchical state machines &lt;a href=&quot;https://statecharts.dev/&quot;&gt;https://statecharts.dev/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please stop… why would you make an executable from a state chart!! Who thought of that terrible idea (imo)!! You’ll wake up all the resting UML enthusiasts from their coffins!&lt;/p&gt;
&lt;p&gt;discussions: &lt;a href=&quot;https://news.ycombinator.com/item?id=47908833&quot;&gt;https://news.ycombinator.com/item?id=47908833&lt;/a&gt;&lt;/p&gt;
</description>
    <category>concept</category>
  </item>
<item>
    <title>USB Cheatsheet</title>
    <link>https://unclassi.fyi/blog/notes/usb-cheatsheet/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/usb-cheatsheet/</guid>
    <pubDate>Sun, 26 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Cheatsheet, so the numbers do not confuse you.&lt;/p&gt;&lt;p&gt;USB cheatsheet: Come take a look at it before buying a random cable from amazon &lt;a href=&quot;https://fabiensanglard.net/usbcheat/index.html&quot;&gt;https://fabiensanglard.net/usbcheat/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For HDMI: &lt;a href=&quot;/blog/notes/hdmi-versions-need-special-attention/&quot;&gt;HDMI versions cheatsheet&lt;/a&gt;&lt;/p&gt;
</description>
    <category>cheatsheet</category>
  </item>
<item>
    <title>Amazing board games</title>
    <link>https://unclassi.fyi/blog/notes/board-game-suggestions/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/board-game-suggestions/</guid>
    <pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Why you should try playing boardgames with your friends right now.&lt;/p&gt;&lt;p&gt;The only board (table top) game I play that’s not in this list in Dungeons and Dragons. With enough fire power you can reignite even a dying star…&lt;/p&gt;
&lt;p&gt;site: &lt;a href=&quot;https://boardgamegeek.com/blog/10755/blogpost/124992/modern-board-games-and-why-you-should-play-them&quot;&gt;https://boardgamegeek.com/blog/10755/blogpost/124992/modern-board-games-and-why-you-should-play-them&lt;/a&gt;&lt;br&gt;
discussions: &lt;a href=&quot;https://news.ycombinator.com/item?id=47836859&quot;&gt;https://news.ycombinator.com/item?id=47836859&lt;/a&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Easy language acquisition as an infant</title>
    <link>https://unclassi.fyi/blog/notes/easy-language-acquisition-as-an-infant/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/easy-language-acquisition-as-an-infant/</guid>
    <pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Lexfridman podcast, featuring a musician - Rick Beato. One particular incident he shared there stuck in my mind.&lt;/p&gt;&lt;p&gt;Rick Beato, one of the greatest musician decided to play music to his new (unborn) infant. He did that quite regularly, also played his (unborn) infant a multitude of different octaves, fundamental notes, everything he could structuredly from his piano. After some years, the (born) infant turns out to be beating his own father in his own domain.&lt;/p&gt;
&lt;p&gt;It’s just crazy. This is not magic, it’s how humans work. I’d definitely want to try this one day. &lt;a href=&quot;https://m.youtube.com/watch?v=1SJiTwbSI58&quot;&gt;https://m.youtube.com/watch?v=1SJiTwbSI58&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Language acquisition, since 15 weeks, as an infant is simply crazy.&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Experimental medcert generator</title>
    <link>https://unclassi.fyi/blog/notes/medcert-generator/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/medcert-generator/</guid>
    <pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Your doctor did not prescribe these!&lt;/p&gt;&lt;p&gt;He’s got some insane templates there - &lt;a href=&quot;https://medicalcertificategenerator.com/&quot;&gt;https://medicalcertificategenerator.com/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
<item>
    <title>Minerals at museum</title>
    <link>https://unclassi.fyi/blog/notes/minerals-at-museum/</link>
    <guid isPermaLink="true">https://unclassi.fyi/blog/notes/minerals-at-museum/</guid>
    <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
    <description>&lt;p&gt;Beautiful iridescent shaded minerals&lt;/p&gt;&lt;p&gt;Raw minerals at natural museum for display:&lt;br&gt;
&lt;a href=&quot;https://wchambliss.wordpress.com/2026/03/03/god-sleeps-in-the-minerals/&quot;&gt;https://wchambliss.wordpress.com/2026/03/03/god-sleeps-in-the-minerals/&lt;/a&gt;&lt;/p&gt;
</description>
    <category>slice-of-life</category>
  </item>
</channel></rss>