<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Fazal Mansuri</title>
    <description>The latest articles on Forem by Fazal Mansuri (@fazal_mansuri_).</description>
    <link>https://forem.com/fazal_mansuri_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2949287%2Fcf0675d7-fc54-4289-bbdc-92bc98944ffa.jpg</url>
      <title>Forem: Fazal Mansuri</title>
      <link>https://forem.com/fazal_mansuri_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fazal_mansuri_"/>
    <language>en</language>
    <item>
      <title>⚠️ Race Conditions in APIs - The Bug You Can’t See</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 18 Apr 2026 09:02:13 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/race-conditions-in-apis-the-bug-you-cant-see-5c0h</link>
      <guid>https://forem.com/fazal_mansuri_/race-conditions-in-apis-the-bug-you-cant-see-5c0h</guid>
      <description>&lt;p&gt;There's a category of bugs that don't show up in tests. They don't throw errors. They don't crash your server. They just silently corrupt your data at the exact moment two users do the same thing at the same time.&lt;/p&gt;

&lt;p&gt;That's a race condition.&lt;/p&gt;

&lt;p&gt;And if you've ever seen a user's account balance go wrong, a product's stock count go negative, or a post get double-liked - you've seen one in production.&lt;/p&gt;

&lt;p&gt;Let's break down exactly what's happening and how to fix it.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Is a Race Condition?
&lt;/h3&gt;

&lt;p&gt;A race condition happens when two concurrent operations read shared data, make a decision based on it, and write back — and neither knows the other exists.&lt;/p&gt;

&lt;p&gt;The classic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread A reads stock = 10
Thread B reads stock = 10
Thread A writes stock = 9  (decremented by 1)
Thread B writes stock = 9  (also decremented from 10 — wrong!)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two orders placed. One decrement applied. You just oversold your inventory.&lt;/p&gt;

&lt;p&gt;The reason this is invisible: each individual operation is correct. Thread A did nothing wrong. Thread B did nothing wrong. The bug lives in the &lt;em&gt;gap between the read and the write&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Real Scenario: The Inventory API
&lt;/h3&gt;

&lt;p&gt;Say you have an endpoint that handles a purchase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ❌ NOT safe under concurrent load&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;purchaseItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT stock FROM items WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"out of stock"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE items SET stock = $1 WHERE id = $2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks fine. In a single-user world, it is fine. But under load — say, a flash sale with 500 concurrent requests — the gap between &lt;code&gt;SELECT&lt;/code&gt; and &lt;code&gt;UPDATE&lt;/code&gt; is enough for dozens of threads to read the same stock value and all decrement from it simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Negative stock. Oversold orders. Angry customers.&lt;/p&gt;




&lt;h3&gt;
  
  
  Three Ways to Fix It
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Fix 1 — Atomic SQL Update (the simplest approach)
&lt;/h4&gt;

&lt;p&gt;The fastest fix is to eliminate the read-then-write pattern entirely and let the database handle the decrement atomically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ✅ Safe — single atomic statement&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
    UPDATE items
    SET stock = stock - 1
    WHERE id = $1 AND stock &amp;gt; 0
`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;rowsAffected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RowsAffected&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rowsAffected&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"out of stock or already taken"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No read. No gap. The database engine serializes this at the row level. This works well for simple decrements and is the right default when you don't need the old value.&lt;/p&gt;




&lt;h4&gt;
  
  
  Fix 2 — Pessimistic Locking (SELECT FOR UPDATE)
&lt;/h4&gt;

&lt;p&gt;When you genuinely need to read the value before deciding what to write — for example, checking business rules before an update — use &lt;code&gt;SELECT FOR UPDATE&lt;/code&gt; to hold a row lock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ✅ Safe — row is locked until transaction commits&lt;/span&gt;
&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BeginTx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// error handling omitted for brevity&lt;/span&gt;
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
    SELECT stock FROM items WHERE id = $1 FOR UPDATE
`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"out of stock"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE items SET stock = $1 WHERE id = $2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;FOR UPDATE&lt;/code&gt; tells the database: lock this row. Any other transaction that tries to read it with &lt;code&gt;FOR UPDATE&lt;/code&gt; will block until this one commits or rolls back. Completely safe — but it creates a queue, so it can become a bottleneck under heavy concurrent traffic.&lt;/p&gt;




&lt;h4&gt;
  
  
  Fix 3 — Optimistic Locking with CAS (Compare-And-Swap)
&lt;/h4&gt;

&lt;p&gt;Optimistic locking says: don't block anyone. Just verify before writing that the world still looks the way you expected when you read it.&lt;/p&gt;

&lt;p&gt;You add a &lt;code&gt;version&lt;/code&gt; column to the row, then make your update conditional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ✅ Safe — version mismatch causes retry, not corruption&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Stock&lt;/span&gt;   &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;purchaseWithCAS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;maxRetries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;maxRetries&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT id, stock, version FROM items WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
            &lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stock&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"out of stock"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
            UPDATE items
            SET stock = $1, version = $2
            WHERE id = $3 AND version = $4
        `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RowsAffected&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="c"&gt;// success&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c"&gt;// version mismatch — someone else wrote first, retry&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"too many concurrent modifications, try again"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If two threads both read &lt;code&gt;version=5&lt;/code&gt;, only the first one that writes &lt;code&gt;version=6&lt;/code&gt; wins. The second sees &lt;code&gt;rowsAffected=0&lt;/code&gt; and retries with a fresh read. No locks held, no blocking — just retry on conflict.&lt;/p&gt;




&lt;h3&gt;
  
  
  When to Use Which Fix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Best approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple increment/decrement&lt;/td&gt;
&lt;td&gt;Atomic SQL (&lt;code&gt;UPDATE ... SET x = x - 1&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex business logic before write&lt;/td&gt;
&lt;td&gt;Pessimistic locking (&lt;code&gt;SELECT FOR UPDATE&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-read, low-conflict workloads&lt;/td&gt;
&lt;td&gt;Optimistic locking (CAS + version)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed systems / no shared DB&lt;/td&gt;
&lt;td&gt;Distributed locks (Redis &lt;code&gt;SET NX&lt;/code&gt;, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  The Distributed Case: Redis to the Rescue
&lt;/h3&gt;

&lt;p&gt;When your API runs across multiple servers and the database lock isn't enough (or too slow), you need a distributed lock. Redis handles this elegantly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ✅ Distributed lock using Redis SET NX (set if not exists)&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;acquireLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetNX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lock:"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;releaseLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;rdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lock:"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;purchaseWithRedisLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;acquired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;acquireLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;acquired&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"could not acquire lock, try again"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;releaseLock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// safe to read and write now — only one server can be here at a time&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;purchaseItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;itemID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;SET NX&lt;/code&gt; command is atomic in Redis — only one caller gets &lt;code&gt;true&lt;/code&gt;. All others get &lt;code&gt;false&lt;/code&gt; and back off. The TTL ensures the lock is released even if your server crashes mid-operation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ One important caveat: &lt;code&gt;SET NX&lt;/code&gt; alone isn't enough for production. Use &lt;strong&gt;Redlock&lt;/strong&gt; (Redis's official distributed locking algorithm) when you need strong guarantees — especially if you have multiple Redis nodes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Summary: The Mental Model
&lt;/h3&gt;

&lt;p&gt;Race conditions happen in the gap between &lt;strong&gt;read&lt;/strong&gt; and &lt;strong&gt;write&lt;/strong&gt;. The longer that gap, the higher the chance of corruption. Your goal is to shrink or eliminate that gap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atomic operations&lt;/strong&gt; collapse the gap to zero.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pessimistic locks&lt;/strong&gt; block others from entering the gap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic locks&lt;/strong&gt; let everyone in but detect and reject stale writes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's no universally best answer. Pick the approach that matches your read/write ratio, your tolerance for blocking, and whether your system is distributed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A race condition is not a bug in any single thread — it's a bug in &lt;em&gt;timing&lt;/em&gt; between threads.&lt;/li&gt;
&lt;li&gt;Any "read, decide, write" pattern is vulnerable unless protected.&lt;/li&gt;
&lt;li&gt;The simplest fix is often a single atomic SQL statement — reach for it first.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SELECT FOR UPDATE&lt;/code&gt; is your safety net when you need business logic between the read and write.&lt;/li&gt;
&lt;li&gt;Optimistic locking with a version column is ideal for high-concurrency, low-conflict scenarios.&lt;/li&gt;
&lt;li&gt;In distributed systems, move to Redis-based locking.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Have you been bitten by a race condition in production? How did you track it down? Drop a comment - these bugs have some of the best war stories.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>backend</category>
      <category>database</category>
      <category>api</category>
      <category>security</category>
    </item>
    <item>
      <title>🚀 Feature Flags - The Secret Behind Safe Deployments</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 15 Mar 2026 07:49:04 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/feature-flags-the-secret-behind-safe-deployments-4ine</link>
      <guid>https://forem.com/fazal_mansuri_/feature-flags-the-secret-behind-safe-deployments-4ine</guid>
      <description>&lt;p&gt;Shipping software used to be risky.&lt;/p&gt;

&lt;p&gt;A new deployment could introduce bugs, break critical workflows or affect thousands (or millions) of users instantly.&lt;/p&gt;

&lt;p&gt;For many teams, releasing software meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploying late at night 🌙&lt;/li&gt;
&lt;li&gt;Monitoring dashboards anxiously 📊&lt;/li&gt;
&lt;li&gt;Hoping nothing breaks 🤞&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern engineering teams solved this problem using &lt;strong&gt;Feature Flags&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Feature flags allow developers to &lt;strong&gt;release code without immediately exposing new features to users&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of deploying and hoping everything works, teams can &lt;strong&gt;control feature visibility dynamically&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 What Are Feature Flags?
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;Feature Flag&lt;/strong&gt; (also called a &lt;strong&gt;Feature Toggle&lt;/strong&gt;) is a mechanism that &lt;strong&gt;enables or disables functionality in an application without deploying new code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;feature_flag_enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;show_new_feature&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;use_old_behavior&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application contains &lt;strong&gt;both code paths&lt;/strong&gt;, but the &lt;strong&gt;feature flag decides which one runs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This allows developers to &lt;strong&gt;separate deployment from release&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key idea:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt; → Shipping code to production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release&lt;/strong&gt; → Making the feature available to users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feature flags allow these two processes to happen &lt;strong&gt;independently&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xz6apnge29zrt51mbp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xz6apnge29zrt51mbp8.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  🎯 Why Feature Flags Matter
&lt;/h1&gt;

&lt;p&gt;Feature flags dramatically reduce the &lt;strong&gt;risk of releasing software&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without Feature Flags
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploy → Feature immediately live
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something breaks, the only option is &lt;strong&gt;rollback&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  With Feature Flags
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploy → Feature disabled → Enable gradually
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something goes wrong, simply &lt;strong&gt;turn the feature off&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No redeployment required.&lt;/p&gt;




&lt;h3&gt;
  
  
  Benefits of Feature Flags
&lt;/h3&gt;

&lt;p&gt;Feature flags enable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Safer releases&lt;/li&gt;
&lt;li&gt;✅ Gradual rollouts&lt;/li&gt;
&lt;li&gt;✅ Instant rollback&lt;/li&gt;
&lt;li&gt;✅ Production testing&lt;/li&gt;
&lt;li&gt;✅ Controlled experiments&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🛒 Real-World Example
&lt;/h1&gt;

&lt;p&gt;Imagine launching a &lt;strong&gt;new checkout system&lt;/strong&gt; for an e-commerce platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without Feature Flags
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploy new checkout → All users see it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If checkout fails → &lt;strong&gt;Revenue stops immediately&lt;/strong&gt; 💥&lt;/p&gt;




&lt;h3&gt;
  
  
  With Feature Flags
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploy new checkout → Feature disabled
Enable for 5% users
Monitor metrics
Gradually increase rollout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If problems appear, the feature can be &lt;strong&gt;disabled instantly&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧩 Types of Feature Flags
&lt;/h1&gt;

&lt;p&gt;Not all feature flags are used for the same purpose.&lt;/p&gt;

&lt;p&gt;Understanding their types helps design systems properly.&lt;/p&gt;




&lt;h1&gt;
  
  
  1️⃣ Release Flags
&lt;/h1&gt;

&lt;p&gt;Used to &lt;strong&gt;gradually release new features&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new_checkout_enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control feature rollout&lt;/li&gt;
&lt;li&gt;Reduce release risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Release flags are usually &lt;strong&gt;temporary&lt;/strong&gt; and removed once the feature is stable.&lt;/p&gt;




&lt;h1&gt;
  
  
  2️⃣ Experiment Flags (A/B Testing)
&lt;/h1&gt;

&lt;p&gt;Used for &lt;strong&gt;product experiments&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;checkout_variant_A
checkout_variant_B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users may see different versions of a feature.&lt;/p&gt;

&lt;p&gt;Metrics measured include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📈 Conversion rate&lt;/li&gt;
&lt;li&gt;📊 Engagement&lt;/li&gt;
&lt;li&gt;🔁 Retention&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  3️⃣ Operational Flags
&lt;/h1&gt;

&lt;p&gt;Used to &lt;strong&gt;control system behavior during incidents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;disable_recommendation_engine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a system starts failing, the feature can be &lt;strong&gt;disabled instantly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Operational flags are useful during &lt;strong&gt;production outages&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  4️⃣ Permission Flags
&lt;/h1&gt;

&lt;p&gt;Used to &lt;strong&gt;control access based on user roles&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;admin_dashboard_enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only certain users or roles see the feature.&lt;/p&gt;

&lt;p&gt;This is commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;internal tools&lt;/li&gt;
&lt;li&gt;beta programs&lt;/li&gt;
&lt;li&gt;admin dashboards&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚙️ Feature Flags vs Configuration Flags
&lt;/h1&gt;

&lt;p&gt;These concepts are often confused.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature Flags
&lt;/h3&gt;

&lt;p&gt;Used to control &lt;strong&gt;product functionality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temporary&lt;/li&gt;
&lt;li&gt;Used for rollouts&lt;/li&gt;
&lt;li&gt;Tied to releases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;enable_new_upload_ui&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Configuration Flags
&lt;/h3&gt;

&lt;p&gt;Used to control &lt;strong&gt;system configuration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usually permanent&lt;/li&gt;
&lt;li&gt;Not tied to releases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;max_upload_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;20MB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understanding this difference prevents &lt;strong&gt;misuse of feature flags&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧪 Simple Implementation Example (Go)
&lt;/h1&gt;

&lt;p&gt;Here is a simple feature flag example in Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FeatureFlags&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;NewCheckout&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="n"&gt;FeatureFlags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCheckout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;newCheckoutFlow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;oldCheckoutFlow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feature flag values may come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;configuration files&lt;/li&gt;
&lt;li&gt;environment variables&lt;/li&gt;
&lt;li&gt;databases&lt;/li&gt;
&lt;li&gt;remote config services&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🌐 Remote Feature Flag Systems
&lt;/h1&gt;

&lt;p&gt;In production, feature flags are often managed &lt;strong&gt;remotely&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Popular platforms include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LaunchDarkly&lt;/li&gt;
&lt;li&gt;Split&lt;/li&gt;
&lt;li&gt;Flagsmith&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These systems allow teams to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toggle features instantly ⚡&lt;/li&gt;
&lt;li&gt;target specific users 🎯&lt;/li&gt;
&lt;li&gt;monitor rollout metrics 📊&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No redeployment required.&lt;/p&gt;




&lt;h1&gt;
  
  
  📈 Gradual Rollouts
&lt;/h1&gt;

&lt;p&gt;One of the most powerful capabilities of feature flags is &lt;strong&gt;progressive rollout&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example rollout strategy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1% users → monitor
10% users → monitor
50% users → monitor
100% users → full release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This dramatically &lt;strong&gt;reduces release risk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Problems can be detected &lt;strong&gt;before the feature reaches everyone&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsiqdsjwleonnrr8uzsp2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsiqdsjwleonnrr8uzsp2.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  🎯 Targeted Rollouts
&lt;/h1&gt;

&lt;p&gt;Feature flags can also target &lt;strong&gt;specific user segments&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;internal employees&lt;/li&gt;
&lt;li&gt;beta testers&lt;/li&gt;
&lt;li&gt;specific countries&lt;/li&gt;
&lt;li&gt;premium users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;enable_feature&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enables &lt;strong&gt;testing directly in production environments&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🐤 Canary Releases
&lt;/h1&gt;

&lt;p&gt;Feature flags are commonly used with &lt;strong&gt;canary releases&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A canary release exposes a feature to a &lt;strong&gt;small subset of users first&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This helps detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;performance issues&lt;/li&gt;
&lt;li&gt;unexpected errors&lt;/li&gt;
&lt;li&gt;unusual user behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;before rolling it out globally.&lt;/p&gt;




&lt;h1&gt;
  
  
  🌑 Dark Launching
&lt;/h1&gt;

&lt;p&gt;Another advanced technique is &lt;strong&gt;Dark Launching&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The feature is deployed but &lt;strong&gt;hidden from users&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The system still runs the feature &lt;strong&gt;in the background&lt;/strong&gt; to test performance.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;recommendation_engine_running&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;recommendation_visible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps test infrastructure safely before exposing the feature.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚠️ The Hidden Problem: Feature Flag Debt
&lt;/h1&gt;

&lt;p&gt;Feature flags are powerful, but they introduce a new problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature Flag Debt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Over time, many flags remain in the codebase long after the feature is released.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;old_feature_flag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the feature is already permanent.&lt;/p&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;messy code&lt;/li&gt;
&lt;li&gt;confusion&lt;/li&gt;
&lt;li&gt;technical debt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flags should be &lt;strong&gt;removed once they are no longer needed&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🚨 Common Mistakes With Feature Flags
&lt;/h1&gt;

&lt;p&gt;Many teams misuse feature flags.&lt;/p&gt;

&lt;p&gt;Here are common pitfalls.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Flag Explosion
&lt;/h3&gt;

&lt;p&gt;Too many flags make systems difficult to understand.&lt;/p&gt;

&lt;p&gt;Every flag increases &lt;strong&gt;system complexity&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Flags in Performance-Critical Paths
&lt;/h3&gt;

&lt;p&gt;Checking flags in very hot paths may affect performance.&lt;/p&gt;

&lt;p&gt;Flag evaluation should be &lt;strong&gt;fast and lightweight&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Long-Lived Release Flags
&lt;/h3&gt;

&lt;p&gt;Release flags should be temporary.&lt;/p&gt;

&lt;p&gt;Once rollout finishes, remove them.&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣ Mixing Flags With Business Logic
&lt;/h3&gt;

&lt;p&gt;Feature flags should control &lt;strong&gt;behavior&lt;/strong&gt;, not implement complex logic.&lt;/p&gt;

&lt;p&gt;Avoid deeply nested conditions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;flagA&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;flagB&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;flagC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  ✅ Best Practices
&lt;/h1&gt;

&lt;p&gt;Successful teams follow several important practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Treat Flags as Temporary
&lt;/h3&gt;

&lt;p&gt;Every release flag should have an &lt;strong&gt;expiration plan&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Track Flag Ownership
&lt;/h3&gt;

&lt;p&gt;Each flag should have an &lt;strong&gt;owner responsible for cleanup&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Monitor Feature Rollouts
&lt;/h3&gt;

&lt;p&gt;Always observe metrics when enabling a feature.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;error rate&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;user behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4️⃣ Use Clear Naming
&lt;/h3&gt;

&lt;p&gt;Bad naming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flag123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better naming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;checkout_v2_release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clear names improve maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  5️⃣ Remove Flags After Release
&lt;/h3&gt;

&lt;p&gt;Cleaning up unused flags keeps the &lt;strong&gt;codebase healthy&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚡ Feature Flags Enable Modern DevOps
&lt;/h1&gt;

&lt;p&gt;Feature flags are a key component of &lt;strong&gt;modern engineering practices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They enable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 Continuous deployment&lt;/li&gt;
&lt;li&gt;🧪 Safe experimentation&lt;/li&gt;
&lt;li&gt;🔄 Instant rollbacks&lt;/li&gt;
&lt;li&gt;🎯 Controlled feature releases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of fearing deployments, teams can &lt;strong&gt;release features with confidence&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🏁 Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Feature flags fundamentally change how software is delivered.&lt;/p&gt;

&lt;p&gt;They transform deployments from &lt;strong&gt;risky events into controlled experiments&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But like any powerful tool, they must be used carefully.&lt;/p&gt;

&lt;p&gt;Without discipline, feature flags can create complexity and technical debt.&lt;/p&gt;

&lt;p&gt;When implemented correctly, they become &lt;strong&gt;one of the most powerful tools in a developer’s toolbox&lt;/strong&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Idempotency in APIs - Why Your Retry Logic Can Break Everything (And How to Fix It)</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 22 Feb 2026 11:22:55 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/idempotency-in-apis-why-your-retry-logic-can-break-everything-and-how-to-fix-it-345k</link>
      <guid>https://forem.com/fazal_mansuri_/idempotency-in-apis-why-your-retry-logic-can-break-everything-and-how-to-fix-it-345k</guid>
      <description>&lt;p&gt;Modern applications rely heavily on APIs. But networks are unreliable - requests fail, time out, or get retried.&lt;/p&gt;

&lt;p&gt;Now imagine this scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User clicks &lt;strong&gt;“Pay Now”&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Request sent to server&lt;/li&gt;
&lt;li&gt;Payment processed successfully&lt;/li&gt;
&lt;li&gt;But response is lost due to network issue&lt;/li&gt;
&lt;li&gt;Client retries the request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💥 Payment gets processed again. User is charged twice.&lt;/p&gt;

&lt;p&gt;This is one of the most dangerous and common problems in distributed systems.&lt;/p&gt;

&lt;p&gt;The solution? &lt;strong&gt;Idempotency.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What is Idempotency?
&lt;/h1&gt;

&lt;p&gt;An operation is &lt;strong&gt;idempotent&lt;/strong&gt; if performing it multiple times produces the same result as performing it once.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Same request → same effect → no duplicate side effects&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Order (without idempotency):
Request sent twice → 2 orders created ❌

Create Order (with idempotency):
Request sent twice → only 1 order created ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Idempotency ensures system correctness even when retries happen.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Do Retries Happen?
&lt;/h1&gt;

&lt;p&gt;Retries are extremely common due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network timeouts&lt;/li&gt;
&lt;li&gt;Server crashes&lt;/li&gt;
&lt;li&gt;Client retries&lt;/li&gt;
&lt;li&gt;Load balancers retrying requests&lt;/li&gt;
&lt;li&gt;Mobile networks instability&lt;/li&gt;
&lt;li&gt;API gateway retries&lt;/li&gt;
&lt;li&gt;Reverse proxy retries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Retries are normal. Duplicate side effects are not.&lt;/p&gt;




&lt;h1&gt;
  
  
  Which HTTP Methods Are Idempotent?
&lt;/h1&gt;

&lt;p&gt;According to HTTP specification:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Idempotent&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Fetch data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Replace resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Delete resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;Create resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PATCH&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;Partial update&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;POST is NOT idempotent by default.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /orders
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling twice → creates 2 orders.&lt;/p&gt;

&lt;p&gt;This must be handled explicitly.&lt;/p&gt;




&lt;h1&gt;
  
  
  Real-World Example: Payment API Problem
&lt;/h1&gt;

&lt;p&gt;Client sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /payments
{
  "user_id": "123",
  "amount": 100
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If client retries due to timeout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /payments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without idempotency → duplicate payment ❌&lt;/p&gt;

&lt;p&gt;With idempotency → single payment ✅&lt;/p&gt;




&lt;h1&gt;
  
  
  Solution: Idempotency Key
&lt;/h1&gt;

&lt;p&gt;Client sends a unique key with request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /payments
Idempotency-Key: abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Server behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If key is new → process request&lt;/li&gt;
&lt;li&gt;If key already exists → return previous result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guarantees single execution.&lt;/p&gt;




&lt;h1&gt;
  
  
  How Idempotency Works Internally
&lt;/h1&gt;

&lt;p&gt;Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client generates unique key&lt;/li&gt;
&lt;li&gt;Sends request with key&lt;/li&gt;
&lt;li&gt;Server checks database/cache for key&lt;/li&gt;
&lt;li&gt;If key exists → return stored response&lt;/li&gt;
&lt;li&gt;If not exists → process request&lt;/li&gt;
&lt;li&gt;Store key and response&lt;/li&gt;
&lt;li&gt;Return response&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  Go Implementation Example
&lt;/h1&gt;

&lt;p&gt;Let’s implement idempotent payment API using Go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database Table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idempotency_keys table:

key (primary key)
response
created_at
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Go Example (Basic Version)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;IdempotencyRecord&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handler Implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;PaymentHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Idempotency-Key"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Idempotency-Key required"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Check if key exists&lt;/span&gt;
    &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getIdempotencyRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Process payment&lt;/span&gt;
    &lt;span class="n"&gt;paymentID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"payment_id": "%s"}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paymentID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Store key and response&lt;/span&gt;
    &lt;span class="n"&gt;saveIdempotencyRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Example Flow
&lt;/h1&gt;

&lt;p&gt;First request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /payments
Idempotency-Key: abc123

Response:
{
  "payment_id": "pay_001"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retry request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /payments
Idempotency-Key: abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response returned from storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "payment_id": "pay_001"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No duplicate payment created.&lt;/p&gt;




&lt;h1&gt;
  
  
  Production Implementation Using Redis (Recommended)
&lt;/h1&gt;

&lt;p&gt;Redis is ideal because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extremely fast&lt;/li&gt;
&lt;li&gt;Supports expiration (TTL)&lt;/li&gt;
&lt;li&gt;Perfect for temporary idempotency storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Redis Example in Go
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;PaymentHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Idempotency-Key"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;redisClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;paymentID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"payment_id": "%s"}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paymentID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;redisClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Important: Handle Race Conditions
&lt;/h1&gt;

&lt;p&gt;Two requests may arrive simultaneously with same key.&lt;/p&gt;

&lt;p&gt;Solution: Use atomic operations.&lt;/p&gt;

&lt;p&gt;Redis example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET key value NX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NX = set only if not exists&lt;/p&gt;




&lt;h1&gt;
  
  
  Important Best Practice: Store Full Response
&lt;/h1&gt;

&lt;p&gt;Do not just store key.&lt;/p&gt;

&lt;p&gt;Store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;status code&lt;/li&gt;
&lt;li&gt;response body&lt;/li&gt;
&lt;li&gt;timestamp&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because retry must return exact same response.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Database Schema (PostgreSQL)
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;idempotency_keys&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Primary key ensures uniqueness.&lt;/p&gt;




&lt;h1&gt;
  
  
  Real-World Systems That Use Idempotency
&lt;/h1&gt;

&lt;p&gt;Critical systems use idempotency extensively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment APIs&lt;/li&gt;
&lt;li&gt;Order creation APIs&lt;/li&gt;
&lt;li&gt;Financial transactions&lt;/li&gt;
&lt;li&gt;Booking systems&lt;/li&gt;
&lt;li&gt;Wallet transfers&lt;/li&gt;
&lt;li&gt;Stripe payments&lt;/li&gt;
&lt;li&gt;Banking APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without idempotency, financial systems would break.&lt;/p&gt;




&lt;h1&gt;
  
  
  Common Mistake Developers Make
&lt;/h1&gt;

&lt;p&gt;❌ Using retry without idempotency&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;retry 3 times on failure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This multiplies side effects.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retry logic: 3 times
Result: 3 payments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dangerous bug.&lt;/p&gt;




&lt;h1&gt;
  
  
  Idempotency vs Duplicate Prevention Using Unique Constraints
&lt;/h1&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UNIQUE(user_id, order_id)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents duplicates at DB level.&lt;/p&gt;

&lt;p&gt;But idempotency is better because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works at API level&lt;/li&gt;
&lt;li&gt;Handles retries cleanly&lt;/li&gt;
&lt;li&gt;Returns same response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best approach: use BOTH.&lt;/p&gt;




&lt;h1&gt;
  
  
  When Should You Use Idempotency?
&lt;/h1&gt;

&lt;p&gt;Use idempotency for operations that create side effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment creation&lt;/li&gt;
&lt;li&gt;Order creation&lt;/li&gt;
&lt;li&gt;Wallet transfer&lt;/li&gt;
&lt;li&gt;Booking&lt;/li&gt;
&lt;li&gt;Resource creation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not required for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET requests&lt;/li&gt;
&lt;li&gt;Read-only operations&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  How Client Should Generate Idempotency Key
&lt;/h1&gt;

&lt;p&gt;Use UUID:&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;550e8400-e29b-41d4-a716-446655440000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unique per operation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Idempotency Key Expiration Strategy
&lt;/h1&gt;

&lt;p&gt;Keys should expire after some time.&lt;/p&gt;

&lt;p&gt;Common TTL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;24 hours&lt;/li&gt;
&lt;li&gt;48 hours&lt;/li&gt;
&lt;li&gt;7 days (depending on business need)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis makes expiration easy.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Architecture
&lt;/h1&gt;

&lt;p&gt;Client → API Gateway → Service → Redis → Database&lt;/p&gt;

&lt;p&gt;Redis handles idempotency keys&lt;br&gt;
Database handles actual data&lt;/p&gt;

&lt;p&gt;Fast and reliable.&lt;/p&gt;


&lt;h1&gt;
  
  
  Real Production Scenario: Mobile Network Retry
&lt;/h1&gt;

&lt;p&gt;Mobile user taps "Place Order"&lt;/p&gt;

&lt;p&gt;Network slow → timeout&lt;br&gt;
Client retries automatically&lt;/p&gt;

&lt;p&gt;Without idempotency → duplicate orders&lt;/p&gt;

&lt;p&gt;With idempotency → safe retry&lt;/p&gt;


&lt;h1&gt;
  
  
  Important Difference: Safe Retry vs Unsafe Retry
&lt;/h1&gt;

&lt;p&gt;Unsafe retry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /orders
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Safe retry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /orders
Idempotency-Key: unique-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Idempotency vs Exactly-Once Execution
&lt;/h1&gt;

&lt;p&gt;Exactly-once execution is impossible in distributed systems.&lt;/p&gt;

&lt;p&gt;Idempotency provides practical solution.&lt;/p&gt;

&lt;p&gt;It ensures same final state.&lt;/p&gt;




&lt;h1&gt;
  
  
  Best Practices Checklist
&lt;/h1&gt;

&lt;p&gt;Always:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use idempotency keys for POST APIs&lt;/li&gt;
&lt;li&gt;Store keys in Redis or database&lt;/li&gt;
&lt;li&gt;Store full response&lt;/li&gt;
&lt;li&gt;Use expiration&lt;/li&gt;
&lt;li&gt;Handle race conditions&lt;/li&gt;
&lt;li&gt;Use UUID keys&lt;/li&gt;
&lt;li&gt;Combine with database constraints&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Key Takeaway
&lt;/h1&gt;

&lt;p&gt;Retries are normal.&lt;/p&gt;

&lt;p&gt;Duplicate side effects are dangerous.&lt;/p&gt;

&lt;p&gt;Idempotency ensures your APIs remain safe, reliable, and production-ready.&lt;/p&gt;

&lt;p&gt;It is not optional for critical APIs - it is essential.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thought
&lt;/h1&gt;

&lt;p&gt;If your API handles payments, orders, bookings, or financial transactions - idempotency is mandatory.&lt;/p&gt;

&lt;p&gt;Without it, retries can silently corrupt your system.&lt;/p&gt;

&lt;p&gt;With it, your APIs become reliable, predictable, and safe.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>api</category>
      <category>microservices</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🚀 UUIDv4 vs UUIDv7 in PostgreSQL</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 08 Feb 2026 16:40:01 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/uuidv4-vs-uuidv7-in-postgresql-2m0l</link>
      <guid>https://forem.com/fazal_mansuri_/uuidv4-vs-uuidv7-in-postgresql-2m0l</guid>
      <description>&lt;h3&gt;
  
  
  Why Switching UUID Versions Can Boost Performance at Scale
&lt;/h3&gt;

&lt;p&gt;Many teams choose UUIDs as primary keys to support distributed systems and avoid ID collisions.&lt;br&gt;
But &lt;strong&gt;not all UUIDs are equal&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some teams have seen &lt;strong&gt;10×–50× performance improvements&lt;/strong&gt; simply by switching from &lt;strong&gt;UUIDv4 to UUIDv7&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sounds surprising?&lt;br&gt;
Let’s break it down - step by step - with &lt;strong&gt;no hand-waving&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 What This Blog Will Help You Decide
&lt;/h2&gt;

&lt;p&gt;By the end, you’ll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What UUIDv4 and UUIDv7 actually are&lt;/li&gt;
&lt;li&gt;How PostgreSQL indexes work internally&lt;/li&gt;
&lt;li&gt;Why random IDs hurt performance&lt;/li&gt;
&lt;li&gt;Why UUIDv7 scales dramatically better&lt;/li&gt;
&lt;li&gt;When you should (and shouldn’t) switch&lt;/li&gt;
&lt;li&gt;How to benchmark this yourself&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1️⃣ Quick Refresher: What Is a UUID?
&lt;/h2&gt;

&lt;p&gt;A UUID (Universally Unique Identifier) is a &lt;strong&gt;128-bit value&lt;/strong&gt; designed to be globally unique.&lt;/p&gt;

&lt;p&gt;Why developers use UUIDs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safe for distributed systems&lt;/li&gt;
&lt;li&gt;Can be generated client-side&lt;/li&gt;
&lt;li&gt;No central ID generator&lt;/li&gt;
&lt;li&gt;Avoids ID collisions across services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PostgreSQL stores UUIDs efficiently (16 bytes), so &lt;strong&gt;UUIDs themselves are not slow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 The &lt;strong&gt;problem is the insertion pattern&lt;/strong&gt;, not the type.&lt;/p&gt;


&lt;h2&gt;
  
  
  2️⃣ UUIDv4 - Random by Design
&lt;/h2&gt;
&lt;h3&gt;
  
  
  How UUIDv4 Works
&lt;/h3&gt;

&lt;p&gt;UUIDv4 is &lt;strong&gt;purely random&lt;/strong&gt; (122 random bits).&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;9f1c0d3a-4b6e-4b8f-8f91-17e0a0c9a721
e2a31f8b-91f2-4df7-98cb-6e9fcae721aa
0d2c5f99-5d8c-4b6d-8a0e-2dbbfa17d441
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No ordering&lt;/li&gt;
&lt;li&gt;No timestamp&lt;/li&gt;
&lt;li&gt;Completely scattered values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This randomness is &lt;strong&gt;great for uniqueness&lt;/strong&gt;&lt;br&gt;
…but &lt;strong&gt;terrible for database indexes&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  3️⃣ UUIDv7 - Time-Ordered UUIDs
&lt;/h2&gt;

&lt;p&gt;UUIDv7 is a &lt;strong&gt;newer standard&lt;/strong&gt; designed specifically for modern databases.&lt;/p&gt;
&lt;h3&gt;
  
  
  How UUIDv7 Works
&lt;/h3&gt;

&lt;p&gt;UUIDv7 combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;timestamp (milliseconds)&lt;/strong&gt; in the most significant bits&lt;/li&gt;
&lt;li&gt;Random bits for uniqueness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example (simplified):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;018f3b3a-9b5c-7d12-bc01-9a2cfe123456
018f3b3a-9b5d-7f44-a231-acde441298ab
018f3b3a-9b5e-82a1-9d22-acde112341aa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mostly increasing over time&lt;/li&gt;
&lt;li&gt;Still globally unique&lt;/li&gt;
&lt;li&gt;Still safe for distributed systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This ordering changes everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ How PostgreSQL Stores and Indexes Data (Critical Part)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PostgreSQL Table Storage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rows are stored in a &lt;strong&gt;heap&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Order in heap is not guaranteed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PostgreSQL Indexes
&lt;/h3&gt;

&lt;p&gt;Primary keys use &lt;strong&gt;B-tree indexes&lt;/strong&gt; by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ What Is a B-Tree (In Simple Terms)
&lt;/h2&gt;

&lt;p&gt;A B-tree:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stores keys in &lt;strong&gt;sorted order&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is optimized for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sequential inserts&lt;/li&gt;
&lt;li&gt;Range scans&lt;/li&gt;
&lt;li&gt;Cache-friendly access&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Think of it like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A well-organized book where new pages are best added at the end.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6️⃣ Why UUIDv4 Hurts PostgreSQL Performance
&lt;/h2&gt;

&lt;p&gt;With UUIDv4:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each new ID belongs &lt;strong&gt;somewhere random&lt;/strong&gt; in the index&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PostgreSQL must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find the correct position&lt;/li&gt;
&lt;li&gt;Split pages frequently&lt;/li&gt;
&lt;li&gt;Rebalance the tree&lt;/li&gt;
&lt;li&gt;Touch random memory pages&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Consequences:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Heavy page splits&lt;/li&gt;
&lt;li&gt;Index fragmentation&lt;/li&gt;
&lt;li&gt;Poor cache locality&lt;/li&gt;
&lt;li&gt;Increased disk I/O&lt;/li&gt;
&lt;li&gt;Slower inserts&lt;/li&gt;
&lt;li&gt;Slower reads&lt;/li&gt;
&lt;li&gt;Slower vacuum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gets &lt;strong&gt;worse as the table grows&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  7️⃣ Why UUIDv7 Is Fast
&lt;/h2&gt;

&lt;p&gt;With UUIDv7:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New rows are &lt;strong&gt;mostly appended&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Inserts hit the &lt;strong&gt;rightmost leaf page&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Minimal page splits&lt;/li&gt;
&lt;li&gt;Excellent cache locality&lt;/li&gt;
&lt;li&gt;Sequential disk writes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is very similar to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BIGSERIAL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IDENTITY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Snowflake-style IDs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 PostgreSQL &lt;em&gt;loves&lt;/em&gt; this pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  8️⃣ Why Teams See 10×–50× Improvements
&lt;/h2&gt;

&lt;p&gt;At scale (millions of rows):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;UUIDv4&lt;/th&gt;
&lt;th&gt;UUIDv7&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Insert latency&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index size&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;td&gt;Smaller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache efficiency&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page splits&lt;/td&gt;
&lt;td&gt;Frequent&lt;/td&gt;
&lt;td&gt;Rare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vacuum cost&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;⚠️ Important note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50× is workload-dependent&lt;/li&gt;
&lt;li&gt;Typical gains are &lt;strong&gt;5×–20×&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Still very significant&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9️⃣ Hands-On Benchmark (You Can Try This)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Table Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;test_uuid_v4&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;test_uuid_v7&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Insert UUIDv4
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;test_uuid_v4&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;generate_series&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Insert UUIDv7 (Postgres 16+ or extension)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;test_uuid_v7&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;uuidv7&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;generate_series&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;UUIDv7 generation requires Postgres 18 (&lt;code&gt;uuidv7()&lt;/code&gt;) or an extension such as &lt;code&gt;pg_uuidv7&lt;/code&gt; in earlier versions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Observe:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Insert time&lt;/li&gt;
&lt;li&gt;Index size&lt;/li&gt;
&lt;li&gt;CPU usage&lt;/li&gt;
&lt;li&gt;Disk writes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UUIDv7 inserts are dramatically smoother&lt;/li&gt;
&lt;li&gt;Index size is smaller&lt;/li&gt;
&lt;li&gt;Less I/O pressure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 Why This Matters in Real Systems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Backend Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Faster writes&lt;/li&gt;
&lt;li&gt;Better read performance&lt;/li&gt;
&lt;li&gt;Healthier indexes&lt;/li&gt;
&lt;li&gt;Lower infrastructure cost&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;IDs sort naturally by creation time&lt;/li&gt;
&lt;li&gt;Easier pagination&lt;/li&gt;
&lt;li&gt;Better caching behavior&lt;/li&gt;
&lt;li&gt;Cleaner URLs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ When UUIDv7 Is NOT the Right Choice
&lt;/h2&gt;

&lt;p&gt;Be honest and balanced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you need &lt;strong&gt;fully random IDs&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If timestamp leakage is a concern&lt;/li&gt;
&lt;li&gt;If your dataset is small&lt;/li&gt;
&lt;li&gt;If sequential IDs are unacceptable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UUIDv7 is a &lt;strong&gt;performance trade-off&lt;/strong&gt;, not magic.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This performance boost isn’t accidental — it’s &lt;strong&gt;how databases work&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The takeaway:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL B-trees love ordered inserts&lt;/li&gt;
&lt;li&gt;UUIDv4 is random → bad at scale&lt;/li&gt;
&lt;li&gt;UUIDv7 is time-ordered → excellent at scale&lt;/li&gt;
&lt;li&gt;Schema design decisions matter more than hardware&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing the right ID strategy early can save &lt;strong&gt;years of performance tuning later&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;Have you used UUIDv4 in production and faced scaling issues?&lt;/strong&gt;&lt;br&gt;
Or already switched to UUIDv7?&lt;/p&gt;

&lt;p&gt;Let’s discuss — real-world experiences help everyone.&lt;/p&gt;




</description>
      <category>database</category>
      <category>performance</category>
      <category>postgres</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>⚠️ JavaScript Precision Loss with Large Numbers - The silent bug that breaks applications without error</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Thu, 25 Dec 2025 11:52:48 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/javascript-precision-loss-with-large-numbers-the-silent-bug-that-breaks-applications-without-4lhg</link>
      <guid>https://forem.com/fazal_mansuri_/javascript-precision-loss-with-large-numbers-the-silent-bug-that-breaks-applications-without-4lhg</guid>
      <description>&lt;p&gt;Imagine this scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend API returns a &lt;strong&gt;perfectly correct number&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Network tab shows the correct value&lt;/li&gt;
&lt;li&gt;No errors, no warnings&lt;/li&gt;
&lt;li&gt;But your frontend logic behaves &lt;strong&gt;incorrectly&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hours of debugging later…&lt;br&gt;
You realize the number &lt;strong&gt;changed automatically&lt;/strong&gt; 😨&lt;/p&gt;

&lt;p&gt;Welcome to &lt;strong&gt;JavaScript precision loss&lt;/strong&gt; - one of the most dangerous &lt;em&gt;silent&lt;/em&gt; bugs in web development.&lt;/p&gt;

&lt;p&gt;This blog explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❓ Why this happens&lt;/li&gt;
&lt;li&gt;💥 How it silently breaks applications&lt;/li&gt;
&lt;li&gt;🔍 How to detect it&lt;/li&gt;
&lt;li&gt;🛠 How to fix it (frontend &amp;amp; backend)&lt;/li&gt;
&lt;li&gt;🧠 What both frontend and backend developers must know&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧠 The Root Cause: JavaScript Number Limit
&lt;/h2&gt;

&lt;p&gt;JavaScript has &lt;strong&gt;only one numeric type&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, it uses &lt;strong&gt;IEEE-754 double-precision floating-point format&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means JavaScript can safely represent integers only up to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_SAFE_INTEGER&lt;/span&gt;
&lt;span class="c1"&gt;// 9007199254740991&lt;/span&gt;
&lt;span class="c1"&gt;// which is 2^53 - 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anything &lt;strong&gt;greater than this&lt;/strong&gt; loses precision.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 The Problem in Real APIs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example API response (from backend):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transactionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9007199254740993&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This value is &lt;strong&gt;valid&lt;/strong&gt;, &lt;strong&gt;correct&lt;/strong&gt; and often used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database IDs&lt;/li&gt;
&lt;li&gt;Transaction numbers&lt;/li&gt;
&lt;li&gt;Order references&lt;/li&gt;
&lt;li&gt;Snowflake IDs&lt;/li&gt;
&lt;li&gt;Big integers from other systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 What You See in the Browser
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🟢 Network → Response tab
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transactionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9007199254740993&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks perfect ✔️&lt;/p&gt;

&lt;h3&gt;
  
  
  🔴 Network → Preview tab (parsed by JS)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transactionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9007199254740992&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💥 &lt;strong&gt;Boom - value changed silently&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No error&lt;br&gt;
No warning&lt;br&gt;
Just wrong data&lt;/p&gt;


&lt;h2&gt;
  
  
  😱 The Shocking Proof
&lt;/h2&gt;

&lt;p&gt;Try this in the browser console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;9007199254740993&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;9007199254740992&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 &lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes. Two different numbers are considered &lt;strong&gt;equal&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s how dangerous this is.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Why This Is So Dangerous
&lt;/h2&gt;

&lt;p&gt;This bug:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Does NOT throw errors&lt;/li&gt;
&lt;li&gt;❌ Does NOT break the UI immediately&lt;/li&gt;
&lt;li&gt;❌ Does NOT show warnings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break ID-based logic&lt;/li&gt;
&lt;li&gt;Send wrong IDs in the next API call&lt;/li&gt;
&lt;li&gt;Fail updates / deletes silently&lt;/li&gt;
&lt;li&gt;Corrupt data flows&lt;/li&gt;
&lt;li&gt;Cause production-only bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And debugging becomes a nightmare because:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The backend sent the correct value.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which is &lt;strong&gt;true&lt;/strong&gt; - but irrelevant.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Where It Breaks Exactly
&lt;/h2&gt;

&lt;p&gt;The precision loss happens during:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript parses JSON numbers into &lt;code&gt;Number&lt;/code&gt;, and the precision is already lost &lt;strong&gt;at parse time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By the time your code runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactionId&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The damage is already done.&lt;/p&gt;




&lt;h2&gt;
  
  
  👨‍💻 Backend Developers: This Is Also Your Responsibility
&lt;/h2&gt;

&lt;p&gt;If your API schema includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IDs&lt;/li&gt;
&lt;li&gt;Counters&lt;/li&gt;
&lt;li&gt;Financial values&lt;/li&gt;
&lt;li&gt;Any number that may exceed &lt;code&gt;2^53 - 1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❌ Returning them as JSON numbers is unsafe.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Best Backend Practice
&lt;/h3&gt;

&lt;p&gt;Return large numeric identifiers as &lt;strong&gt;strings&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transactionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9007199254740993"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids precision loss entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧑‍💻 Frontend Developers: What If Backend Can’t Change?
&lt;/h2&gt;

&lt;p&gt;Sometimes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API is legacy&lt;/li&gt;
&lt;li&gt;Schema cannot be changed&lt;/li&gt;
&lt;li&gt;Third-party API returns big numbers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You still need a solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 The Solution: &lt;code&gt;json-bigint&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;json-bigint&lt;/code&gt; is a &lt;a href="https://github.com/sidorares/json-bigint" rel="noopener noreferrer"&gt;library&lt;/a&gt; that parses JSON &lt;strong&gt;without losing precision&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;json-bigint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;JSONbig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json-bigint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSONbig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiResponseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large numbers are preserved&lt;/li&gt;
&lt;li&gt;You can handle them safely&lt;/li&gt;
&lt;li&gt;No silent corruption&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can choose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BigInt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;String representation&lt;/li&gt;
&lt;li&gt;Custom handling logic&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Important Things to Remember
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ BigInt is NOT JSON-serializable
&lt;/h3&gt;

&lt;p&gt;You must convert it before sending back to APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Mixing Number &amp;amp; BigInt throws errors
&lt;/h3&gt;

&lt;p&gt;Be consistent in comparisons and calculations.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ IDs ≠ numbers
&lt;/h3&gt;

&lt;p&gt;Treat IDs as &lt;strong&gt;identifiers&lt;/strong&gt;, not math values.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 How to Debug This Faster Next Time
&lt;/h2&gt;

&lt;p&gt;If you suspect precision issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check &lt;strong&gt;Network → Response&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Compare with &lt;strong&gt;Network → Preview&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Log raw response text&lt;/li&gt;
&lt;li&gt;Compare values with strict equality&lt;/li&gt;
&lt;li&gt;Check against &lt;code&gt;Number.MAX_SAFE_INTEGER&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This can save &lt;strong&gt;hours of debugging&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This bug is dangerous because it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Looks harmless&lt;/li&gt;
&lt;li&gt;Produces no errors&lt;/li&gt;
&lt;li&gt;Corrupts data silently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you know it, you’ll &lt;strong&gt;never forget it&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript numbers have limits&lt;/li&gt;
&lt;li&gt;APIs must respect client constraints&lt;/li&gt;
&lt;li&gt;Large IDs should be strings&lt;/li&gt;
&lt;li&gt;Silent bugs are the most expensive bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this post helped you learn something new, you’re already ahead of many developers.&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Have you ever faced a bug where everything “looked correct” but wasn’t?&lt;/strong&gt;&lt;br&gt;
Drop your experience - let’s learn from each other.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>backend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🚨 Memory Leaks in JavaScript &amp; React - The Hidden Enemy</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 14 Dec 2025 14:07:11 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/memory-leaks-in-javascript-react-the-hidden-enemy-74p</link>
      <guid>https://forem.com/fazal_mansuri_/memory-leaks-in-javascript-react-the-hidden-enemy-74p</guid>
      <description>&lt;p&gt;Memory leaks are tricky. You don’t see them immediately. Your UI works fine… until it &lt;strong&gt;doesn’t&lt;/strong&gt;.&lt;br&gt;
A few minutes, hours, or days later -&lt;/p&gt;

&lt;p&gt;❌ the app becomes slow&lt;br&gt;
❌ scrolling lags&lt;br&gt;
❌ typing delays&lt;br&gt;
❌ CPU usage spikes&lt;br&gt;
❌ mobile devices heat up or crash&lt;/p&gt;

&lt;p&gt;And the worst part?&lt;br&gt;
&lt;strong&gt;The bug is invisible. No errors. No warnings. Nothing in the console.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This blog will reveal &lt;em&gt;exactly&lt;/em&gt; why memory leaks happen in JavaScript &amp;amp; React, how to avoid them, how to debug them, and real mistakes developers make in production.&lt;/p&gt;

&lt;p&gt;Let’s dive in 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 1. What Is a Memory Leak?
&lt;/h2&gt;

&lt;p&gt;A memory leak happens when your program &lt;strong&gt;keeps holding onto memory it no longer needs&lt;/strong&gt;, preventing the browser from freeing it.&lt;br&gt;
JS uses automatic garbage collection - but GC can only help if memory becomes unreachable.&lt;/p&gt;

&lt;p&gt;If something &lt;em&gt;still references&lt;/em&gt; that memory → leak.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 2. Why Memory Leaks Happen in JavaScript
&lt;/h2&gt;

&lt;p&gt;JavaScript leaks commonly come from:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Global variables&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never cleared → stored forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Closures storing unnecessary data&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;heavy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;big&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The closure keeps &lt;code&gt;big&lt;/code&gt; alive.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Event listeners not removed&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// never removed → stays in memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4️⃣ Timers not cleared&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// still running even when component unmounted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;5️⃣ DOM references stored in JS&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;elems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// Even if 'box' is removed from DOM, elems still holds reference → leak&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚛️ 3. Memory Leaks in React - Real Reasons They Happen
&lt;/h2&gt;

&lt;p&gt;React helps prevent leaks…&lt;br&gt;
…but leaks still happen when &lt;em&gt;side effects&lt;/em&gt; run incorrectly.&lt;/p&gt;

&lt;p&gt;Here are the most common sources:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 3.1 Not cleaning up useEffect
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ❌ Leak example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;running...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After component unmount → interval continues → leak.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Fix:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;running...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Cleanup: clear interval when component unmounts&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧩 3.2 Event listeners inside components
&lt;/h3&gt;

&lt;h3&gt;
  
  
  ❌ Leak:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Fix:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧩 3.3 Async calls setting state after unmount
&lt;/h3&gt;

&lt;p&gt;This is one of the MOST common leaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the user navigates away →&lt;br&gt;
React tries to update state on an unmounted component → memory leak + warning.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Fix:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AbortError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧩 3.4 Huge arrays stored in state
&lt;/h3&gt;

&lt;p&gt;React re-renders + stores stale copies.&lt;/p&gt;

&lt;p&gt;❌ Storing large datasets in state&lt;br&gt;
❌ Duplicating arrays on every update&lt;br&gt;
❌ Logging huge objects inside useEffect&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 Fix:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use pagination&lt;/li&gt;
&lt;li&gt;Use memoization (&lt;code&gt;useMemo&lt;/code&gt;) for expensive computations&lt;/li&gt;
&lt;li&gt;Avoid storing raw API responses if unnecessary&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧩 3.5 Memory Leaks with React Strict Mode
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;React Strict Mode intentionally runs effects twice in development.&lt;/strong&gt;&lt;br&gt;
If cleanup logic is wrong → leaks appear in dev only.&lt;br&gt;
⚠️ This doesn't happen in production, but fixing cleanup issues prevents real leaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 4. Debugging Memory Leaks - Chrome DevTools (Simplest Guide)
&lt;/h2&gt;

&lt;p&gt;This is the part devs struggle with.&lt;br&gt;
Here is a &lt;strong&gt;beginner-friendly&lt;/strong&gt; flow:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Open Performance Monitor&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Chrome → More Tools → &lt;strong&gt;Performance Monitor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS Heap Size&lt;/li&gt;
&lt;li&gt;DOM Nodes&lt;/li&gt;
&lt;li&gt;Event Listeners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these numbers keep increasing → leak.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Take a Heap Snapshot&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DevTools → &lt;strong&gt;Memory tab&lt;/strong&gt; → Take Heap Snapshot&lt;/p&gt;

&lt;p&gt;Then repeat after performing interactions.&lt;/p&gt;

&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detached HTML elements&lt;/li&gt;
&lt;li&gt;Large arrays&lt;/li&gt;
&lt;li&gt;Retained closures&lt;/li&gt;
&lt;li&gt;Growing listeners&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Check Event Listeners&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DevTools → Elements → Event Listeners&lt;/p&gt;

&lt;p&gt;If the number keeps increasing on rerender → leak.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛡 5. Preventing Memory Leaks - Best Practices
&lt;/h2&gt;

&lt;h4&gt;
  
  
  ✔ Always clean up useEffect
&lt;/h4&gt;

&lt;h4&gt;
  
  
  ✔ Avoid storing huge data in state
&lt;/h4&gt;

&lt;h4&gt;
  
  
  ✔ Use paginated API responses
&lt;/h4&gt;

&lt;h4&gt;
  
  
  ✔ Use AbortController to cancel fetch
&lt;/h4&gt;

&lt;h4&gt;
  
  
  ✔ Throttle expensive events
&lt;/h4&gt;

&lt;h4&gt;
  
  
  ✔ Use profiling tools regularly
&lt;/h4&gt;




&lt;h2&gt;
  
  
  🧨 6. Real-World Example - A Leak That Happened in Production
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;A dashboard had multiple charts&lt;/li&gt;
&lt;li&gt;Each chart added a &lt;code&gt;resize&lt;/code&gt; listener&lt;/li&gt;
&lt;li&gt;Rerender recreated listeners&lt;/li&gt;
&lt;li&gt;Old listeners remained&lt;/li&gt;
&lt;li&gt;50+ listeners running simultaneously&lt;/li&gt;
&lt;li&gt;Browser froze after 10 minutes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; cleanup logic in useEffect + throttling resize events.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Memory leaks are scary because you don’t notice them immediately - but the impact is real.&lt;br&gt;
React apps slow down, mobile users suffer, and debugging becomes painful.&lt;/p&gt;

&lt;p&gt;But the good news?&lt;/p&gt;

&lt;p&gt;👉 Once you understand how leaks happen&lt;br&gt;
👉 And how to avoid them&lt;br&gt;
👉 You can prevent 95% of them permanently&lt;/p&gt;

&lt;p&gt;Your UI becomes faster, cleaner, smoother - and much easier to maintain.&lt;/p&gt;




</description>
      <category>javascript</category>
      <category>performance</category>
      <category>react</category>
    </item>
    <item>
      <title>⚛️ Controlled vs Uncontrolled Components in React – A Deep Dive</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 16 Nov 2025 09:22:37 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/controlled-vs-uncontrolled-components-in-react-a-deep-dive-1hhb</link>
      <guid>https://forem.com/fazal_mansuri_/controlled-vs-uncontrolled-components-in-react-a-deep-dive-1hhb</guid>
      <description>&lt;p&gt;When building forms in React, you’ll inevitably come across &lt;strong&gt;controlled&lt;/strong&gt; and &lt;strong&gt;uncontrolled&lt;/strong&gt; components.&lt;br&gt;
At first glance, they look similar — both accept user input and manage form data.&lt;br&gt;
But how they manage that data under the hood can significantly impact &lt;strong&gt;performance, maintainability and UX&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, let’s break down the difference, see them in action, explore real-world issues (like cursor position and undo/redo bugs), and understand when to use each.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 What Are Controlled Components?
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;controlled components&lt;/strong&gt;, React state is the &lt;strong&gt;single source of truth&lt;/strong&gt;.&lt;br&gt;
That means every keystroke or change updates the component’s state and that state determines what’s rendered.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ControlledInput&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Type your name"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; value is fully controlled by React via the &lt;code&gt;name&lt;/code&gt; state.&lt;br&gt;
Each keystroke triggers &lt;code&gt;setName()&lt;/code&gt;, re-rendering the component with the updated value.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to validate or transform input on change.&lt;/li&gt;
&lt;li&gt;Centralized state makes debugging and unit testing easier.&lt;/li&gt;
&lt;li&gt;Integrates seamlessly with complex UIs or form libraries (Formik, React Hook Form).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frequent re-renders can impact performance in large forms.&lt;/li&gt;
&lt;li&gt;Need to carefully manage performance and input lag.&lt;/li&gt;
&lt;li&gt;Cursor position bugs can occur with advanced state management.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧩 What Are Uncontrolled Components?
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;uncontrolled components&lt;/strong&gt;, the DOM maintains its own state — React just &lt;strong&gt;references&lt;/strong&gt; it.&lt;br&gt;
You don’t handle every keystroke; instead, you access the value when needed.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UncontrolledInput&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Input value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;inputRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Type your name"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better performance for simple forms.&lt;/li&gt;
&lt;li&gt;Minimal React re-renders.&lt;/li&gt;
&lt;li&gt;Perfect when you just need the final value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Harder to validate or modify values dynamically.&lt;/li&gt;
&lt;li&gt;Not ideal when input data must always reflect application state.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚔️ Controlled vs Uncontrolled: Key Differences
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Controlled&lt;/th&gt;
&lt;th&gt;Uncontrolled&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Source&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;React State&lt;/td&gt;
&lt;td&gt;DOM (via refs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;May re-render often&lt;/td&gt;
&lt;td&gt;Faster for simple inputs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy to handle dynamically&lt;/td&gt;
&lt;td&gt;Requires manual check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complex, validated forms&lt;/td&gt;
&lt;td&gt;Simple or performance-critical inputs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚡ Valtio &amp;amp; Controlled Inputs: Why Cursor Jumps Happen
&lt;/h2&gt;

&lt;p&gt;When you use a state library like Valtio in a React controlled input, you might encounter this issue: you edit text in the middle of the input, but the cursor jumps to the end. This frustrates users and breaks the typing experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 What’s going on?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By default, Valtio batches updates before triggering re-renders. The documentation states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“By default, state mutations are batched before triggering re-render. Sometimes, we want to disable the batching.”&lt;br&gt;
Because of this batching behavior, when you type and update the proxy state, multiple changes may be queued and then re-rendered in one go. During that delay, the browser loses context of the input cursor position, so after render the input’s value is applied and the cursor jumps to the end.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;✅ The fix: { sync: true }&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Valtio provides the option to disable batching for specific use-cases like inputs:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const snap = useSnapshot(state, { sync: true });&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;sync: true&lt;/code&gt;, updates go through immediately rather than being deferred/batched. This keeps the input cursor where the user expects it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Trade-off:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;sync: true&lt;/code&gt; disables batching optimizations, which can reduce render efficiency in large/complex components. Therefore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;sync: true&lt;/code&gt; only in input fields where cursor behaviour matters.&lt;/li&gt;
&lt;li&gt;Avoid it for general state where performance is more important than instantaneous update.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔁 Undo/Redo (Cmd+Z / Cmd+Shift+Z) in Controlled Components
&lt;/h2&gt;

&lt;p&gt;Another subtle but important issue:&lt;br&gt;
Undo (&lt;code&gt;Cmd+Z&lt;/code&gt;) and Redo (&lt;code&gt;Cmd+Shift+Z&lt;/code&gt;) &lt;strong&gt;might not work&lt;/strong&gt; as expected in controlled inputs.&lt;/p&gt;

&lt;p&gt;Why?&lt;br&gt;
Because React replaces the entire value on every keystroke rather than letting the browser handle native input history.&lt;/p&gt;

&lt;p&gt;This means the browser sometimes &lt;strong&gt;loses the input undo stack&lt;/strong&gt;, especially if re-renders happen between updates.&lt;/p&gt;

&lt;p&gt;🧪 &lt;strong&gt;What to do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test undo/redo behavior in all input fields before handing over to QA.&lt;/li&gt;
&lt;li&gt;If using a state library or custom hooks, check whether it maintains the input history properly.&lt;/li&gt;
&lt;li&gt;In cases where it fails and browser-native undo is critical (e.g., long text editors), consider using &lt;strong&gt;uncontrolled inputs&lt;/strong&gt; or controlled wrappers that debounce updates.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧰 Best Practices for React Forms
&lt;/h2&gt;

&lt;p&gt;✅ Use &lt;strong&gt;controlled inputs&lt;/strong&gt; when you need validation, dynamic control or shared state.&lt;br&gt;
✅ Use &lt;strong&gt;uncontrolled inputs&lt;/strong&gt; when performance and simplicity matter.&lt;br&gt;
✅ For state libraries like &lt;strong&gt;Valtio&lt;/strong&gt;, test cursor and undo behaviors thoroughly.&lt;br&gt;
✅ Avoid unnecessary re-renders – use &lt;code&gt;React.memo&lt;/code&gt;, &lt;code&gt;useCallback&lt;/code&gt; or split components.&lt;br&gt;
✅ Always test form UX — typing, cursor and undo/redo should feel &lt;strong&gt;native and fluid&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Controlled vs Uncontrolled Components seem like a small React concept, but they can deeply impact user experience, especially in &lt;strong&gt;complex form-heavy applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;💡 Understanding these nuances (like cursor handling, undo/redo, and batching) helps you ship &lt;strong&gt;smoother, bug-free UIs&lt;/strong&gt; that feel professional and reliable.&lt;/p&gt;

&lt;p&gt;🚀 Whether you use plain React or libraries like Valtio, always test the real typing experience — that’s where users feel the difference.&lt;/p&gt;

&lt;p&gt;💬 Have you ever faced cursor or undo issues in your React forms? Drop your experience or workaround below — let’s learn together! 👇&lt;/p&gt;

</description>
      <category>react</category>
      <category>frontend</category>
      <category>performance</category>
      <category>learning</category>
    </item>
    <item>
      <title>🚀 Mastering NestJS Concepts: Decorators, Dependency Injection, DTOs &amp; More</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 04 Oct 2025 08:43:56 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/mastering-nestjs-concepts-decorators-dependency-injection-dtos-more-2c1f</link>
      <guid>https://forem.com/fazal_mansuri_/mastering-nestjs-concepts-decorators-dependency-injection-dtos-more-2c1f</guid>
      <description>&lt;p&gt;NestJS is one of the most popular Node.js frameworks, combining &lt;strong&gt;TypeScript&lt;/strong&gt;, &lt;strong&gt;OOP principles&lt;/strong&gt; and &lt;strong&gt;modular design&lt;/strong&gt;. It provides powerful tools like decorators, dependency injection and interceptors, which simplify building scalable applications.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll explore some &lt;strong&gt;core concepts of NestJS&lt;/strong&gt; and tackle a real-world issue developers often face with &lt;strong&gt;DTOs and getters&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ What Are Decorators in NestJS?
&lt;/h2&gt;

&lt;p&gt;Decorators are &lt;strong&gt;metadata annotations&lt;/strong&gt; that NestJS uses to add behavior to classes, methods and properties.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Controller()&lt;/code&gt; → Marks a class as a controller.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Get()&lt;/code&gt;, &lt;code&gt;@Post()&lt;/code&gt; → Define route handlers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Injectable()&lt;/code&gt; → Marks a class as available for dependency injection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ &lt;strong&gt;Best practice:&lt;/strong&gt; Always use NestJS decorators instead of manually wiring routes or dependencies - it keeps code clean and testable.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Dependency Injection (DI) in NestJS
&lt;/h2&gt;

&lt;p&gt;Dependency Injection is a design pattern where objects (services) are &lt;strong&gt;injected into a class&lt;/strong&gt; instead of being created manually.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;UserService&lt;/code&gt; is &lt;strong&gt;automatically injected&lt;/strong&gt; into &lt;code&gt;UserController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;➡️ &lt;strong&gt;Why it matters?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Makes testing easier (you can mock dependencies).&lt;/li&gt;
&lt;li&gt;Encourages loose coupling.&lt;/li&gt;
&lt;li&gt;Simplifies large codebases.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Think about ordering pizza 🍕. You don’t grow the wheat, make the cheese and cook the pizza yourself every time - instead, you depend on a pizza shop to give it to you.&lt;br&gt;
That’s Dependency Injection in software. Instead of a class creating everything it needs by itself, NestJS provides the needed things (dependencies) for you.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3️⃣ DTOs, Serialization &amp;amp; the Getter Issue
&lt;/h2&gt;

&lt;p&gt;When working with &lt;strong&gt;DTOs (Data Transfer Objects)&lt;/strong&gt; in NestJS, you often want to control what fields are returned in API responses. This is where &lt;strong&gt;&lt;code&gt;class-transformer&lt;/code&gt; decorators&lt;/strong&gt; like &lt;code&gt;@Expose()&lt;/code&gt; and &lt;code&gt;@Exclude()&lt;/code&gt; come in.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 &lt;code&gt;@Expose()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Marks a property (or getter) to be included in the serialized response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Expose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Expose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;➡ Only &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; will be serialized if you enable &lt;code&gt;ClassSerializerInterceptor&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In NestJS, the &lt;code&gt;ClassSerializerInterceptor&lt;/code&gt; cleans up API responses by hiding or exposing only the properties you mark (e.g., using &lt;code&gt;@Exclude()&lt;/code&gt; or &lt;code&gt;@Expose()&lt;/code&gt;). It’s mainly used to prevent sensitive fields like passwords from being sent back in responses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🔹 &lt;code&gt;@Exclude()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Removes sensitive/internal fields from the response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Exclude&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;➡ &lt;code&gt;password&lt;/code&gt; will &lt;strong&gt;never&lt;/strong&gt; appear in the response.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Best practice:&lt;/strong&gt; Use &lt;code&gt;@Exclude()&lt;/code&gt; on class level, then selectively &lt;code&gt;@Expose()&lt;/code&gt; only the fields you want returned.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚠️ A Real-World Getter Issue
&lt;/h3&gt;

&lt;p&gt;Imagine you want to &lt;strong&gt;dynamically compute a field&lt;/strong&gt;. For example, a &lt;code&gt;FolderDto&lt;/code&gt; that returns a folder type based on internal conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FolderDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;isSpecial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Expose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSpecial&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;special&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this looks fine ✅.&lt;br&gt;
But what if you later need to &lt;strong&gt;override &lt;code&gt;type&lt;/code&gt; explicitly&lt;/strong&gt; for certain cases?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;custom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Won’t work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;➡ The response will still show the &lt;strong&gt;getter’s computed value&lt;/strong&gt;, because NestJS serialization prioritizes &lt;strong&gt;getters&lt;/strong&gt; over explicitly set fields.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ The Robust Solution: Backing Property + Setter
&lt;/h3&gt;

&lt;p&gt;To handle both cases (computed and explicit), use a &lt;strong&gt;private backing property&lt;/strong&gt; with a setter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FolderDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;isSpecial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_customType&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;customType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_customType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Expose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_customType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_customType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSpecial&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;special&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you set &lt;code&gt;dto.customType = "archive"&lt;/code&gt;, the response will use &lt;code&gt;"archive"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you don’t set it, the getter’s logic (&lt;code&gt;special&lt;/code&gt;/&lt;code&gt;default&lt;/code&gt;) will apply.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This approach is &lt;strong&gt;flexible and future-proof&lt;/strong&gt; – you avoid being locked into only getter-based logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Other Useful NestJS Concepts &amp;amp; Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔹 Pipes
&lt;/h3&gt;

&lt;p&gt;Transform and validate input data automatically. Example: &lt;code&gt;ValidationPipe&lt;/code&gt; for DTO validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Interceptors
&lt;/h3&gt;

&lt;p&gt;Modify requests/responses, add logging, or handle caching. Example: &lt;code&gt;ClassSerializerInterceptor&lt;/code&gt; to apply &lt;code&gt;@Expose&lt;/code&gt; and &lt;code&gt;@Exclude&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Guards
&lt;/h3&gt;

&lt;p&gt;Control access with authorization logic (&lt;code&gt;CanActivate&lt;/code&gt;). Example: &lt;code&gt;AuthGuard&lt;/code&gt; for JWT.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Filters
&lt;/h3&gt;

&lt;p&gt;Handle exceptions globally or locally. Example: &lt;code&gt;HttpExceptionFilter&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;NestJS offers &lt;strong&gt;powerful abstractions&lt;/strong&gt; that make backend development faster, safer and more maintainable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Use decorators to keep code clean.&lt;/li&gt;
&lt;li&gt;✅ Rely on dependency injection for flexibility.&lt;/li&gt;
&lt;li&gt;✅ Understand &lt;code&gt;@Expose()&lt;/code&gt; / &lt;code&gt;@Exclude()&lt;/code&gt; to manage responses.&lt;/li&gt;
&lt;li&gt;✅ Watch out for getter pitfalls—fix with setters and backing properties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 By learning these &lt;strong&gt;patterns and best practices&lt;/strong&gt;, you’ll avoid debugging headaches and build APIs that scale.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>backend</category>
      <category>api</category>
      <category>programming</category>
    </item>
    <item>
      <title>🌐 Understanding CORS (Cross-Origin Resource Sharing): A Complete Guide</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 27 Sep 2025 08:49:19 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/understanding-cors-cross-origin-resource-sharing-a-complete-guide-5gbg</link>
      <guid>https://forem.com/fazal_mansuri_/understanding-cors-cross-origin-resource-sharing-a-complete-guide-5gbg</guid>
      <description>&lt;h2&gt;
  
  
  🔎 What is CORS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cross-Origin Resource Sharing (CORS)&lt;/strong&gt; is a browser security feature that controls how web applications request resources (APIs, images, fonts, etc.) from a &lt;strong&gt;different origin (domain, protocol or port)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your React frontend runs at &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Your Go API runs at &lt;code&gt;http://localhost:8080&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When React fetches data from Go API → this is a &lt;strong&gt;cross-origin request&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without proper CORS setup, the browser &lt;strong&gt;blocks the request&lt;/strong&gt; for security reasons.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ How Does CORS Work?
&lt;/h2&gt;

&lt;p&gt;CORS works via &lt;strong&gt;HTTP headers&lt;/strong&gt; exchanged between the browser and server.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Simple Requests&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Happen when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Method is &lt;strong&gt;GET, POST or HEAD&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Headers are only "safe" ones (&lt;code&gt;Accept&lt;/code&gt;, &lt;code&gt;Content-Type&lt;/code&gt; as &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;, &lt;code&gt;multipart/form-data&lt;/code&gt;, &lt;code&gt;text/plain&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/api/products&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://example-frontend.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Server Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://example-frontend.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the header matches → browser allows. Otherwise, request is blocked.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;strong&gt;Preflight Requests&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For non-simple requests (e.g., &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; or custom headers), the browser sends a &lt;strong&gt;preflight request&lt;/strong&gt; using &lt;code&gt;OPTIONS&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is Preflight Request?&lt;/strong&gt;&lt;br&gt;
Not all requests go directly to the server. Sometimes, the browser first asks:&lt;br&gt;
&lt;em&gt;"Hey server, is it safe if I send this request?"&lt;/em&gt; - This is called a preflight request.&lt;br&gt;
A preflight request is an &lt;code&gt;OPTIONS&lt;/code&gt; call that the browser automatically makes before the actual request, when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The HTTP method is not simple (&lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The request has custom headers (e.g., &lt;code&gt;Authorization&lt;/code&gt;, &lt;code&gt;X-Custom-Header&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The Content-Type is not "safe" (&lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;, &lt;code&gt;multipart/form-data&lt;/code&gt;, &lt;code&gt;text/plain&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;OPTIONS&lt;/span&gt; &lt;span class="nn"&gt;/api/products&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://example-frontend.com&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Request-Method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PUT&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Request-Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Content-Type, Authorization&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Server must respond with allowed methods/headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;204&lt;/span&gt; &lt;span class="ne"&gt;No Content&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://example-frontend.com&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET, POST, PUT, DELETE&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Content-Type, Authorization&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Max-Age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the &lt;strong&gt;actual request&lt;/strong&gt; (PUT/DELETE) is sent.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Why is CORS Important?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protects Users:&lt;/strong&gt; Prevents malicious sites from sending requests to other sites using your credentials (Cross-Site Request Forgery protection).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granular Control:&lt;/strong&gt; You decide which origins, methods and headers are safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Requirement:&lt;/strong&gt; Any modern web app with &lt;strong&gt;frontend + backend on different domains&lt;/strong&gt; needs correct CORS setup.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Common Issues Caused by CORS
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Blocked by CORS Policy (No 'Access-Control-Allow-Origin' header)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server not configured to allow the frontend domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;Credential Errors&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookies or tokens require:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://myapp.com
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❌ Note: &lt;code&gt;*&lt;/code&gt; cannot be used when credentials are allowed.&lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;Preflight Failures&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend doesn’t respond correctly to &lt;code&gt;OPTIONS&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4️⃣ &lt;strong&gt;Wildcard Misuse&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt; everywhere → insecure.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Example: CORS in Go (Gin Framework)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/gin-gonic/gin"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/gin-contrib/cors"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;AllowOrigins&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:3000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"https://myapp.com"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;AllowMethods&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"PUT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DELETE"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;AllowHeaders&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;ExposeHeaders&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Content-Length"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;AllowCredentials&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;MaxAge&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}))&lt;/span&gt;

    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/products"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"product"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Laptop"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This setup allows React (&lt;code&gt;localhost:3000&lt;/code&gt;) or production frontend to call your Go API.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌍 Real-World Examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend hosted on Netlify (&lt;code&gt;https://myapp.netlify.app&lt;/code&gt;)&lt;/strong&gt; calling backend on AWS EC2 (&lt;code&gt;https://api.myapp.com&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Without CORS → browser blocks requests.&lt;/li&gt;
&lt;li&gt;With proper CORS headers → smooth API calls.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔒 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Always &lt;strong&gt;restrict origins&lt;/strong&gt; → never &lt;code&gt;*&lt;/code&gt; for sensitive APIs.&lt;/li&gt;
&lt;li&gt;✅ For multiple environments (dev/staging/prod), configure env-specific origins.&lt;/li&gt;
&lt;li&gt;✅ Handle &lt;strong&gt;preflight (OPTIONS)&lt;/strong&gt; requests in backend properly.&lt;/li&gt;
&lt;li&gt;✅ Use &lt;code&gt;Access-Control-Max-Age&lt;/code&gt; to reduce repeated preflights.&lt;/li&gt;
&lt;li&gt;✅ Avoid allowing unnecessary headers/methods.&lt;/li&gt;
&lt;li&gt;✅ Never rely only on CORS for security → also use authentication &amp;amp; rate limiting.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📌 Latest Info &amp;amp; Trends
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CORS in Fetch API:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;fetch(url, { mode: "cors", credentials: "include" })&lt;/code&gt; must match backend CORS setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Private Network Access (PNA):&lt;/strong&gt;&lt;br&gt;
Browsers now add &lt;strong&gt;extra preflights&lt;/strong&gt; for requests to private networks (like &lt;code&gt;http://192.168.x.x&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Proxies in Dev:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React (&lt;code&gt;create-react-app&lt;/code&gt;) uses &lt;code&gt;proxy&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt; to bypass CORS in local dev.&lt;/li&gt;
&lt;li&gt;In production → must fix at backend.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;CORS might look like a “weird error message” at first, but it’s one of the &lt;strong&gt;most important browser security features&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your frontend talks to your backend (different domain/port), &lt;strong&gt;you must configure CORS properly&lt;/strong&gt; — otherwise, users face blocked requests.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;The key takeaway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t just throw &lt;code&gt;*&lt;/code&gt; in &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Think carefully about which origins, headers and methods are safe.&lt;/li&gt;
&lt;li&gt;Set it once, document it and avoid long debugging sessions.&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>webdev</category>
      <category>security</category>
      <category>frontend</category>
      <category>backend</category>
    </item>
    <item>
      <title>🛡️ Content Security Policy (CSP): A Complete Guide for Developers</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 30 Aug 2025 11:00:57 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/content-security-policy-csp-a-complete-guide-for-developers-56lp</link>
      <guid>https://forem.com/fazal_mansuri_/content-security-policy-csp-a-complete-guide-for-developers-56lp</guid>
      <description>&lt;p&gt;Security is one of the most critical aspects of modern web development. Even if your code is correct, attackers may exploit vulnerabilities like &lt;strong&gt;Cross-Site Scripting (XSS)&lt;/strong&gt; or &lt;strong&gt;Clickjacking&lt;/strong&gt;. That’s where &lt;strong&gt;Content Security Policy (CSP)&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;This blog covers:&lt;br&gt;
✅ What CSP is &amp;amp; how it works&lt;br&gt;
✅ All major directives (&lt;code&gt;default-src&lt;/code&gt;, &lt;code&gt;script-src&lt;/code&gt;, &lt;code&gt;img-src&lt;/code&gt;, etc.) explained in detail&lt;br&gt;
✅ Real-world examples&lt;br&gt;
✅ Best practices &amp;amp; common pitfalls&lt;/p&gt;

&lt;p&gt;Let’s dive in. 🔥&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚙️ What is CSP &amp;amp; Why Do We Need It?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Content Security Policy (CSP) is an &lt;strong&gt;HTTP response header&lt;/strong&gt; that defines where browsers can load resources (scripts, images, styles, fonts, iframes, workers, etc.) from.&lt;/li&gt;
&lt;li&gt;Its main purpose: &lt;strong&gt;prevent XSS attacks&lt;/strong&gt; by restricting execution of malicious scripts.&lt;/li&gt;
&lt;li&gt;Without CSP, if an attacker injects a script into your page, the browser executes it blindly. With CSP, you can &lt;strong&gt;whitelist only trusted domains&lt;/strong&gt;, blocking everything else.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example CSP header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: default-src 'self'; img-src https://cdn.example.com; script-src 'self' https://apis.google.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By default, only load resources from the same origin (&lt;code&gt;'self'&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Allow images from &lt;code&gt;cdn.example.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Allow scripts from self and Google APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt;&lt;br&gt;
 If &lt;code&gt;default-src&lt;/code&gt; is missing, everything is allowed, weakening your CSP.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📌 Important Directives
&lt;/h2&gt;

&lt;p&gt;Here’s a breakdown of &lt;strong&gt;commonly used CSP directives&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔑 &lt;code&gt;default-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The fallback for all other directives (if they are not explicitly defined).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Security-Policy: default-src 'self';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;script-src&lt;/code&gt; or &lt;code&gt;style-src&lt;/code&gt; is missing, browsers fall back to &lt;code&gt;default-src&lt;/code&gt;. ✅&lt;/p&gt;




&lt;h3&gt;
  
  
  📜 &lt;code&gt;script-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines where JavaScript can be loaded from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Security-Policy: script-src 'self' https://apis.google.com;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Special values:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'self'&lt;/code&gt;: allow only current domain&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'unsafe-eval'&lt;/code&gt;: allow &lt;code&gt;eval()&lt;/code&gt; usage (⚠️ dangerous)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'unsafe-inline'&lt;/code&gt;: allow inline scripts (⚠️ not recommended)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Better options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nonce&lt;/strong&gt; → Random value per request:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Safe!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;With CSP:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Security-Policy: script-src 'self' 'nonce-abc123';
&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hash&lt;/strong&gt; → Allow only exact inline script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;With CSP:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: script-src 'self' 'sha256-XYZhashHere...';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;✅ Nonce &amp;amp; Hash are safer than &lt;code&gt;'unsafe-inline'&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 &lt;code&gt;style-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Controls where CSS can be loaded from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: style-src 'self' https://fonts.googleapis.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Using &lt;code&gt;'unsafe-inline'&lt;/code&gt; allows inline styles → risky.&lt;br&gt;
🔑 Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;nonce&lt;/strong&gt; or &lt;strong&gt;hashes&lt;/strong&gt; for dynamic styles.&lt;/li&gt;
&lt;li&gt;Example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🖼️ &lt;code&gt;img-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines allowed image sources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: img-src 'self' https://cdn.example.com data:;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 &lt;code&gt;data:&lt;/code&gt; allows base64-encoded images.&lt;/p&gt;




&lt;h3&gt;
  
  
  📄 &lt;code&gt;font-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Controls allowed font sources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: font-src 'self' https://fonts.gstatic.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🔗 &lt;code&gt;connect-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines where AJAX/fetch/WebSocket connections can be made.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: connect-src 'self' https://api.example.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🎵 &lt;code&gt;media-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Specifies allowed sources for &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: media-src 'self' https://media.example.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🏗️ &lt;code&gt;frame-src&lt;/code&gt; vs &lt;code&gt;frame-ancestors&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;frame-src&lt;/code&gt;&lt;/strong&gt;: Controls what &lt;em&gt;your app&lt;/em&gt; can embed in an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;  Content-Security-Policy: frame-src https://www.youtube.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;frame-ancestors&lt;/code&gt;&lt;/strong&gt;: Controls who can embed &lt;em&gt;your site&lt;/em&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;  Content-Security-Policy: frame-ancestors 'none';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Use &lt;code&gt;frame-ancestors&lt;/code&gt; to prevent clickjacking.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 &lt;code&gt;worker-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines allowed sources for &lt;strong&gt;Web Workers&lt;/strong&gt; &amp;amp; &lt;strong&gt;Service Workers&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web Workers&lt;/strong&gt;: Run scripts in a separate thread (background tasks).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Workers&lt;/strong&gt;: Proxy requests for offline support / caching.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: worker-src 'self' https://cdn.example.com;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📂 &lt;code&gt;object-src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Restricts plugins like Flash/Silverlight (legacy). Best to set &lt;code&gt;'none'&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: object-src 'none';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📝 Reporting with CSP
&lt;/h3&gt;

&lt;p&gt;Instead of enforcing, you can &lt;strong&gt;test with reporting only&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, violations are logged but not blocked. Useful before rollout.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Real-World Example
&lt;/h2&gt;

&lt;p&gt;Imagine your webapp loads:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scripts from your domain + Google APIs&lt;/li&gt;
&lt;li&gt;Styles from your domain + Google Fonts&lt;/li&gt;
&lt;li&gt;Images from CDN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CSP could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://cdn.example.com; connect-src 'self' https://api.myapp.com; object-src 'none'; frame-ancestors 'none'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This protects you from attackers injecting malicious scripts/images from untrusted domains.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 Common CSP Issues Developers Face
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;❌ Images not loading → Forgot &lt;code&gt;img-src&lt;/code&gt; domain.&lt;/li&gt;
&lt;li&gt;❌ Fonts breaking → Missing &lt;code&gt;font-src&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;❌ Videos not playing → &lt;code&gt;media-src&lt;/code&gt; missing.&lt;/li&gt;
&lt;li&gt;❌ API calls failing → Missing &lt;code&gt;connect-src&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;❌ App not embeddable → Strict &lt;code&gt;frame-ancestors&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 If your &lt;strong&gt;frontend/backend look fine but still break&lt;/strong&gt;, check CSP first.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always define a strict &lt;code&gt;default-src&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;'unsafe-inline'&lt;/code&gt; and &lt;code&gt;'unsafe-eval'&lt;/code&gt; unless absolutely necessary – use &lt;strong&gt;nonces or hashes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;'self'&lt;/code&gt; wherever possible.&lt;/li&gt;
&lt;li&gt;Test with &lt;code&gt;Content-Security-Policy-Report-Only&lt;/code&gt; before enforcing.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📌 Conclusion
&lt;/h2&gt;

&lt;p&gt;CSP is not just another header—it’s a &lt;strong&gt;powerful security shield&lt;/strong&gt; 🛡️ for your apps.&lt;br&gt;
The right configuration prevents XSS, clickjacking, and data injection while keeping performance intact.&lt;/p&gt;

&lt;p&gt;👉 The bottom line: &lt;strong&gt;CSP = Control + Security + Peace of Mind&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>csp</category>
      <category>learning</category>
      <category>security</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>🛡️ Rate Limiting in Web Applications</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 24 Aug 2025 11:25:42 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/rate-limiting-in-web-applications-3cjh</link>
      <guid>https://forem.com/fazal_mansuri_/rate-limiting-in-web-applications-3cjh</guid>
      <description>&lt;p&gt;In today’s API-driven world, applications face thousands—or even millions—of requests every day. While high traffic is great, it can also create &lt;strong&gt;challenges&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔒 Security risks (brute force, DDoS attacks)&lt;/li&gt;
&lt;li&gt;⚖️ Fair usage enforcement (avoid abuse of free tiers)&lt;/li&gt;
&lt;li&gt;🚀 Performance stability (prevent one user from hogging resources)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;Rate Limiting&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Rate limiting ensures &lt;strong&gt;a user, IP or client can only make a defined number of requests within a specific time window&lt;/strong&gt;. It’s a cornerstone of modern, scalable APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Why Do We Need Rate Limiting?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔐 &lt;strong&gt;Security&lt;/strong&gt; → Protect against brute force login attempts, API scraping, and DDoS attacks.&lt;/li&gt;
&lt;li&gt;⚖️ &lt;strong&gt;Fair Usage&lt;/strong&gt; → Prevent abuse of APIs, especially for freemium services.&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Performance&lt;/strong&gt; → Ensure backend resources are shared fairly among all users.&lt;/li&gt;
&lt;li&gt;💰 &lt;strong&gt;Cost Control&lt;/strong&gt; → Reduce infrastructure bills by blocking excessive or abusive requests.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Common Rate Limiting Algorithms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Token Bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Requests are allowed if tokens are available.&lt;/li&gt;
&lt;li&gt;Tokens refill at a fixed rate.&lt;/li&gt;
&lt;li&gt;Commonly used (flexible + efficient).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔧 Example: Allow 10 requests per second. If unused, tokens accumulate up to a max limit (burst handling).&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Leaky Bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Works like water dripping from a bucket at a fixed rate.&lt;/li&gt;
&lt;li&gt;Bursts are smoothed out.&lt;/li&gt;
&lt;li&gt;Useful for evenly distributing traffic.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3️⃣ Fixed Window Counter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Count requests in a fixed time window (e.g., 100 requests per minute).&lt;/li&gt;
&lt;li&gt;❌ Edge case: allows bursts at window boundaries.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4️⃣ Sliding Window Log
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keeps timestamps of requests.&lt;/li&gt;
&lt;li&gt;Precise but memory-heavy for large scale.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5️⃣ Sliding Window Counter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hybrid approach: averages counts across windows.&lt;/li&gt;
&lt;li&gt;More accurate than fixed window, less heavy than logs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Implementing Rate Limiting in Applications
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example in &lt;strong&gt;Go (Gin Framework)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/gin-gonic/gin"&lt;/span&gt;
    &lt;span class="s"&gt;"golang.org/x/time/rate"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Create a limiter: 5 requests/sec, burst up to 10&lt;/span&gt;
    &lt;span class="n"&gt;limiter&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLimiter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;limiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Allow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusTooManyRequests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Too many requests"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Request successful"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Each client is limited to &lt;strong&gt;5 requests per second&lt;/strong&gt; with a burst allowance of 10.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚦 Rate Limiting with NGINX
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NGINX&lt;/strong&gt; can handle rate limiting &lt;strong&gt;at the web server or reverse proxy level&lt;/strong&gt;, making it a powerful tool to protect your backend before requests hit your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ How It Works
&lt;/h3&gt;

&lt;p&gt;NGINX uses two main directives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;limit_req_zone&lt;/code&gt;&lt;/strong&gt; → Defines a shared memory zone to track requests (by IP or custom key).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;limit_req&lt;/code&gt;&lt;/strong&gt; → Applies the limit to endpoints.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🔧 Basic Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;# 1. Define rate limit zone (1 request/sec, burst 5)&lt;/span&gt;
  &lt;span class="kn"&gt;limit_req_zone&lt;/span&gt; &lt;span class="nv"&gt;$binary_remote_addr&lt;/span&gt; &lt;span class="s"&gt;zone=api_limit:10m&lt;/span&gt; &lt;span class="s"&gt;rate=1r/s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;# 2. Apply rate limit&lt;/span&gt;
      &lt;span class="kn"&gt;limit_req&lt;/span&gt; &lt;span class="s"&gt;zone=api_limit&lt;/span&gt; &lt;span class="s"&gt;burst=5&lt;/span&gt; &lt;span class="s"&gt;nodelay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://backend_service&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔍 Explanation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key:&lt;/strong&gt; &lt;code&gt;$binary_remote_addr&lt;/code&gt; → Track by client IP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate:&lt;/strong&gt; &lt;code&gt;1r/s&lt;/code&gt; → Allows &lt;strong&gt;1 request per second per IP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Burst:&lt;/strong&gt; &lt;code&gt;5&lt;/code&gt; → Short bursts up to 5 requests allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nodelay:&lt;/strong&gt; Burst requests are processed immediately.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✅ Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Filters traffic &lt;strong&gt;before hitting your backend&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Can apply limits &lt;strong&gt;per endpoint&lt;/strong&gt; (e.g., &lt;code&gt;/login&lt;/code&gt; stricter than &lt;code&gt;/products&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Lightweight &amp;amp; fast.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📊 Logs &amp;amp; Monitoring
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Exceeded requests → logged as &lt;code&gt;503&lt;/code&gt; (Service Unavailable).&lt;/li&gt;
&lt;li&gt;Useful for tracking abuse &amp;amp; fine-tuning limits.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚠️ Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid overly strict global limits (may block valid traffic).&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;$realip_remote_addr&lt;/code&gt; when behind a proxy/load balancer.&lt;/li&gt;
&lt;li&gt;Always test before production rollout.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔒 Best Practices for Rate Limiting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🎯 Apply stricter limits on &lt;strong&gt;sensitive endpoints&lt;/strong&gt; (like &lt;code&gt;/login&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;🌍 Use &lt;strong&gt;different limits per client type&lt;/strong&gt; (mobile app vs. server-to-server).&lt;/li&gt;
&lt;li&gt;🧩 Combine &lt;strong&gt;server-level (NGINX/API Gateway)&lt;/strong&gt; + &lt;strong&gt;app-level&lt;/strong&gt; checks.&lt;/li&gt;
&lt;li&gt;📊 Monitor logs &amp;amp; dashboards for &lt;strong&gt;blocked traffic trends&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;🚀 Use &lt;strong&gt;distributed stores&lt;/strong&gt; (Redis) for shared limits in multi-instance apps.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Bonus Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;429 Status Code:&lt;/strong&gt; Always return HTTP &lt;code&gt;429 Too Many Requests&lt;/code&gt; with a helpful message.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Retry-After Header:&lt;/strong&gt; Tell clients when to retry. Example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;429&lt;/span&gt; &lt;span class="ne"&gt;Too Many Requests&lt;/span&gt;
&lt;span class="na"&gt;Retry-After&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Graceful Degradation:&lt;/strong&gt; Don’t just block—offer reduced functionality for non-critical requests.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Rate limiting is &lt;strong&gt;not just a performance tool&lt;/strong&gt;—it’s a &lt;strong&gt;security guard, cost saver and reliability booster&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whether you use &lt;strong&gt;algorithms in code&lt;/strong&gt;, &lt;strong&gt;NGINX&lt;/strong&gt; or &lt;strong&gt;API Gateways (Kong, Apigee, AWS API Gateway)&lt;/strong&gt;, implementing proper rate limiting ensures:&lt;/p&gt;

&lt;p&gt;✔️ Fair usage&lt;br&gt;
✔️ Secure endpoints&lt;br&gt;
✔️ Scalable systems&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;The bottom line?&lt;/strong&gt; Smart rate limiting makes APIs faster, safer, and fairer—for everyone.&lt;/p&gt;

&lt;p&gt;💬 What approach do you use for rate limiting in your backend? Have you tried using Redis or NGINX rules? Let’s discuss in the comments!&lt;/p&gt;

</description>
      <category>ratelimit</category>
      <category>softwaredevelopment</category>
      <category>security</category>
      <category>learning</category>
    </item>
    <item>
      <title>⚡️ Caching Strategies for Web Apps: From Browser to Backend</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 13 Jul 2025 07:28:46 +0000</pubDate>
      <link>https://forem.com/fazal_mansuri_/caching-strategies-for-web-apps-from-browser-to-backend-38nj</link>
      <guid>https://forem.com/fazal_mansuri_/caching-strategies-for-web-apps-from-browser-to-backend-38nj</guid>
      <description>&lt;p&gt;Caching is one of the &lt;strong&gt;most powerful ways to improve application performance&lt;/strong&gt;—reducing load times, server costs, and user frustration. Yet many developers treat caching as a “black box” or skip it due to fear of cache-related bugs.&lt;/p&gt;

&lt;p&gt;In this blog, we will:&lt;br&gt;
✅ Demystify caching: what it is and why it matters&lt;br&gt;
✅ Explore &lt;strong&gt;frontend (browser) caching strategies&lt;/strong&gt;&lt;br&gt;
✅ Dive into &lt;strong&gt;backend and distributed caching&lt;/strong&gt; with Go examples&lt;br&gt;
✅ Cover &lt;strong&gt;Cache-Control headers, ETag, stale-while-revalidate&lt;/strong&gt;&lt;br&gt;
✅ Discuss &lt;strong&gt;common pitfalls and best practices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By the end, you’ll know how to confidently implement caching in your React frontend and Go backend to build &lt;strong&gt;scalable, fast, and efficient applications&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 What is Caching?
&lt;/h2&gt;

&lt;p&gt;Caching means &lt;strong&gt;storing data temporarily&lt;/strong&gt; so future requests can be served faster without recomputing or refetching the same data repeatedly.&lt;/p&gt;

&lt;p&gt;Think of it like &lt;strong&gt;preparing tea and storing it in a flask&lt;/strong&gt;—you don’t need to reboil water each time you want to drink.&lt;/p&gt;


&lt;h2&gt;
  
  
  📈 Why Caching Matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Return data faster to users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce Server Load:&lt;/strong&gt; Avoid redundant computation or DB queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve Reliability:&lt;/strong&gt; Serve cached responses when backend services are down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce Costs:&lt;/strong&gt; Less compute = lower cloud bills.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧩 Caching in the Frontend (Browser)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1️⃣ Browser Cache (HTTP Caching)
&lt;/h3&gt;

&lt;p&gt;Browsers automatically cache assets (JS, CSS, images) and API responses based on HTTP headers.&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Headers:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Cache-Control&lt;/code&gt;: Defines how long and under what conditions the browser can reuse the response.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ETag&lt;/code&gt;: Helps validate cached data; server sends a hash, and browser sends it back to check if the data changed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Expires&lt;/code&gt;: Sets a hard expiration time for cache.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stale-while-revalidate&lt;/code&gt;: Allows serving stale content while revalidating in the background for a seamless UX.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Cache-Control: public, max-age=3600, stale-while-revalidate=600
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Use Case:&lt;/strong&gt; Cache API GET responses for non-user-specific data (e.g., blog posts, product catalogs).&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Client-Side Data Fetching Libraries
&lt;/h3&gt;

&lt;p&gt;Libraries like &lt;strong&gt;React Query, SWR&lt;/strong&gt; provide built-in caching for API calls.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache API responses in memory.&lt;/li&gt;
&lt;li&gt;Background revalidation for fresh data.&lt;/li&gt;
&lt;li&gt;Avoids unnecessary re-fetching on component re-mounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Use for &lt;strong&gt;per-session data caching&lt;/strong&gt; in React apps.&lt;/p&gt;




&lt;h2&gt;
  
  
  🗂️ Caching in the Backend
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ In-Memory Caching
&lt;/h3&gt;

&lt;p&gt;Store frequently accessed data in memory for fast retrieval.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Golang’s &lt;code&gt;sync.Map&lt;/code&gt;, &lt;code&gt;groupcache&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fastest but limited by server RAM and is not shared across instances.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Use for small, frequently requested data (e.g., config, auth tokens).&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Distributed Caching
&lt;/h3&gt;

&lt;p&gt;Tools like &lt;strong&gt;Redis and Memcached&lt;/strong&gt; provide a shared cache layer accessible across multiple servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralized cache for load-balanced apps.&lt;/li&gt;
&lt;li&gt;Supports expiration policies.&lt;/li&gt;
&lt;li&gt;Can handle large datasets.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔹 Go Example: Using Redis for Caching
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Install Redis client:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/go-redis/redis/v8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Basic Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;rdb&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Addr&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"localhost:6379"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c"&gt;// Set cache&lt;/span&gt;
&lt;span class="n"&gt;rdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"product_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Get cache&lt;/span&gt;
&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"product_123"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Cache miss, fetch from DB&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Cache hit, use val&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚖️ Cache Invalidation: The Hard Part
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“There are only two hard things in Computer Science: cache invalidation and naming things.” – Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whenever the underlying data changes, you need to ensure the cache is updated to avoid stale data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strategies:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;✅ Time-based expiration (TTL):&lt;/strong&gt;&lt;br&gt;
Set a cache expiry time so data auto-expires after a fixed duration, ensuring old data clears automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Manual invalidation:&lt;/strong&gt;&lt;br&gt;
Manually clear or update cache entries whenever the underlying data changes to keep data fresh.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Write-through caching:&lt;/strong&gt;&lt;br&gt;
Write data to both the cache and the database at the same time, ensuring consistency during reads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Cache busting:&lt;/strong&gt;&lt;br&gt;
Change cache keys (e.g., &lt;code&gt;v1:product_123&lt;/code&gt; → &lt;code&gt;v2:product_123&lt;/code&gt;) when your data structure changes to avoid serving stale or incompatible data.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Best Practices for Caching
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cache &lt;strong&gt;only GET requests&lt;/strong&gt;; avoid caching POST unless explicitly designed.&lt;/li&gt;
&lt;li&gt;Set reasonable TTLs to avoid stale data.&lt;/li&gt;
&lt;li&gt;Monitor cache hit/miss rates to tune cache policies.&lt;/li&gt;
&lt;li&gt;Be cautious caching user-specific or sensitive data.&lt;/li&gt;
&lt;li&gt;Use cache versioning (&lt;code&gt;v1:product_123&lt;/code&gt;) to manage structure changes.&lt;/li&gt;
&lt;li&gt;Document what is cached, where, and why.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Common Pitfalls
&lt;/h2&gt;

&lt;p&gt;🚫 Caching sensitive user data publicly.&lt;br&gt;
🚫 Forgetting to invalidate cache on data updates.&lt;br&gt;
🚫 Over-caching dynamic endpoints, leading to stale or incorrect UI.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔮 Future of Caching: CDN &amp;amp; Edge Caching
&lt;/h2&gt;

&lt;p&gt;Content Delivery Networks (CDNs) like &lt;strong&gt;Cloudflare, AWS CloudFront, Vercel Edge&lt;/strong&gt; cache data closer to the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;br&gt;
✅ Lower latency.&lt;br&gt;
✅ Offload origin server traffic.&lt;br&gt;
✅ Built-in stale-while-revalidate strategies.&lt;/p&gt;

&lt;p&gt;Using edge caching in modern React + Go apps can drastically improve performance globally.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Caching isn’t just an optimization; it’s essential for building &lt;strong&gt;scalable, reliable, and fast applications.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whether it’s &lt;strong&gt;browser caching, React Query in the frontend, or Redis in the backend&lt;/strong&gt;, knowing when and how to cache makes you a stronger developer.&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;Have you implemented caching in your apps? What caching challenges have you faced? Let’s discuss in the comments!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>redis</category>
      <category>backend</category>
      <category>frontend</category>
      <category>webperf</category>
    </item>
  </channel>
</rss>
