<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Level Up Coding - Medium]]></title>
        <description><![CDATA[Coding tutorials and news. The developer homepage gitconnected.com &amp;&amp; skilled.dev &amp;&amp; levelup.dev - Medium]]></description>
        <link>https://levelup.gitconnected.com?source=rss----5517fd7b58a6---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Level Up Coding - Medium</title>
            <link>https://levelup.gitconnected.com?source=rss----5517fd7b58a6---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 24 Sep 2026 09:00:01 GMT</lastBuildDate>
        <atom:link href="https://levelup.gitconnected.com/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Friedman test in R, or the nonparametric version of the repeated measures ANOVA]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/friedman-test-in-r-or-the-nonparametric-version-of-the-repeated-measures-anova-85b7329ac355?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/2600/0*xx0dgrkwf71K3zux" width="3456"></a></p><p class="medium-feed-snippet">Learn how to perform the Friedman test in R, the nonparametric alternative to the repeated measures ANOVA for comparing 3+ related groups.</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/friedman-test-in-r-or-the-nonparametric-version-of-the-repeated-measures-anova-85b7329ac355?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/friedman-test-in-r-or-the-nonparametric-version-of-the-repeated-measures-anova-85b7329ac355?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/85b7329ac355</guid>
            <category><![CDATA[statistics]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[education]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Antoine Soetewey]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:42:36 GMT</pubDate>
            <atom:updated>2026-09-23T14:42:35.637Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
        </item>
        <item>
            <title><![CDATA[Jev is getting a lot of hype. Here’s why it could be a big deal for developers.]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/jev-is-getting-a-lot-of-hype-heres-why-it-could-be-a-big-deal-for-developers-afc0a5c36169?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/1254/0*4gAyMRg91fqjqVyW" width="1254"></a></p><p class="medium-feed-snippet">A first look at Jev&#x2019;s speed and probability outputs</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/jev-is-getting-a-lot-of-hype-heres-why-it-could-be-a-big-deal-for-developers-afc0a5c36169?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/jev-is-getting-a-lot-of-hype-heres-why-it-could-be-a-big-deal-for-developers-afc0a5c36169?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/afc0a5c36169</guid>
            <category><![CDATA[typefaceai]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[jevs]]></category>
            <category><![CDATA[distributed-systems]]></category>
            <category><![CDATA[transformers]]></category>
            <dc:creator><![CDATA[Hammad Abbasi]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:42:24 GMT</pubDate>
            <atom:updated>2026-09-23T14:42:23.125Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[There’s No Cache For What An Agent Just Figured Out]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/theres-no-cache-for-what-an-agent-just-figured-out-5bb816d1c01d?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/1600/1*xKAFhdN0-tTiHoNI22saqw.png" width="1600"></a></p><p class="medium-feed-snippet">Your Agent Already Found The Bug, And Forgot.</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/theres-no-cache-for-what-an-agent-just-figured-out-5bb816d1c01d?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/theres-no-cache-for-what-an-agent-just-figured-out-5bb816d1c01d?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/5bb816d1c01d</guid>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[harness-engineering]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[agentic-ai]]></category>
            <dc:creator><![CDATA[Akshat Tiwari]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:42:11 GMT</pubDate>
            <atom:updated>2026-09-23T14:42:09.715Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[We Added More Kafka Partitions for Throughput. Ordering Broke Somewhere We’d Never Checked.]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/we-added-more-kafka-partitions-for-throughput-ordering-broke-somewhere-wed-never-checked-4210f571d95e?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/2600/0*d2t8nAHluxDSgLL5" width="6000"></a></p><p class="medium-feed-snippet">Partition count is a performance decision until it&#x2019;s silently also a correctness decision nobody flagged at design time.</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/we-added-more-kafka-partitions-for-throughput-ordering-broke-somewhere-wed-never-checked-4210f571d95e?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/we-added-more-kafka-partitions-for-throughput-ordering-broke-somewhere-wed-never-checked-4210f571d95e?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/4210f571d95e</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[backend-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[distributed-systems]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[syarif]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:42:03 GMT</pubDate>
            <atom:updated>2026-09-23T14:42:01.282Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Why your nav health check slowed down as the menu grew]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/why-your-nav-health-check-slowed-down-as-the-menu-grew-822e5201e1d7?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/1200/1*UN5IxgncYLXDGcvY2ChsLA.png" width="1200"></a></p><p class="medium-feed-snippet">It worked in dev &#xB7; Episode 5 &#xB7; technique: returning two facts from one pass</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/why-your-nav-health-check-slowed-down-as-the-menu-grew-822e5201e1d7?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/why-your-nav-health-check-slowed-down-as-the-menu-grew-822e5201e1d7?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/822e5201e1d7</guid>
            <category><![CDATA[trees]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[algorithms]]></category>
            <category><![CDATA[dsa-problem]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[Archit Agarwal]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:41:44 GMT</pubDate>
            <atom:updated>2026-09-23T14:41:43.626Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[RAZ Encrypt: Post-Quantum Cryptography in 10 Lines of JavaScript]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/raz-encrypt-post-quantum-cryptography-in-10-lines-of-javascript-eb875d491d58?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/2600/0*hlhlqSVxSwrUroVa" width="3999"></a></p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/raz-encrypt-post-quantum-cryptography-in-10-lines-of-javascript-eb875d491d58?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/raz-encrypt-post-quantum-cryptography-in-10-lines-of-javascript-eb875d491d58?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/eb875d491d58</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[cryptography]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[post-quantum-cryptography]]></category>
            <dc:creator><![CDATA[RYMS]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:41:32 GMT</pubDate>
            <atom:updated>2026-09-23T14:41:30.953Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[I Built a Context Meter for Four AI Chat Apps. Counting Tokens Was the Easy Part.]]></title>
            <link>https://levelup.gitconnected.com/i-built-a-context-meter-for-four-ai-chat-apps-counting-tokens-was-the-easy-part-f2c0f5afc26a?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/f2c0f5afc26a</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[chrome-extension]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[Adi Leviim]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:41:20 GMT</pubDate>
            <atom:updated>2026-09-23T14:41:19.101Z</atom:updated>
            <content:encoded><![CDATA[<p><em>The same conversation read 2%, 12% and 64% on three machines. The fix was choosing which source of truth to believe.</em></p><figure><img alt="Three identical round dashboard gauges labelled laptop, phone and after reload. Their needles point to 2 percent, 12 percent and 64 percent. A line under them reads same conversation, same account." src="https://cdn-images-1.medium.com/max/1024/1*peGqYbIcmTZ5GR7d-Hmfsg.png" /><figcaption>Three readings of one conversation, all produced by the same build. Each was correct for what that machine could see. Credit: Illustration by author</figcaption></figure><p>Long AI chats degrade in ways that look like bugs. Claude starts summarizing earlier messages to stay inside its window, which Anthropic’s help centre describes as Claude “organizing its thoughts” during long conversations. ChatGPT gets slower and starts losing the thread. Nothing in either interface tells you how full the conversation is, so users blame the model, the network, or whatever tool sits in the page.</p><p>I co-build a browser extension for ChatGPT, Claude, Gemini and Grok, and we shipped a context window meter: a small gauge in the corner of the page showing roughly how much of the window this conversation has used. The token math turned out to be the simple half. The hard parts were the denominator and deciding which copy of the conversation to trust.</p><h3>The numerator: an estimate that admits it is one</h3><p>We do not run a real tokenizer in the page. Each vendor uses a different one, they change, and shipping one per platform into a content script buys precision that the rest of the calculation cannot honour anyway. So the count is a character heuristic, the same one our word counter already used:</p><pre>const CJK_RE = /[\u3000-\u9fff\uac00-\ud7af\uff00-\uffef]/g;</pre><pre>export function estimateTokens(text: string): number {<br>  if (!text || text.trim() === &quot;&quot;) return 0;<br>  const cjkChars = (text.match(CJK_RE) || []).length;<br>  const otherChars = text.length - cjkChars;<br>  return Math.ceil(otherChars / 4 + cjkChars / 1.5);<br>}</pre><p>Four characters per token for Latin text, 1.5 for CJK, which packs far more meaning per glyph. It ignores files, images and whatever system prompt the vendor injects, so it reads low on conversations with attachments.</p><p>That imprecision is fine, and saying so is part of the design. A meter that claims to be exact invites a user to check it, and the moment they find it off by 8% they stop believing the part that matters: that they are close to the ceiling. The number is labelled an estimate in the UI for the same reason.</p><p>The denominator is where a meter earns or loses its credibility, because being wrong about the ceiling is not imprecision, it is a different answer.</p><h3>The denominator: context windows are a product decision, not a model fact</h3><p>The context window of a consumer chat app is not the model’s API window. It is set by the vendor per plan, and it changes. This is the part most people get wrong, including us, twice.</p><p>For ChatGPT, the numbers come from OpenAI’s own plan comparison table, and they differ across three plans and two kinds of model:</p><pre>export function chatgptWindowTokens(modelLabel: string, plan: ChatGPTPlan): number {<br>  const reasoning = isChatGPTReasoningModel(modelLabel);<br>  if (plan === &quot;pro&quot;) return reasoning ? 400000 : 128000;<br>  // Go and Plus are the same two numbers on OpenAI&#39;s table.<br>  if (plan === &quot;plus&quot; || plan === &quot;go&quot;) return reasoning ? 256000 : 54000;<br>  return 27000; // Free (its reasoning cell says &quot;Varies&quot;, so Free cannot pin one)<br>}</pre><p>A Plus user on an instant answer has 54K. The same person on a reasoning model has 256K. Same account, same page, nearly five times the room, and nothing in the interface says so.</p><figure><img alt="A matrix of context window sizes. ChatGPT rows: Free 27K instant, Plus and Go 54K instant and 256K reasoning, Pro 128K instant and 400K reasoning. Claude rows: free 200K for every model, paid 1M for Fable 5.1, Opus 5 and Sonnet 5, 500K for Opus 4.6 to 4.8 and Sonnet 4.6, 200K for everything else. Gemini rows: free 32K, paid 1M on the same three models." src="https://cdn-images-1.medium.com/max/1024/1*ZMedYiYoASgmr8dbI3kuJQ.png" /><figcaption>One gauge, three vendors, nine different denominators. The plan matters as much as the model. Credit: Diagram by author, figures from OpenAI’s plan comparison table and the Anthropic and Google help centres</figcaption></figure><p>Claude splits by model rather than by plan above the free tier, and Gemini by plan rather than by model. That last one caught us: we shipped “free users get the small models at about 128K”, and by August 2026 both halves of that sentence were wrong. Google’s help page now says free and paid users get the same three models, and the plans differ by window, 32K against 1M.</p><p>Detecting which case you are in has its own traps. Reading the model label from the DOM looks obvious until a user opens the model picker, at which point the page contains every model they could switch to, and a naive scan happily reports whichever one is first in the list. Our detector runs two passes and skips anything with a menu item role, so an open picker cannot vote. On ChatGPT we gave up on inference entirely and ask the app: /backend-api/accounts/check returns a plan_type, which beats guessing from a label that is often not on the page at all.</p><h3>The bug: three machines, three answers, all correct</h3><p>A user reported that one conversation read 2%, then 12% after a reload, then 64% on a second computer. Same account, same build.</p><p>Both numbers came from sources that are complete only by accident:</p><ol><li>Our local cache. Background sync stores conversations in IndexedDB per device. A machine that synced yesterday holds a shorter copy than the one you are typing in now.</li><li>The rendered page. Long transcripts are virtualised. What is in the DOM is what you have scrolled through, not what exists.</li></ol><p>Summing either one gives you a defensible number and the wrong one. Worse, the failure is silent: a partial cache looks exactly like a complete one.</p><p>The fix was to stop reconciling two partial sources and read the authoritative one. The platform’s own conversation endpoint returns the whole thread, identically on every device. The rules for when to call it live in a pure module so they can be tested rather than buried in a widget:</p><pre>export const LIVE_REFRESH_MIN_MS = 20_000;</pre><pre>export function shouldReadLive(input: LiveReadInputs): boolean {<br>  if (!input.hasLiveReader) return false;<br>  if (!input.readThisConversation) return true;      // first read is unconditional<br>  if (input.msSinceLastRead &lt; LIVE_REFRESH_MIN_MS) return false;<br>  return input.domTurns &gt; input.domTurnsAtLastRead;  // only when turns were added<br>}</pre><p>Three decisions in that function are worth more than the code:</p><ul><li>The first read per conversation is unconditional. There is no test that proves a cached copy is complete, so “refresh only when the cache looks short” cannot close the gap.</li><li>Later reads compare on-screen turn counts to each other, never to the stored transcript length. The rendered count is not the conversation’s length, but a rise in it does mean something was added.</li><li>The two numbers are reconciled by taking the larger, never the newer.</li></ul><pre>export function reconcileTokens(cacheTokens: number, liveTokens: number): number {<br>  return Math.max(cacheTokens || 0, liveTokens || 0);<br>}</pre><p>That last one is the asymmetry that makes the feature honest. Both sources describe the same conversation, so the bigger number is the more complete view, and under-reporting is the failure that actually hurts. A meter that says 2% on a chat about to hit its ceiling is worse than no meter, because the user acted on it.</p><figure><img alt="A flow diagram titled when to read the conversation live. First branch, no live reader, use the cache. Second, first read of this conversation, read live. Third, less than 20 seconds since the last read, skip. Fourth, more turns on screen than at the last read, read live, otherwise skip. The result feeds a reconcile step that takes the larger of cache and live." src="https://cdn-images-1.medium.com/max/1024/1*cdv54azPEmyfR2IyhOxO9g.png" /><figcaption>One authoritative read per conversation, then reads only when the page proves something changed. Credit: Diagram by author</figcaption></figure><h3>The judgment call we wrote down instead of guessing</h3><p>When Anthropic published its chat window buckets, one model was missing from the chat page: Fable 5, named only in a sentence about Claude Code. A literal reading would drop it into the 200K remainder. We kept it at 500K and left the reasoning in the file:</p><pre>// Fable 5 (not 5.1) is HELD at 500K by an explicit product decision, not by the<br>// page. Anthropic names it only in the Claude Code sentence, so a literal reading<br>// would drop it into the 200K remainder below, but &quot;undocumented&quot; is not the same<br>// as &quot;confirmed small&quot;, and halving a flagship&#39;s denominator on an inference would<br>// make the gauge cry wolf on every long Fable chat. It stays at the previous value<br>// until Anthropic publishes a chat figure, at which point this branch is deleted.</pre><p>Any team that mirrors someone else’s numbers ends up with a version of this: a value you cannot source, a default that has to be wrong in one direction, and a future reader who needs to know which way you chose and why. The comment is the deliverable, not the constant. A number with a deletion condition attached is maintainable; a magic number is a landmine for whoever inherits it.</p><h3>What happens when the gauge fills</h3><p>A meter that only reports is half a feature. The useful moment is the one just before compaction, when the conversation still has everything in it.</p><p>So the premium half of the feature carries a conversation forward: summarize the thread, open a fresh chat, and paste the summary into the composer as the first message. It works across platforms too, so a Claude thread can continue in a new ChatGPT chat. The seed is stored keyed to its target platform with a short expiry, and only a freshly booting content script claims it, so a later unrelated visit can never receive a stale paste.</p><figure><img alt="Three step diagram. Step one, meter: 92 percent of the window used, everything still in the conversation. Step two, vendor: compaction starts, Claude summarizes earlier messages to keep going, shown as organizing its thoughts. Step three, handoff: fresh chat seeded, summary pasted as the first message, offline fallback carries a 7,000 character excerpt." src="https://cdn-images-1.medium.com/max/1024/1*9x1jD2XESKdWlL9ExZ-Xmg.png" /><figcaption>The gauge is only worth building if something useful happens at the top of it. Credit: Diagram by author, compaction behaviour from the Anthropic Help Center</figcaption></figure><p>The fallback matters more than the summarizer. When the backend is unreachable, we build the summary locally with no API call at all: short chats are carried verbatim, and long ones become an extractive excerpt, the opening request plus as many recent turns as fit a 7,000 character budget, with an explicit marker where the middle was dropped. The start says what the work is, the end holds the current state, and the middle is the safest thing to cut.</p><h3>Key Takeaways</h3><ul><li>Precision in the numerator is worth less than honesty about it. A character heuristic labelled as an estimate is more useful than a precise number the user cannot verify.</li><li>Consumer context windows are per plan, per model and subject to change. Source them from vendor documentation and keep a dated comment saying when you checked.</li><li>A cache and a rendered page are both partial. If correctness matters, read the authoritative endpoint once per conversation, then only when the page proves something changed.</li><li>Pick the failure direction deliberately. Taking the larger of two token counts is not a rounding choice, it is a decision about which way the feature is allowed to be wrong.</li><li>Write the reason next to the constant. A held value with a deletion condition survives the next maintainer; a bare number does not.</li></ul><h3>FAQ</h3><p>How accurate is a character based token estimate? Close enough for a gauge, not for billing. Four characters per token is a good approximation for Latin script and 1.5 fits CJK better, but the estimate excludes files, images and vendor system prompts, so it reads low on conversations with attachments. Label it as an estimate in the UI.</p><p>Why not run a real tokenizer in the browser? Each vendor tokenizes differently and those tokenizers change. Shipping one per platform into a content script adds weight and maintenance for precision the rest of the calculation cannot match, because the true denominator and the hidden system tokens are unknown anyway.</p><p>Where do the context window numbers come from? Vendor documentation, not model cards. OpenAI publishes windows per plan in its plan comparison table, Anthropic lists chat windows per model on paid plans, and Google states free and paid windows for the Gemini app. We keep the plan by plan numbers current in <a href="https://www.ai-toolbox.co/chatgpt-models/chatgpt-context-window-token-limits-2026">our ChatGPT context window guide</a>.</p><p>What is context compaction? When a conversation approaches the window limit, Claude summarizes earlier messages so the chat can continue, and the full history stays available to it. Anthropic says users may see Claude “organizing its thoughts” while this happens. It is not an error, but it is the moment older detail stops being quoted back verbatim.</p><p>If you work inside ChatGPT, Claude, Gemini or Grok all day, you can <a href="https://chromewebstore.google.com/detail/ai-toolbox-folders-prompt/jlalnhjkfiogoeonamcnngdndjbneina">try AI Toolbox free on the Chrome Web Store</a>. The context meter is free on all four platforms. Premium adds the carry forward handoff, full text search without a result cap, unlimited folders and bulk export, at $9.99 a month, $59 a year or $99 lifetime, with All Access at $199 for all four modules. These are browser extension features, not an AI subscription.</p><p>What does your team do when a conversation fills its window: start over, summarize, or split the work earlier?</p><p>About the author: Adi Leviim is the co-founder of AI Toolbox (formerly ChatGPT Toolbox), a Chrome extension with modules for ChatGPT, Claude, Gemini and Grok, used by 40,000+ people across 150+ countries to search, organize and export their AI conversations. He writes about the reality of building AI products with 7+ years of full-stack development experience. Follow him on Medium for honest takes on SaaS, AI tools, and shipping software that people actually use.</p><p><a href="https://ai-toolbox.co/">AI Toolbox</a> | <a href="https://medium.com/@adi_leviim">Medium</a> | <a href="https://x.com/adileviim">Twitter/X</a> | <a href="https://www.linkedin.com/in/adi-leviim/">LinkedIn</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f2c0f5afc26a" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/i-built-a-context-meter-for-four-ai-chat-apps-counting-tokens-was-the-easy-part-f2c0f5afc26a">I Built a Context Meter for Four AI Chat Apps. Counting Tokens Was the Easy Part.</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[One Table to Rule Them All: How We Adapted a Document Schema in MySQL]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/one-table-to-rule-them-all-how-we-adapted-a-document-schema-in-mysql-55a180b0c7de?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/1376/1*9Sd61mLBCJ6UogN2JiMG_w.jpeg" width="1376"></a></p><p class="medium-feed-snippet">We had a product catalogue with fifty attribute sets across twenty product types. The traditional approach meant twenty tables, fifty&#x2026;</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/one-table-to-rule-them-all-how-we-adapted-a-document-schema-in-mysql-55a180b0c7de?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/one-table-to-rule-them-all-how-we-adapted-a-document-schema-in-mysql-55a180b0c7de?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/55a180b0c7de</guid>
            <category><![CDATA[json-schema]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[spring-boot-3]]></category>
            <category><![CDATA[mysql]]></category>
            <category><![CDATA[database-architecture]]></category>
            <dc:creator><![CDATA[Sriram Mahalingam]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:41:07 GMT</pubDate>
            <atom:updated>2026-09-23T14:41:05.888Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Agent skills over MCP: load SKILL.md only when you need it]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://levelup.gitconnected.com/agent-skills-over-mcp-load-skill-md-only-when-you-need-it-7eabb290d90b?source=rss----5517fd7b58a6---4"><img src="https://cdn-images-1.medium.com/max/1536/1*Q6IMq4a7dgWcZdlZOHR75g.png" width="1536"></a></p><p class="medium-feed-snippet">MCP discovers skills on the server; you pull SKILL.md only when the task matches.</p><p class="medium-feed-link"><a href="https://levelup.gitconnected.com/agent-skills-over-mcp-load-skill-md-only-when-you-need-it-7eabb290d90b?source=rss----5517fd7b58a6---4">Continue reading on Level Up Coding »</a></p></div>]]></description>
            <link>https://levelup.gitconnected.com/agent-skills-over-mcp-load-skill-md-only-when-you-need-it-7eabb290d90b?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/7eabb290d90b</guid>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[claude-code]]></category>
            <category><![CDATA[mcp-server]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[allglenn]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:40:53 GMT</pubDate>
            <atom:updated>2026-09-23T14:40:52.243Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Map Reduce explained with example | System Design]]></title>
            <link>https://levelup.gitconnected.com/map-reduce-explained-with-example-system-design-e900a20ee131?source=rss----5517fd7b58a6---4</link>
            <guid isPermaLink="false">https://medium.com/p/e900a20ee131</guid>
            <category><![CDATA[hadoop]]></category>
            <category><![CDATA[big-data-processing]]></category>
            <category><![CDATA[mapreduce]]></category>
            <category><![CDATA[apache-spark]]></category>
            <dc:creator><![CDATA[Hayk Simonyan]]></dc:creator>
            <pubDate>Wed, 23 Sep 2026 14:40:41 GMT</pubDate>
            <atom:updated>2026-09-23T14:40:40.533Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6Dl1_GZDGFVB2UrG.png" /></figure><h3>The Problem: How to Analyze Massive Datasets</h3><p>Imagine you have terabytes of website logs tracking every single visitor interaction, and from here, you want to filter out some information, like which pages are most popular or where visitors drop off in your purchase funnel, etc.</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*vecbcM3jAJAcq7ZV.png" /></figure><p>Traditional tools and databases are simply not designed for datasets of this scale. That’s where MapReduce comes in.</p><h3>What is MapReduce?</h3><p>MapReduce is a programming model designed specifically to handle the challenges of processing enormous amounts of data that just won’t fit on a single computer. It was <a href="https://static.googleusercontent.com/media/research.google.com/en//archive/mapreduce-osdi04.pdf">introduced by Google</a> in 2004 to tackle exactly these kinds of scenarios. Let’s see how it works through our website log example…</p><h3>How MapReduce Handles Big Data</h3><p>MapReduce operates in two primary phases — The map phase and the reduce phase.</p><h3>Map Phase</h3><p>In the Map Phase, we first split these huge logs into smaller and manageable chunks. These chunks then get sent to different worker computers in a cluster.</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rgoIOuswf-VtwUVB.png" /></figure><p>Think of each worker as a separate server that handles its assigned chunk. It has a <strong>Map Function</strong> that extracts the key information: in our case, it will map the <strong>keys</strong>, which are the specific webpage visited, to the <strong>values</strong>, which, if we are counting visits, can be the number of visits to that page (e.g., 1)</p><h3>Reduce Phase</h3><p>Then, we enter the reduce phase, where all the key-value pairs generated by the map phase are sorted and grouped by webpage (‘key’).</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pNbIEyqe1f9C4pky.png" /></figure><p>We forward those to the <strong>Reduce Function</strong>. For each unique webpage, it adds up the ‘1’ values to find the total visits. It can also tackle more complex questions, such as average time spent, visitor demographics, etc.</p><p>And now, using this information, we can visualize it via charts and other visuals on the screen.</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*zOwkHjs5rZePpg6C.png" /></figure><h3>Benefits of MapReduce for Log Analysis</h3><p>We get a couple of benefits when processing data with MapReduce:</p><ul><li><strong>Parallel Power:</strong> Distributing the work makes processing much faster than a single computer could manage.</li><li><strong>Scalability:</strong> Got even more log data? Just add more computers to the cluster and MapReduce can keep up.</li><li><strong>Fault Tolerance:</strong> If a computer fails during a job, MapReduce automatically reassigns its work to other computers in the network. This ensures that all the tasks are completed successfully without interruption.</li></ul><h3>Batch vs. Stream Processing</h3><p>To understand why MapReduce is so unique, let’s quickly touch on batch versus stream processing:</p><h3>Batch Processing</h3><p>Batch Processing deals with data in large chunks that have already been collected. For example, if you search for a word in Google Docs or Microsoft Word in a large file, the data is available upfront, so it can be processed immediately.</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/945/0*wgAMBkyjKgPH5cV_.png" /></figure><p>This is useful for large datasets where immediate results aren’t essential, such as when generating monthly sales reports, analyzing customer purchase history, or training machine learning models on data.</p><h3>Streaming Processing</h3><p>Stream Processing handles data as it arrives in a continuous flow. For example, when watching a YouTube video, you hit ‘play’, and it starts almost immediately. That’s because tiny pieces of video are sent to your computer in a continuous flow, letting you watch while the rest of the video is still being transmitted.</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*c2OHG24EoH1NYATp.png" /></figure><p>Streaming is ideal for situations requiring immediate action on data streams, such as when you want to identify suspicious activity in financial transactions or when you need real-time analytics for social media feeds.</p><h3>Micro-batch Processing</h3><p>We also have micro-batch processing, which is a hybrid approach that bridges the gap between traditional batch processing and stream processing.</p><p>Instead of processing all of your data in one huge batch, micro-batch processing breaks data down into very small batches. These batches are processed at short, fixed intervals (often in seconds or minutes).</p><p>Press enter or click to view image in full size</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ThpcvbwPQi7o98z-.png" /></figure><p>Micro-batching is often the preferred method for scenarios demanding faster results than traditional batch, but where full-on streaming isn’t necessary.</p><h3>What is the processing method used by MapReduce?</h3><p>MapReduce is a batch-processing model because it operates on data that is already stored, not on a live continuous stream of incoming data. Input data needs to be divided and distributed before the Map phase of MapReduce even begins.</p><p>As you can imagine, Batch processing is slower than Streaming<strong> </strong>due to the accumulation of data before processing. But it’s generally simpler to set up and manage, while Stream Processing can be more complex due to the constant flow of data and the potential for errors or inconsistencies.</p><h3>MapReduce Limitations and Modern Alternatives</h3><p>While MapReduce was revolutionary, it has limitations in terms of speed and flexibility for iterative and complex data processing tasks. This is where tools like <a href="https://spark.apache.org/">Apache Spark</a> come in.</p><h3>Apache Spark</h3><p>Spark leverages in-memory processing, meaning it keeps data in RAM for very fast calculations compared to MapReduce’s reliance on disk storage. It handles a wider range of tasks, including SQL queries, machine learning, and real-time data processing (streaming).</p><h3>Apache Flink</h3><p><a href="https://flink.apache.org/">Apache Flink</a> is another powerful framework used for real-time data processing (stream processing). It offers similar capabilities to Spark Streaming, allowing for immediate analysis of data as it arrives. This is a specialized tool for scenarios requiring real-time data analysis, often used alongside Spark for a complete big data processing toolkit.</p><h3>Hadoop</h3><p><a href="https://hadoop.apache.org/">Hadoop</a> is a broader ecosystem that provides the foundation for tools like Spark and MapReduce to run. It includes a distributed file system (HDFS) for storing large datasets across multiple machines and a resource management system (YARN<strong>) </strong>that allocates resources (CPU, memory) to applications like Spark or MapReduce.</p><p>Think of it as the underlying infrastructure that Spark and other tools use to manage and store big data.</p><h3>Cloud-based Services (AWS, Azure, GCP)</h3><p>Cloud providers like AWS, Azure, and Google offer managed data processing solutions that often streamline the use of MapReduce frameworks. These include <a href="https://aws.amazon.com/emr/">AWS EMR</a> (which supports Hadoop), <a href="https://azure.microsoft.com/en-us/services/hdinsight/">Azure HDInsight</a>, and <a href="https://cloud.google.com/dataflow">Google Cloud Dataflow</a> (Google’s successor to classic MapReduce, built for both batch and streaming data).</p><h3>In Conclusion</h3><p>While MapReduce was a breakthrough, Spark has largely taken its place for most modern big data batch processing tasks. However, understanding MapReduce is still important because it gives you a solid foundation for understanding how these powerful tools work.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e900a20ee131" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/map-reduce-explained-with-example-system-design-e900a20ee131">Map Reduce explained with example | System Design</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>