<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Tewodros Birhanu]]></title><description><![CDATA[Tewodros Birhanu]]></description><link>https://onesamket.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!_1Xl!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ead260d-4554-4f31-836c-02b7835c58b4_96x96.jpeg</url><title>Tewodros Birhanu</title><link>https://onesamket.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sat, 30 May 2026 09:58:56 GMT</lastBuildDate><atom:link href="https://onesamket.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Tewodros Birhanu]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[onesamket@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[onesamket@substack.com]]></itunes:email><itunes:name><![CDATA[Tewodros Birhanu]]></itunes:name></itunes:owner><itunes:author><![CDATA[Tewodros Birhanu]]></itunes:author><googleplay:owner><![CDATA[onesamket@substack.com]]></googleplay:owner><googleplay:email><![CDATA[onesamket@substack.com]]></googleplay:email><googleplay:author><![CDATA[Tewodros Birhanu]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[The Event Loop: The Royal Sovereign of JavaScript ]]></title><description><![CDATA[Think of your JavaScript runtime as a bustling kingdom.]]></description><link>https://onesamket.substack.com/p/the-event-loop-the-royal-sovereign</link><guid isPermaLink="false">https://onesamket.substack.com/p/the-event-loop-the-royal-sovereign</guid><pubDate>Sun, 14 Dec 2025 09:12:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/dbe990e4-89e1-4792-99e9-73bb7ba54e94_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Think of your JavaScript runtime as a bustling kingdom. Code flows through its streets, promises are made, timeouts are set, and events wait to be heard. And presiding over this entire realm with elegant precision is the <strong>Event Loop</strong> &#8212; the undisputed sovereign who maintains order in what could easily become chaos.</p><h2><strong> Meet the Monarch</strong></h2><p>The Event Loop isn&#8217;t just another part of JavaScript&#8212;it&#8217;s the central organizing principle that makes asynchronous programming possible in a single-threaded world. Without this royal decree, your callbacks, promises, and async functions would descend into anarchy.</p><h2><strong>The Four Royal Edicts </strong></h2><h3><strong>1. First Commandment: Run All Synchronous Code</strong></h3><p>The Event Loop always begins by clearing the throne room (call stack) of all immediate business. Synchronous code gets royal priority&#8212;it&#8217;s executed immediately, from top to bottom, without delay.</p><p>javascript</p><pre><code>console.log(&#8221;Loyal subjects bow first&#8221;); // Immediate attention
const royalDecree = &#8220;Execute this now!&#8221;; // Processed at once
calculateTaxes(); // Handled on the spot</code></pre><h3><strong>2.  Second Commandment: Drain ALL Microtasks</strong></h3><p>Once the immediate business concludes, the Event Loop turns to its most trusted advisors: <strong>Microtasks</strong>. These include:</p><ul><li><p>Promise callbacks (<code>.then()</code>, <code>.catch()</code>, <code>.finally()</code>)</p></li><li><p><code>queueMicrotask()</code> operations</p></li><li><p><code>MutationObserver</code> callbacks</p></li></ul><p>The key here is <strong>ALL</strong>&#8212;every single microtask must be completed before anything else happens.</p><p>javascript</p><pre><code>Promise.resolve().then(() =&gt; {
  console.log(&#8221;Trusted advisor speaks first&#8221;);
});

queueMicrotask(() =&gt; {
  console.log(&#8221;Second advisor adds counsel&#8221;);
});

// All microtasks complete before ANY next macrotask runs</code></pre><h3><strong>3. Third Commandment: Run ONE Macrotask</strong></h3><p>After the microtask queue is completely empty, the sovereign permits <strong>exactly one</strong> macrotask to approach the throne. These include:</p><ul><li><p><code>setTimeout()</code> and <code>setInterval()</code> callbacks</p></li><li><p>DOM events (clicks, scrolls, inputs)</p></li><li><p>I/O operations</p></li><li><p>UI rendering</p></li></ul><p>javascript</p><pre><code>setTimeout(() =&gt; {
  console.log(&#8221;Messenger from distant land delivers news&#8221;);
}, 0);

button.addEventListener(&#8221;click&#8221;, () =&gt; {
  console.log(&#8221;A citizen&#8217;s petition is heard&#8221;);
});

// Only ONE of these runs per cycle, after ALL microtasks</code></pre><h3><strong>4. Fourth Commandment: Repeat Forever</strong></h3><p>The Event Loop continues this elegant dance indefinitely, maintaining perfect balance between urgency and patience, between immediate needs and scheduled business.</p><h2><strong>A Royal Procession in Action </strong></h2><p>javascript</p><pre><code>console.log(&#8221;Announcement from the throne!&#8221;); // 1&#65039;&#8419; Synchronous

Promise.resolve().then(() =&gt; {
  console.log(&#8221;Royal scribe records the decree&#8221;); // 2&#65039;&#8419; Microtask
});

setTimeout(() =&gt; {
  console.log(&#8221;Herald proclaims in the town square&#8221;); // 3&#65039;&#8419; Macrotask
}, 0);

console.log(&#8221;Court is adjourned&#8221;); // 1&#65039;&#8419; More synchronous

// Output order:
// 1. Announcement from the throne!
// 2. Court is adjourned  
// 3. Royal scribe records the decree
// 4. Herald proclaims in the town square</code></pre><h2><strong>Why This Reign Brings Peace </strong></h2><p>This elegant system prevents the common pitfalls of multithreading while allowing JavaScript to handle thousands of simultaneous operations. The Event Loop ensures that:</p><ul><li><p><strong>UI never freezes</strong> while waiting for network requests</p></li><li><p><strong>High-priority updates</strong> (promises) jump ahead of scheduled tasks</p></li><li><p><strong>Everything happens in a predictable order</strong></p></li><li><p><strong>Your application remains responsive</strong> no matter how many tasks await</p></li></ul><h2><strong>Paying Homage to the Sovereign </strong></h2><p>Next time you write asynchronous JavaScript, remember you&#8217;re working within a beautifully designed monarchy. The Event Loop isn&#8217;t a quirk or limitation&#8212;it&#8217;s an elegant solution that allows JavaScript to rule over the dynamic, event-driven world of web applications with grace and efficiency.</p><p></p>]]></content:encoded></item><item><title><![CDATA[Unknown vs any in TypeScript]]></title><description><![CDATA[Both any and unknown represent &#8220;any type of value&#8221; in TypeScript, but they have crucial differences in how they handle type safety.]]></description><link>https://onesamket.substack.com/p/unknown-vs-any-in-typescript</link><guid isPermaLink="false">https://onesamket.substack.com/p/unknown-vs-any-in-typescript</guid><dc:creator><![CDATA[Tewodros Birhanu]]></dc:creator><pubDate>Thu, 16 Oct 2025 10:34:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_1Xl!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ead260d-4554-4f31-836c-02b7835c58b4_96x96.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Both <code>any</code> and <code>unknown</code> represent &#8220;any type of value&#8221; in TypeScript, but they have <strong>crucial differences</strong> in how they handle type safety.</p><h2><code>any</code><strong> - The &#8220;Escape Hatch&#8221;</strong></h2><pre><code>// ANY: Opts out of type checking completely
let anything: any = &#8220;hello world&#8221;;

// All of these are allowed with NO type checking:
anything = 42;                    // OK
anything = true;                  // OK
anything = [1, 2, 3];            // OK
anything.toUpperCase();           // OK (but runtime error if not string)
anything.nonExistentMethod();     // OK (no compile-time error)
anything * 10;                    // OK

// This compiles fine but will crash at runtime:
function dangerousOperation(value: any) {
    return value.nonExistentProperty.anotherProperty.toUpperCase();
}
// No TypeScript error, but runtime error if called with wrong type</code></pre><h2><code>unknown</code><strong> - The Type-Safe Alternative</strong></h2><pre><code>// UNKNOWN: Type-safe way to handle uncertain types
let uncertainValue: unknown = &#8220;hello world&#8221;;

// These assignments are fine:
uncertainValue = 42;              // OK
uncertainValue = true;            // OK
uncertainValue = [1, 2, 3];      // OK

// But these operations are NOT allowed:
// uncertainValue.toUpperCase();        // &#10060; Error
// uncertainValue.nonExistentMethod();  // &#10060; Error  
// uncertainValue * 10;                 // &#10060; Error

// You MUST perform type checking first:
if (typeof uncertainValue === &#8220;string&#8221;) {
    console.log(uncertainValue.toUpperCase()); // &#9989; OK
}

if (typeof uncertainValue === &#8220;number&#8221;) {
    console.log(uncertainValue * 10); // &#9989; OK
}</code></pre><h2><strong>Key Differences</strong></h2><p><strong>Aspect</strong><code>anyunknown</code><strong>Type Safety</strong>&#10060; No type checking&#9989; Type-safe<strong>Assignment</strong>Can assign to anythingCan only assign to <code>any</code> or <code>unknown</code><strong>Operations</strong>Any operation allowedNo operations allowed without type checking<strong>Purpose</strong>Escape from type systemSafe handling of dynamic content</p><h2><strong>Practical Examples</strong></h2><h3><strong>Function Parameters</strong></h3><pre><code>// UNSAFE with any
function processDataAny(data: any) {
    // No type checking - potential runtime errors
    return data.name.toUpperCase() + data.age.toString();
}

// SAFE with unknown
function processDataUnknown(data: unknown) {
    // Must validate structure first
    if (typeof data === &#8216;object&#8217; &amp;&amp; data !== null &amp;&amp; &#8216;name&#8217; in data &amp;&amp; &#8216;age&#8217; in data) {
        const user = data as { name: string; age: number };
        return user.name.toUpperCase() + user.age.toString();
    }
    throw new Error(&#8221;Invalid data structure&#8221;);
}

// Even better with type guards
function isUserData(data: unknown): data is { name: string; age: number } {
    return (
        typeof data === &#8216;object&#8217; &amp;&amp;
        data !== null &amp;&amp;
        &#8216;name&#8217; in data &amp;&amp;
        &#8216;age&#8217; in data &amp;&amp;
        typeof (data as any).name === &#8216;string&#8217; &amp;&amp;
        typeof (data as any).age === &#8216;number&#8217;
    );
}

function processDataWithGuard(data: unknown) {
    if (isUserData(data)) {
        // TypeScript now knows data has name and age properties
        return data.name.toUpperCase() + data.age.toString();
    }
    throw new Error(&#8221;Invalid user data&#8221;);
}</code></pre><h3><strong>API Responses</strong></h3><pre><code>// Fetch data from external API (type is unknown)
async function fetchUserData(userId: string): Promise&lt;unknown&gt; {
    const response = await fetch(`/api/users/${userId}`);
    return response.json(); // We don&#8217;t know the exact type
}

// Process the unknown data safely
async function getUserName(userId: string): Promise&lt;string&gt; {
    const data = await fetchUserData(userId);
    
    if (typeof data === &#8216;object&#8217; &amp;&amp; data !== null &amp;&amp; &#8216;name&#8217; in data) {
        const name = (data as any).name;
        if (typeof name === &#8216;string&#8217;) {
            return name;
        }
    }
    
    throw new Error(&#8221;Invalid user data structure&#8221;);
}</code></pre><h3><strong>JSON Parsing</strong></h3><pre><code>// UNSAFE approach with any
function parseJsonUnsafe(json: string): any {
    return JSON.parse(json);
}

const unsafeResult = parseJsonUnsafe(&#8217;{&#8221;name&#8221;: &#8220;John&#8221;, &#8220;age&#8221;: 30}&#8217;);
console.log(unsafeResult.name); // No TypeScript error, but could be wrong

// SAFE approach with unknown
function parseJsonSafe&lt;T&gt;(json: string): unknown {
    return JSON.parse(json);
}

const safeResult = parseJsonSafe(&#8217;{&#8221;name&#8221;: &#8220;John&#8221;, &#8220;age&#8221;: 30}&#8217;);
// console.log(safeResult.name); // &#10060; Error: Property &#8216;name&#8217; does not exist on type &#8216;unknown&#8217;

// With validation
function parseAndValidateUser(json: string): { name: string; age: number } {
    const data = parseJsonSafe(json);
    
    if (
        typeof data === &#8216;object&#8217; &amp;&amp;
        data !== null &amp;&amp;
        &#8216;name&#8217; in data &amp;&amp;
        &#8216;age&#8217; in data &amp;&amp;
        typeof (data as any).name === &#8216;string&#8217; &amp;&amp;
        typeof (data as any).age === &#8216;number&#8217;
    ) {
        return data as { name: string; age: number };
    }
    
    throw new Error(&#8221;Invalid user data&#8221;);
}</code></pre><h2><strong>When to Use Each</strong></h2><h3><strong>Use </strong><code>any</code><strong> when:</strong></h3><ul><li><p>Migrating JavaScript code to TypeScript</p></li><li><p>Working with third-party libraries without types</p></li><li><p>In very specific cases where you truly need dynamic behavior</p></li><li><p></p></li></ul><pre><code>// Legacy code migration
const legacyData: any = getDataFromLegacySystem();

// Third-party library without types
declare const ThirdPartyLib: any;</code></pre><h3><strong>Use </strong><code>unknown</code><strong> when:</strong></h3><ul><li><p>Handling data from external sources (APIs, user input, etc.)</p></li><li><p>Writing library functions that accept arbitrary data</p></li><li><p>You want type safety but don&#8217;t know the type upfront</p></li></ul><p>typescript</p><pre><code>// Handling user input
function handleFormInput(input: unknown) {
    if (typeof input === &#8216;string&#8217;) {
        return input.trim();
    }
    if (typeof input === &#8216;number&#8217;) {
        return input.toString();
    }
    return &#8216;&#8217;;
}

// Generic data processing
function safeStringify(data: unknown): string {
    if (typeof data === &#8216;object&#8217; &amp;&amp; data !== null) {
        return JSON.stringify(data);
    }
    return String(data);
}</code></pre><h2><strong>Best Practices</strong></h2><pre><code>// &#9989; GOOD - Use unknown for external data
async function fetchData(url: string): Promise&lt;unknown&gt; {
    const response = await fetch(url);
    return response.json();
}

// &#9989; GOOD - Validate before use
function processApiResponse(response: unknown) {
    if (isValidResponse(response)) {
        // Now TypeScript knows the type
        return response.data;
    }
    throw new Error(&#8221;Invalid response&#8221;);
}

// &#10060; AVOID - Using any unnecessarily
function badFunction(data: any) {
    return data.whatever.you.want; // No safety!
}

// &#9989; BETTER - Use unknown with type guards
function betterFunction(data: unknown) {
    if (typeof data === &#8216;object&#8217; &amp;&amp; data !== null &amp;&amp; &#8216;whatever&#8217; in data) {
        // Proper type checking here
    }
}</code></pre><h2><strong>Type Narrowing with </strong><code>unknown</code></h2><p>typescript</p><pre><code>function handleValue(value: unknown) {
    // Type narrowing with typeof
    if (typeof value === &#8216;string&#8217;) {
        console.log(value.toUpperCase()); // value is string
    }
    else if (typeof value === &#8216;number&#8217;) {
        console.log(value.toFixed(2)); // value is number
    }
    else if (Array.isArray(value)) {
        console.log(value.length); // value is array
    }
    else if (value instanceof Date) {
        console.log(value.getFullYear()); // value is Date
    }
    else if (value === null) {
        console.log(&#8217;null value&#8217;); // value is null
    }
    else if (typeof value === &#8216;object&#8217; &amp;&amp; value !== null) {
        console.log(&#8217;object value&#8217;); // value is object
    }
}</code></pre><ul><li><p><code>any</code> = &#8220;I don&#8217;t care about type safety&#8221; </p></li><li><p><code>unknown</code> = &#8220;I don&#8217;t know the type yet, but I&#8217;ll check it&#8221; </p></li></ul>]]></content:encoded></item><item><title><![CDATA[How Express Rate Limiting Works]]></title><description><![CDATA[A rate limiter controls how many requests a user (usually identified by IP address) can make to your Express server within a certain time window.]]></description><link>https://onesamket.substack.com/p/how-express-rate-limiting-works</link><guid isPermaLink="false">https://onesamket.substack.com/p/how-express-rate-limiting-works</guid><dc:creator><![CDATA[Tewodros Birhanu]]></dc:creator><pubDate>Tue, 14 Oct 2025 21:21:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!wuJ8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wuJ8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wuJ8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!wuJ8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!wuJ8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!wuJ8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wuJ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1444498,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://onesamket.substack.com/i/176180673?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wuJ8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!wuJ8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!wuJ8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!wuJ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb6f8ac2-608f-4407-a1b1-bd3b712c1362_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>A <strong>rate limiter</strong> controls how many requests a user (usually identified by IP address) can make to your Express server within a certain time window.<br>This helps prevent <strong>abuse</strong>, <strong>DDoS attacks</strong>, and <strong>API overuse</strong>.</p><div><hr></div><h3>How It Works (Conceptually)</h3><p>A rate limiter tracks each client&#8217;s request count:</p><ol><li><p>When a request comes in, it looks up the client&#8217;s record (often using IP).</p></li><li><p>It checks:</p><ul><li><p>How many requests were made recently (within the current time window)</p></li><li><p>Whether the limit has been exceeded</p></li></ul></li><li><p>If within limit &#8594; request continues <br>If exceeded &#8594; request is blocked  (usually returns <strong>HTTP 429 Too Many Requests</strong>).</p></li></ol><div><hr></div><h3> Basic Example Using <code>express-rate-limit</code></h3><pre><code><code>import express from &#8216;express&#8217;;
import rateLimit from &#8216;express-rate-limit&#8217;;

const app = express();

// Create a rate limiter middleware
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100,                 // limit each IP to 100 requests per windowMs
  message: &#8216;Too many requests, please try again later.&#8217;,
  standardHeaders: true,    // Return rate limit info in the RateLimit-* headers
  legacyHeaders: false,     // Disable the X-RateLimit-* headers
});

// Apply limiter to all requests
app.use(limiter);

app.get(&#8217;/&#8217;, (req, res) =&gt; {
  res.send(&#8217;Hello, world!&#8217;);
});

app.listen(3000, () =&gt; console.log(&#8217;Server running on port 3000&#8217;));
</code></code></pre><div><hr></div><h3> What Happens Internally</h3><p>When a request hits:</p><ul><li><p>The middleware keeps an <strong>in-memory store</strong> (or Redis, if configured).</p></li><li><p>It increments a counter for the user&#8217;s IP.</p></li><li><p>It sets a <strong>TTL (time-to-live)</strong> for when that counter resets (e.g., 15 minutes).</p></li><li><p>If the counter &gt; <code>max</code>, it blocks the request.</p></li></ul><div><hr></div><h3> Customization</h3><p>You can customize the logic by:</p><ul><li><p>Using a custom <strong>store</strong> (Redis, MongoDB, etc.) to share limits across servers.</p></li><li><p>Applying limits <strong>per route</strong>, <strong>per API key</strong>, or <strong>per user</strong>.</p></li><li><p>Dynamically adjusting limits based on authentication or role.</p></li></ul><p>Example:</p><pre><code><code>app.use(&#8217;/api/login&#8217;, rateLimit({
  windowMs: 60 * 1000,
  max: 5,
  message: &#8216;Too many login attempts. Try again in a minute.&#8217;,
}));
</code></code></pre><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Nodejs core architecture]]></title><description><![CDATA[The core architecture of Node.js is a single-threaded event loop that uses an event-driven, non-blocking I/O model.]]></description><link>https://onesamket.substack.com/p/nodejs-core-architecture</link><guid isPermaLink="false">https://onesamket.substack.com/p/nodejs-core-architecture</guid><dc:creator><![CDATA[Tewodros Birhanu]]></dc:creator><pubDate>Tue, 14 Oct 2025 20:56:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!lrhR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The core architecture of Node.js is a <strong>single-threaded event loop</strong> that uses an <strong>event-driven</strong>, <strong>non-blocking I/O</strong> model. This architecture is designed to handle a large number of simultaneous connections efficiently, making it highly scalable for I/O-intensive applications</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lrhR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lrhR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!lrhR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!lrhR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!lrhR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lrhR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1455047,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://onesamket.substack.com/i/176178797?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lrhR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!lrhR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!lrhR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!lrhR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823ce9e6-c595-4427-8645-58edabfb352e_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h3><strong>Core Components Explained</strong></h3><p>The architecture consists of several key components that work together as shown in the diagram above:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://onesamket.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><ul><li><p><strong>Event Queue</strong>: Incoming client requests are first stored in the Event Queue before they are processed.</p></li><li><p><strong>Event Loop</strong>: This is the heart of the architecture. It is a single-threaded loop that continuously pulls requests from the queue and processes them. If a request involves a simple, <strong>non-blocking</strong> operation (like an I/O poll), the Event Loop handles it immediately. For <strong>blocking</strong> or complex operations (like reading a file or querying a database), the Event Loop offloads the task to the <strong>Thread Pool</strong>.</p></li><li><p><strong>Thread Pool</strong>: Unlike the main thread that runs the Event Loop, Node.js maintains a pool of auxiliary threads. When a complex task is offloaded by the Event Loop, a single thread from this pool is assigned to handle it, ensuring that the main thread remains unblocked.</p></li><li><p><strong>External Resources</strong>: These are system resources (like a file system, database, or other network services) that the Thread Pool uses to complete complex blocking operations</p></li></ul><h3><strong>The Power Behind the Scenes</strong></h3><p>This entire processing model is powered by a few critical technologies:</p><ul><li><p><strong>V8 JavaScript Engine</strong>: Developed by Google for Chrome, V8 is what compiles your JavaScript code directly into machine code for fast execution. It is responsible for Just-In-Time (JIT) compilation and memory management.</p></li><li><p><strong>libuv</strong>: This is a C library that implements the <strong>Event Loop</strong> and <strong>Thread Pool</strong>. It provides the abstraction for non-blocking I/O operations across different operating systems.</p></li><li><p><strong>Event-Driven Architecture</strong>: Node.js operates by reacting to events. You define callback functions (or use Promises/async-await) that are executed only when a specific event occurs, such as a request arriving or a file read being completed. This is more efficient than traditional models that waste resources waiting for tasks to finish</p></li></ul><h3><strong>Key Code Behavior</strong></h3><p>The difference between blocking and non-blocking operations is fundamental. Here&#8217;s a simple code example that demonstrates the non-blocking nature:</p><pre><code>const fs = require(&#8217;fs&#8217;);

console.log(&#8217;Start of code&#8217;); // This runs first

// Non-blocking file read. The callback is queued and executed later.
fs.readFile(&#8217;myfile.txt&#8217;, &#8216;utf8&#8217;, (err, data) =&gt; {
    if (err) throw err;
    console.log(&#8217;File contents received&#8217;); // This runs third, after the file is read
});

console.log(&#8217;End of code&#8217;); // This runs second, without waiting for the file read</code></pre><h3><strong>Ideal Use Cases and Caveats</strong></h3><p>This architecture gives Node.js significant advantages:</p><ul><li><p><strong>High Concurrency</strong>: It can handle thousands of concurrent connections (like for a chat app or a live notification system) with minimal overhead.</p></li><li><p><strong>Efficiency</strong>: It uses a single process and minimal memory compared to creating a new thread for each connection.</p></li></ul><p>However, it&#8217;s important to know its limitations:</p><ul><li><p><strong>CPU-Intensive Tasks</strong>: Since the Event Loop runs on a single thread, a long-running calculation (like image processing or complex mathematical computations) will block the loop, making the application unresponsive. For such tasks, it&#8217;s better to use <strong>Worker Threads</strong> or break the work into smaller chunks.</p></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://onesamket.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>