<?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>DEV Community: Fazal Mansuri</title>
    <description>The latest articles on DEV Community by Fazal Mansuri (@fazal_mansuri_).</description>
    <link>https://dev.to/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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2949287%2Fcf0675d7-fc54-4289-bbdc-92bc98944ffa.jpg</url>
      <title>DEV Community: Fazal Mansuri</title>
      <link>https://dev.to/fazal_mansuri_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fazal_mansuri_"/>
    <language>en</language>
    <item>
      <title>📦 AI Context Engineering (Part 2): Tokens, Context Windows &amp; Memory - Why More Context Isn't Always Better</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 05 Jul 2026 06:23:35 +0000</pubDate>
      <link>https://dev.to/fazal_mansuri_/ai-context-engineering-part-2-tokens-context-windows-memory-why-more-context-isnt-always-453e</link>
      <guid>https://dev.to/fazal_mansuri_/ai-context-engineering-part-2-tokens-context-windows-memory-why-more-context-isnt-always-453e</guid>
      <description>&lt;p&gt;In &lt;strong&gt;Part 1&lt;/strong&gt;, we learned that building great AI applications isn't just about writing better prompts.&lt;/p&gt;

&lt;p&gt;It's about providing the &lt;strong&gt;right context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But that naturally leads to another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much context can an AI actually understand?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you've used ChatGPT, Claude, Gemini, Cursor or any AI coding assistant for a while, you've probably experienced something like this.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 "Didn't I Already Tell You That?"
&lt;/h2&gt;

&lt;p&gt;Imagine you're debugging a production issue with an AI assistant.&lt;/p&gt;

&lt;p&gt;You start by explaining the architecture.&lt;/p&gt;

&lt;p&gt;Then you share the API flow.&lt;/p&gt;

&lt;p&gt;Then database schema.&lt;/p&gt;

&lt;p&gt;Then logs.&lt;/p&gt;

&lt;p&gt;Then stack traces.&lt;/p&gt;

&lt;p&gt;After 30 minutes of conversation, you ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"So what's causing the bug?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of giving the answer, the AI responds:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Could you share your database schema?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You stare at the screen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"I already did..."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes it even forgets details from earlier in the same conversation.&lt;/p&gt;

&lt;p&gt;Naturally, people assume:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The AI has bad memory.&lt;/li&gt;
&lt;li&gt;The model is unreliable.&lt;/li&gt;
&lt;li&gt;The conversation is broken.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In reality, something completely different is happening.&lt;/p&gt;

&lt;p&gt;You're running into one of the most important concepts in modern AI systems:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Context Window.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Understanding this concept changes how you interact with AI—and more importantly, how you build AI-powered applications.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 Before We Talk About Context Windows…
&lt;/h1&gt;

&lt;p&gt;We first need to understand something much smaller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Almost every AI provider mentions them.&lt;/p&gt;

&lt;p&gt;Pricing is based on them.&lt;/p&gt;

&lt;p&gt;Context windows are measured using them.&lt;/p&gt;

&lt;p&gt;Yet many developers still think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;1 token = 1 word&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That isn't true.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔤 What Exactly Is a Token?
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;token&lt;/strong&gt; is the basic unit of text that an AI model processes.&lt;/p&gt;

&lt;p&gt;Humans naturally read text as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Characters&lt;/li&gt;
&lt;li&gt;Words&lt;/li&gt;
&lt;li&gt;Sentences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Large Language Models don't.&lt;/p&gt;

&lt;p&gt;Before text reaches the model, it's converted into smaller pieces called &lt;strong&gt;tokens&lt;/strong&gt; by a tokenizer.&lt;/p&gt;

&lt;p&gt;The model never sees your original sentence.&lt;/p&gt;

&lt;p&gt;It only sees a sequence of tokens.&lt;/p&gt;

&lt;p&gt;Think of a tokenizer as a translator between humans and AI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You write English
        ↓
Tokenizer
        ↓
Sequence of Tokens
        ↓
LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tokenizer decides how text is split.&lt;/p&gt;

&lt;p&gt;And that's why &lt;strong&gt;tokens aren't the same as words&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Tokens ≠ Words
&lt;/h1&gt;

&lt;p&gt;This is probably the biggest misconception about LLMs.&lt;/p&gt;

&lt;p&gt;Consider this sentence:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You might expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 words = 2 tokens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes that's true.&lt;/p&gt;

&lt;p&gt;Sometimes it isn't.&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;One word.&lt;/p&gt;

&lt;p&gt;But depending on the tokenizer, it may be split into multiple tokens because the model has learned common sub-word patterns rather than every possible English word.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;authentication
authorization
microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may also become multiple tokens.&lt;/p&gt;

&lt;p&gt;The tokenizer isn't trying to understand grammar.&lt;/p&gt;

&lt;p&gt;It's trying to represent text efficiently based on patterns it learned during training.&lt;/p&gt;




&lt;h1&gt;
  
  
  📦 Different Types of Content Produce Different Numbers of Tokens
&lt;/h1&gt;

&lt;p&gt;One reason token counting surprises developers is that not all text is equal.&lt;/p&gt;

&lt;p&gt;Take these examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1 — Simple English
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The server is running normally.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is relatively efficient because it contains common words.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 2 — JSON
&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;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isActive"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Even though this looks short, punctuation, quotes, braces and field names also become tokens.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 3 — Source Code
&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Programming languages introduce symbols, keywords, indentation and identifiers, all of which contribute to the token count.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 4 — URLs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/api/v1/users/123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;URLs often tokenize differently because of slashes, punctuation and path segments.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 5 — Emojis
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🚀🔥🎉
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even emojis are tokenized.&lt;/p&gt;

&lt;p&gt;Different models may tokenize the same emoji sequence differently.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Important Lesson
&lt;/h2&gt;

&lt;p&gt;Tokens are &lt;strong&gt;not based on what humans consider words.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They're based on how the tokenizer breaks text into pieces.&lt;/p&gt;

&lt;p&gt;That's why two pieces of text with the same number of characters can consume very different numbers of tokens.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎯 Why Should Developers Care About Tokens?
&lt;/h1&gt;

&lt;p&gt;Many developers only think about tokens when they receive an API bill.&lt;/p&gt;

&lt;p&gt;In reality, tokens influence almost everything about an AI system.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Cost&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Context size&lt;/li&gt;
&lt;li&gt;Response quality&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every AI request starts with a token budget.&lt;/p&gt;

&lt;p&gt;The more tokens you consume, the more work the model has to perform.&lt;/p&gt;




&lt;h1&gt;
  
  
  💰 Everything Consumes Tokens
&lt;/h1&gt;

&lt;p&gt;Here's something many people don't realize.&lt;/p&gt;

&lt;p&gt;When you send a request to an LLM, you're not paying only for your latest prompt.&lt;/p&gt;

&lt;p&gt;The model processes &lt;strong&gt;everything&lt;/strong&gt; included in the request.&lt;/p&gt;

&lt;p&gt;That may include:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;th&gt;Uses Tokens?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System Instructions&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Prompt&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conversation History&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uploaded Documents&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retrieved RAG Results&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool Outputs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function Call Results&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Response&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Even if you only typed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Summarize this.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model might actually receive thousands of tokens.&lt;/p&gt;

&lt;p&gt;Imagine asking an AI coding assistant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Why is this function failing?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behind the scenes, the application might automatically include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System instructions&lt;/li&gt;
&lt;li&gt;Current source file&lt;/li&gt;
&lt;li&gt;Nearby functions&lt;/li&gt;
&lt;li&gt;Package imports&lt;/li&gt;
&lt;li&gt;Build configuration&lt;/li&gt;
&lt;li&gt;Previous conversation&lt;/li&gt;
&lt;li&gt;Compiler errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your four-word prompt becomes a request containing thousands of tokens.&lt;/p&gt;

&lt;p&gt;This is another example of &lt;strong&gt;Context Engineering&lt;/strong&gt; in action.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔄 Every New Request Starts Again
&lt;/h1&gt;

&lt;p&gt;This surprises many engineers.&lt;/p&gt;

&lt;p&gt;Suppose your conversation looks like this:&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;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Explain&lt;/span&gt; &lt;span class="n"&gt;JWT&lt;/span&gt; &lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;Assistant&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Can&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Go&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;

&lt;span class="n"&gt;Assistant&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Can&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many people imagine the model simply remembers everything internally.&lt;/p&gt;

&lt;p&gt;That's not how most stateless LLM API interactions work.&lt;/p&gt;

&lt;p&gt;For each new request, the application typically sends the conversation history (or a selected portion of it) again so the model has the necessary context to continue the conversation coherently.&lt;/p&gt;

&lt;p&gt;Conceptually, it looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request 1

System Prompt
User Message

↓

LLM

------------------------

Request 2

System Prompt
Conversation History
New User Message

↓

LLM

------------------------

Request 3

System Prompt
Conversation History
Latest User Message

↓

LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the conversation grows longer, more tokens are often included with each request unless the application trims, summarizes or otherwise manages the context.&lt;/p&gt;

&lt;p&gt;This is one reason token usage can increase significantly during long conversations.&lt;/p&gt;




&lt;h1&gt;
  
  
  🪟 What Is a Context Window?
&lt;/h1&gt;

&lt;p&gt;Now we can finally answer the question from the beginning.&lt;/p&gt;

&lt;p&gt;If tokens are the building blocks…&lt;/p&gt;

&lt;p&gt;Then what is the &lt;strong&gt;Context Window?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A context window is the maximum amount of information (measured in tokens) that a model can consider at one time while generating a response.&lt;/p&gt;

&lt;p&gt;Think of it like a whiteboard.&lt;/p&gt;

&lt;p&gt;Imagine you're solving a difficult problem with a teammate.&lt;/p&gt;

&lt;p&gt;Everything written on the whiteboard is available to both of you.&lt;/p&gt;

&lt;p&gt;You can read it.&lt;/p&gt;

&lt;p&gt;Reference it.&lt;/p&gt;

&lt;p&gt;Connect ideas.&lt;/p&gt;

&lt;p&gt;Reason about it.&lt;/p&gt;

&lt;p&gt;But the whiteboard isn't infinite.&lt;/p&gt;

&lt;p&gt;Eventually, it fills up.&lt;/p&gt;

&lt;p&gt;To continue working, you have two choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Erase older notes.&lt;/li&gt;
&lt;li&gt;Replace them with a summary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Large Language Models work in a very similar way.&lt;/p&gt;

&lt;p&gt;The context window is that whiteboard.&lt;/p&gt;

&lt;p&gt;Everything currently inside it is visible to the model while it generates its next response.&lt;/p&gt;

&lt;p&gt;Everything outside it is invisible unless your application decides to bring it back.&lt;/p&gt;




&lt;h1&gt;
  
  
  📖 What's Actually Inside the Context Window?
&lt;/h1&gt;

&lt;p&gt;One common misconception is that the context window contains only your prompt.&lt;/p&gt;

&lt;p&gt;In reality, modern AI applications often build a much richer context before sending the request.&lt;/p&gt;

&lt;p&gt;A simplified request might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Instructions

↓

Conversation History

↓

Retrieved Knowledge (RAG)

↓

Uploaded Files

↓

Tool Results

↓

Current User Prompt

↓

LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice something interesting.&lt;/p&gt;

&lt;p&gt;Your latest message may only be a tiny fraction of everything the model receives.&lt;/p&gt;

&lt;p&gt;The application has already assembled the rest of the context behind the scenes.&lt;/p&gt;

&lt;p&gt;This is why two AI tools using the same underlying model can produce very different answers.&lt;/p&gt;

&lt;p&gt;The difference often isn't the model itself.&lt;/p&gt;

&lt;p&gt;It's &lt;strong&gt;how effectively each application constructs the context before making the request.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  🤔 Does a Bigger Context Window Always Mean Better AI?
&lt;/h1&gt;

&lt;p&gt;At first glance, it sounds obvious.&lt;/p&gt;

&lt;p&gt;If an AI model can process more information, shouldn't the answers always improve?&lt;/p&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Imagine you're preparing for an interview.&lt;/p&gt;

&lt;p&gt;Someone gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your resume&lt;/li&gt;
&lt;li&gt;The job description&lt;/li&gt;
&lt;li&gt;Company documentation&lt;/li&gt;
&lt;li&gt;Engineering handbook&lt;/li&gt;
&lt;li&gt;API documentation&lt;/li&gt;
&lt;li&gt;Meeting notes&lt;/li&gt;
&lt;li&gt;Internal wiki&lt;/li&gt;
&lt;li&gt;Product roadmap&lt;/li&gt;
&lt;li&gt;Last year's planning documents&lt;/li&gt;
&lt;li&gt;Random Slack conversations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Could you answer the interview questions?&lt;/p&gt;

&lt;p&gt;Probably.&lt;/p&gt;

&lt;p&gt;Would all that information actually help?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;In fact, it might make things worse because you'd spend time filtering out irrelevant information before focusing on what matters.&lt;/p&gt;

&lt;p&gt;Large Language Models face a similar challenge.&lt;/p&gt;

&lt;p&gt;A larger context window allows the model to &lt;strong&gt;see more information&lt;/strong&gt;, but it doesn't mean every piece of that information is equally useful.&lt;/p&gt;

&lt;p&gt;Good Context Engineering isn't about maximizing context.&lt;/p&gt;

&lt;p&gt;It's about &lt;strong&gt;optimizing context&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎯 More Context ≠ Better Context
&lt;/h1&gt;

&lt;p&gt;One of the biggest mistakes in AI applications is thinking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If some context helps,
more context must help even more.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's rarely true.&lt;/p&gt;

&lt;p&gt;Imagine building an AI coding assistant.&lt;/p&gt;

&lt;p&gt;A developer asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Why is this API returning 500?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Option A:&lt;/p&gt;

&lt;p&gt;Provide only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API handler&lt;/li&gt;
&lt;li&gt;Relevant service&lt;/li&gt;
&lt;li&gt;Error log&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Option B:&lt;/p&gt;

&lt;p&gt;Provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entire repository&lt;/li&gt;
&lt;li&gt;All dependencies&lt;/li&gt;
&lt;li&gt;Every README&lt;/li&gt;
&lt;li&gt;CI/CD configuration&lt;/li&gt;
&lt;li&gt;Kubernetes manifests&lt;/li&gt;
&lt;li&gt;Previous conversations&lt;/li&gt;
&lt;li&gt;All database schemas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technically, the model has more information.&lt;/p&gt;

&lt;p&gt;Practically, you've introduced noise.&lt;/p&gt;

&lt;p&gt;Finding the relevant signal becomes harder.&lt;/p&gt;

&lt;p&gt;This is why mature AI systems spend significant effort deciding &lt;strong&gt;what not to include&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Context Engineering is often about removing information rather than adding it.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔍 The "Lost in the Middle" Problem
&lt;/h1&gt;

&lt;p&gt;Researchers have observed an interesting behavior in long-context language models.&lt;/p&gt;

&lt;p&gt;When a prompt becomes very large, information buried in the middle of the context may receive less attention than information closer to the beginning or end.&lt;/p&gt;

&lt;p&gt;This phenomenon is commonly referred to as the &lt;strong&gt;"Lost in the Middle"&lt;/strong&gt; effect.&lt;/p&gt;

&lt;p&gt;Imagine reading a 300-page document.&lt;/p&gt;

&lt;p&gt;You usually remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The introduction&lt;/li&gt;
&lt;li&gt;The conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But details from page 147?&lt;/p&gt;

&lt;p&gt;Much harder.&lt;/p&gt;

&lt;p&gt;Language models can exhibit similar behavior under certain conditions.&lt;/p&gt;

&lt;p&gt;This doesn't mean long-context models are ineffective.&lt;/p&gt;

&lt;p&gt;It means that &lt;strong&gt;how information is organized inside the context matters&lt;/strong&gt;, not just how much information is included.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 Context Is NOT Memory
&lt;/h1&gt;

&lt;p&gt;This is probably the biggest misconception about modern AI.&lt;/p&gt;

&lt;p&gt;People often say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"ChatGPT remembered what I told it last week."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What actually happened depends on the application.&lt;/p&gt;

&lt;p&gt;It's important to distinguish between &lt;strong&gt;context&lt;/strong&gt; and &lt;strong&gt;memory&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Context is the information available &lt;strong&gt;only for the current request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once the request is complete, the model itself doesn't retain that context for future API calls.&lt;/p&gt;

&lt;p&gt;Think of it as a whiteboard used during a meeting.&lt;/p&gt;

&lt;p&gt;Erase the whiteboard and the discussion is gone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Memory
&lt;/h2&gt;

&lt;p&gt;Memory is information that an application intentionally stores and later reintroduces into future conversations.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;You tell an AI assistant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I primarily write Go and React.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application might choose to save that preference.&lt;/p&gt;

&lt;p&gt;Next week, when you ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate an API example.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application retrieves your stored preference and injects it into the new request.&lt;/p&gt;

&lt;p&gt;The model appears to "remember."&lt;/p&gt;

&lt;p&gt;In reality, the application supplied that information again.&lt;/p&gt;

&lt;p&gt;The memory lives in the application—not inside the language model itself.&lt;/p&gt;




&lt;h1&gt;
  
  
  🏗️ A Simple Mental Model
&lt;/h1&gt;

&lt;p&gt;Think of an AI application as three separate components:&lt;br&gt;
&lt;/p&gt;

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

                  │
                  ▼

      ┌─────────────────────┐
      │   Memory Store      │
      └─────────────────────┘
                  │
                  ▼
      ┌─────────────────────┐
      │ Context Builder     │
      │ - System Prompt     │
      │ - History           │
      │ - RAG Results       │
      │ - Tool Outputs      │
      └─────────────────────┘
                  │
                  ▼
      ┌─────────────────────┐
      │        LLM          │
      └─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM only sees the final assembled context.&lt;/p&gt;

&lt;p&gt;It doesn't know where each piece of information came from.&lt;/p&gt;




&lt;h1&gt;
  
  
  💰 Why Tokens Matter for Cost and Performance
&lt;/h1&gt;

&lt;p&gt;We've already learned that everything consumes tokens.&lt;/p&gt;

&lt;p&gt;But token usage affects much more than pricing.&lt;/p&gt;

&lt;p&gt;It also impacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request latency&lt;/li&gt;
&lt;li&gt;Throughput&lt;/li&gt;
&lt;li&gt;Infrastructure cost&lt;/li&gt;
&lt;li&gt;User experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider these two requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Efficient Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Prompt

Relevant API documentation

Current User Question
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Inefficient Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Prompt

Entire conversation

Complete codebase

Multiple PDFs

Large JSON payloads

Old logs

Current User Question
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second request requires the model to process significantly more information before generating a response.&lt;/p&gt;

&lt;p&gt;Even if the answer only depends on a small portion of that data.&lt;/p&gt;

&lt;p&gt;More tokens generally mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More computation&lt;/li&gt;
&lt;li&gt;Higher latency&lt;/li&gt;
&lt;li&gt;Higher cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why production AI systems invest heavily in efficient context management.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚙️ How Production AI Systems Manage Context
&lt;/h1&gt;

&lt;p&gt;Well-designed AI applications rarely send everything they know to the model.&lt;/p&gt;

&lt;p&gt;Instead, they carefully construct the context.&lt;/p&gt;

&lt;p&gt;Some common strategies include:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Retrieve Only What's Relevant
&lt;/h3&gt;

&lt;p&gt;Instead of sending an entire knowledge base,&lt;/p&gt;

&lt;p&gt;retrieve only the documents related to the user's question.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Summarize Long Conversations
&lt;/h3&gt;

&lt;p&gt;Rather than sending hundreds of previous messages,&lt;/p&gt;

&lt;p&gt;summarize earlier parts while preserving important facts.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;150 previous messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conversation Summary:

• User uses Go
• Building REST APIs
• Uses PostgreSQL
• Currently debugging authentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Far fewer tokens.&lt;/p&gt;

&lt;p&gt;Much easier for the model.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Keep System Prompts Focused
&lt;/h3&gt;

&lt;p&gt;System instructions should define behavior,&lt;/p&gt;

&lt;p&gt;not contain an entire company handbook.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Separate Long-Term Memory from Current Context
&lt;/h3&gt;

&lt;p&gt;Store reusable preferences separately.&lt;/p&gt;

&lt;p&gt;Retrieve them only when needed.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Measure Token Usage
&lt;/h3&gt;

&lt;p&gt;Don't optimize blindly.&lt;/p&gt;

&lt;p&gt;Most AI SDKs expose token usage statistics.&lt;/p&gt;

&lt;p&gt;Monitoring them helps identify unnecessary context and control costs.&lt;/p&gt;




&lt;h1&gt;
  
  
  🚫 Common Context Engineering Mistakes
&lt;/h1&gt;

&lt;p&gt;Here are some patterns that often reduce AI quality rather than improve it.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Dumping entire documents into every request
&lt;/h3&gt;

&lt;p&gt;More information isn't automatically better.&lt;/p&gt;




&lt;h3&gt;
  
  
  ❌ Sending the full conversation forever
&lt;/h3&gt;

&lt;p&gt;Long conversations should be summarized or trimmed when appropriate.&lt;/p&gt;




&lt;h3&gt;
  
  
  ❌ Treating memory as conversation history
&lt;/h3&gt;

&lt;p&gt;They're different concepts.&lt;/p&gt;




&lt;h3&gt;
  
  
  ❌ Ignoring token usage
&lt;/h3&gt;

&lt;p&gt;Unexpected token growth often leads to higher costs and slower responses.&lt;/p&gt;




&lt;h3&gt;
  
  
  ❌ Assuming bigger context windows solve everything
&lt;/h3&gt;

&lt;p&gt;Context quality matters far more than context quantity.&lt;/p&gt;




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

&lt;p&gt;If you're building AI-powered applications, keep these principles in mind:&lt;/p&gt;

&lt;p&gt;✅ Send only the information required for the current task.&lt;/p&gt;

&lt;p&gt;✅ Prefer relevant context over larger context.&lt;/p&gt;

&lt;p&gt;✅ Separate memory from conversation history.&lt;/p&gt;

&lt;p&gt;✅ Summarize older interactions instead of continuously expanding prompts.&lt;/p&gt;

&lt;p&gt;✅ Monitor token usage in production.&lt;/p&gt;

&lt;p&gt;✅ Design context deliberately instead of simply appending more text.&lt;/p&gt;




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

&lt;p&gt;When people first start working with AI, they often focus on prompts.&lt;/p&gt;

&lt;p&gt;Then they discover Context Engineering.&lt;/p&gt;

&lt;p&gt;Eventually, they realize another important truth:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not all context is equally valuable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern AI systems succeed because they carefully decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What to include&lt;/li&gt;
&lt;li&gt;What to exclude&lt;/li&gt;
&lt;li&gt;What to summarize&lt;/li&gt;
&lt;li&gt;What to retrieve&lt;/li&gt;
&lt;li&gt;What to remember&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That decision-making process is often more important than the prompt itself.&lt;/p&gt;

&lt;p&gt;The best AI applications aren't the ones with the biggest context windows.&lt;/p&gt;

&lt;p&gt;They're the ones that provide &lt;strong&gt;the right information at the right time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that's exactly what Context Engineering is about.&lt;/p&gt;




&lt;h1&gt;
  
  
  📌 Key Takeaways
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Tokens are the fundamental units processed by language models—they are not the same as words.&lt;/li&gt;
&lt;li&gt;Every request consumes tokens, including system prompts, conversation history, retrieved documents, tool outputs and the model's response.&lt;/li&gt;
&lt;li&gt;A context window defines how much information a model can consider at once.&lt;/li&gt;
&lt;li&gt;Larger context windows are useful, but more context doesn't automatically lead to better answers.&lt;/li&gt;
&lt;li&gt;Context and memory are different: context exists for the current request, while memory is information intentionally stored and reintroduced by the application.&lt;/li&gt;
&lt;li&gt;Effective Context Engineering is about sending &lt;strong&gt;relevant&lt;/strong&gt; information, not &lt;strong&gt;all&lt;/strong&gt; available information.&lt;/li&gt;
&lt;li&gt;Good context management improves response quality, reduces costs and lowers latency.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🚀 Coming Up in Part 3
&lt;/h1&gt;

&lt;p&gt;So far, we've answered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Context Engineering?&lt;/li&gt;
&lt;li&gt;What are tokens?&lt;/li&gt;
&lt;li&gt;How do context windows work?&lt;/li&gt;
&lt;li&gt;Why isn't bigger context always better?&lt;/li&gt;
&lt;li&gt;What's the difference between context and memory?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But another important question remains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where does all this context actually come from?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do AI applications automatically search documentation, query databases, call APIs, execute tools and decide what information should be sent to the model?&lt;/p&gt;

&lt;p&gt;That's where concepts like &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt;, &lt;strong&gt;Tool Calling&lt;/strong&gt;, &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; and &lt;strong&gt;AI Agents&lt;/strong&gt; come into the picture.&lt;/p&gt;

&lt;p&gt;We'll break each of them down in &lt;strong&gt;Part 3&lt;/strong&gt; with practical examples and real-world engineering scenarios.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🧠 AI Context Engineering — Why Great AI Systems Need More Than Great Prompts (Part 1)</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 27 Jun 2026 11:15:39 +0000</pubDate>
      <link>https://dev.to/fazal_mansuri_/ai-context-engineering-why-great-ai-systems-need-more-than-great-prompts-part-1-25dd</link>
      <guid>https://dev.to/fazal_mansuri_/ai-context-engineering-why-great-ai-systems-need-more-than-great-prompts-part-1-25dd</guid>
      <description>&lt;p&gt;A couple of years ago, almost every AI discussion revolved around one thing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Prompt Engineering.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People shared prompts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Use this prompt to become a senior software engineer."&lt;/li&gt;
&lt;li&gt;"Use this prompt to write perfect SQL."&lt;/li&gt;
&lt;li&gt;"Use this prompt to generate production-ready code."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The assumption was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Better prompt = Better AI output.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While prompts certainly matter, engineers building production AI systems quickly realized something important:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The prompt is only one piece of the puzzle.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern AI applications - whether it's ChatGPT, Claude, Cursor, GitHub Copilot or AI coding agents - don't rely on a single prompt.&lt;/p&gt;

&lt;p&gt;They combine multiple sources of information before generating a response.&lt;/p&gt;

&lt;p&gt;That broader discipline is known as &lt;strong&gt;Context Engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And understanding it is becoming one of the most valuable skills for engineers building AI-powered products.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Is Context Engineering?
&lt;/h1&gt;

&lt;p&gt;Context Engineering is the practice of providing an AI model with the &lt;strong&gt;right information at the right time&lt;/strong&gt; so it can generate accurate, relevant, and reliable responses.&lt;/p&gt;

&lt;p&gt;Think of it this way:&lt;/p&gt;

&lt;p&gt;Prompt Engineering asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What should I ask the model?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Context Engineering asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What information should the model have before it answers?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That difference might sound subtle.&lt;/p&gt;

&lt;p&gt;In reality, it changes everything.&lt;/p&gt;




&lt;h1&gt;
  
  
  A Simple Analogy
&lt;/h1&gt;

&lt;p&gt;Imagine you ask two developers the same question.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I fix this production bug?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Developer A
&lt;/h3&gt;

&lt;p&gt;You only tell them:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The application is broken."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Can they help?&lt;/p&gt;

&lt;p&gt;Maybe.&lt;/p&gt;

&lt;p&gt;But they'll probably ask dozens of follow-up questions.&lt;/p&gt;




&lt;h3&gt;
  
  
  Developer B
&lt;/h3&gt;

&lt;p&gt;Instead, you provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error logs&lt;/li&gt;
&lt;li&gt;Stack trace&lt;/li&gt;
&lt;li&gt;API request&lt;/li&gt;
&lt;li&gt;Database query&lt;/li&gt;
&lt;li&gt;Recent deployment&lt;/li&gt;
&lt;li&gt;Service architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now they're much more likely to identify the issue quickly.&lt;/p&gt;

&lt;p&gt;Did they become smarter?&lt;/p&gt;

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

&lt;p&gt;You simply gave them &lt;strong&gt;better context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Large Language Models work the same way.&lt;/p&gt;




&lt;h1&gt;
  
  
  Prompt vs Context
&lt;/h1&gt;

&lt;p&gt;Suppose you ask an AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;Write&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;SQL&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="k"&gt;fetch&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a perfectly valid prompt.&lt;/p&gt;

&lt;p&gt;But now imagine providing additional context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PostgreSQL&lt;/span&gt;

&lt;span class="n"&gt;Tables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;

&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;ACTIVE&lt;/span&gt;
&lt;span class="n"&gt;INACTIVE&lt;/span&gt;
&lt;span class="n"&gt;BLOCKED&lt;/span&gt;

&lt;span class="k"&gt;Return&lt;/span&gt; &lt;span class="k"&gt;only&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt; &lt;span class="k"&gt;after&lt;/span&gt; &lt;span class="n"&gt;January&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt itself barely changed.&lt;/p&gt;

&lt;p&gt;What improved was the &lt;strong&gt;context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And naturally, the quality of the output improves as well.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Prompt Engineering Alone Isn't Enough
&lt;/h1&gt;

&lt;p&gt;Imagine building an AI customer support assistant.&lt;/p&gt;

&lt;p&gt;If every user message is handled using only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User:
Where is my order?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the model has no idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which customer is asking&lt;/li&gt;
&lt;li&gt;Which order they mean&lt;/li&gt;
&lt;li&gt;Whether it has already been shipped&lt;/li&gt;
&lt;li&gt;Previous conversations&lt;/li&gt;
&lt;li&gt;Company refund policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without that information, the model can only guess.&lt;/p&gt;

&lt;p&gt;Instead, production AI systems enrich the request with additional context before sending it to the model.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Instructions

Customer Name

Previous Conversation

Order Status

Shipping Details

Refund Policy

Current User Question
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model now has everything it needs to generate a useful answer.&lt;/p&gt;

&lt;p&gt;Notice something interesting:&lt;/p&gt;

&lt;p&gt;The user's prompt didn't become dramatically better.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;available context&lt;/strong&gt; did.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Actually Forms the Context?
&lt;/h1&gt;

&lt;p&gt;Many developers think context means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The text I type into ChatGPT."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's only part of it.&lt;/p&gt;

&lt;p&gt;In reality, the model usually receives much more information.&lt;/p&gt;

&lt;p&gt;A typical request may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System instructions&lt;/li&gt;
&lt;li&gt;User prompt&lt;/li&gt;
&lt;li&gt;Conversation history&lt;/li&gt;
&lt;li&gt;Retrieved documentation&lt;/li&gt;
&lt;li&gt;Project files&lt;/li&gt;
&lt;li&gt;Tool outputs&lt;/li&gt;
&lt;li&gt;Function call results&lt;/li&gt;
&lt;li&gt;Memory from previous interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this together forms the &lt;strong&gt;context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The model doesn't distinguish whether information came from you, a database, or another tool.&lt;/p&gt;

&lt;p&gt;It simply processes the complete context it receives.&lt;/p&gt;




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

&lt;p&gt;Consider an AI coding assistant.&lt;/p&gt;

&lt;p&gt;You ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain this function.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does it know which function you're referring to?&lt;/p&gt;

&lt;p&gt;It doesn't.&lt;/p&gt;

&lt;p&gt;The IDE silently provides additional context such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The currently opened file&lt;/li&gt;
&lt;li&gt;Surrounding code&lt;/li&gt;
&lt;li&gt;Project structure&lt;/li&gt;
&lt;li&gt;Imported packages&lt;/li&gt;
&lt;li&gt;Programming language&lt;/li&gt;
&lt;li&gt;Cursor position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You only typed four words.&lt;/p&gt;

&lt;p&gt;Yet the model received thousands of tokens of additional information behind the scenes.&lt;/p&gt;

&lt;p&gt;That's Context Engineering in action.&lt;/p&gt;




&lt;h1&gt;
  
  
  Another Example: ChatGPT
&lt;/h1&gt;

&lt;p&gt;Suppose you ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Summarize this document.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What actually reaches the model?&lt;/p&gt;

&lt;p&gt;Something closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Instructions

Conversation History

Uploaded PDF

User Prompt

Formatting Rules

Safety Instructions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, the prompt is only a small part of the overall request.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Mental Shift
&lt;/h1&gt;

&lt;p&gt;Many developers spend hours refining prompts like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Act as a senior software engineer with 20 years of experience...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes it helps.&lt;/p&gt;

&lt;p&gt;But often, providing the model with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better documentation&lt;/li&gt;
&lt;li&gt;Relevant code&lt;/li&gt;
&lt;li&gt;Correct API schemas&lt;/li&gt;
&lt;li&gt;Business rules&lt;/li&gt;
&lt;li&gt;Examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;produces significantly better results than endlessly tweaking the wording of the prompt.&lt;/p&gt;

&lt;p&gt;The question changes from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How should I ask?"&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"What information is the model missing?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the mindset of Context Engineering.&lt;/p&gt;




&lt;h1&gt;
  
  
  Common Misconceptions
&lt;/h1&gt;

&lt;h3&gt;
  
  
  ❌ "A bigger prompt always gives better answers."
&lt;/h3&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Adding irrelevant information can confuse the model.&lt;/p&gt;

&lt;p&gt;Good context is &lt;strong&gt;relevant&lt;/strong&gt;, &lt;strong&gt;accurate&lt;/strong&gt;, and &lt;strong&gt;focused&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  ❌ "Prompt Engineering is no longer useful."
&lt;/h3&gt;

&lt;p&gt;Prompt Engineering is still important.&lt;/p&gt;

&lt;p&gt;A clear prompt helps the model understand the task.&lt;/p&gt;

&lt;p&gt;Context Engineering simply expands the scope by ensuring the model also has the information required to perform that task well.&lt;/p&gt;

&lt;p&gt;Think of prompt engineering as one part of the larger Context Engineering process.&lt;/p&gt;




&lt;h3&gt;
  
  
  ❌ "Only AI engineers need to know this."
&lt;/h3&gt;

&lt;p&gt;If you build software that integrates AI in any form—chatbots, coding assistants, document search, customer support, or internal tools—understanding how context influences responses will help you design more reliable systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why This Matters More Than Ever
&lt;/h1&gt;

&lt;p&gt;Modern AI applications are no longer just chat interfaces.&lt;/p&gt;

&lt;p&gt;They're becoming agents that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read documents&lt;/li&gt;
&lt;li&gt;Search knowledge bases&lt;/li&gt;
&lt;li&gt;Execute tools&lt;/li&gt;
&lt;li&gt;Call APIs&lt;/li&gt;
&lt;li&gt;Generate code&lt;/li&gt;
&lt;li&gt;Reason over project files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The quality of these systems depends less on writing a "magic prompt" and more on giving the model the &lt;strong&gt;right context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that's exactly what Context Engineering is about.&lt;/p&gt;




&lt;h1&gt;
  
  
  What's Coming in Part 2?
&lt;/h1&gt;

&lt;p&gt;Now that we understand why context matters, another important question arises:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much context should we provide?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is more always better?&lt;/p&gt;

&lt;p&gt;What are &lt;strong&gt;tokens&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;What is a &lt;strong&gt;context window&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Why do AI tools sometimes forget earlier parts of a conversation?&lt;/p&gt;

&lt;p&gt;And why can adding too much information actually reduce response quality?&lt;/p&gt;

&lt;p&gt;We'll answer all of these in &lt;strong&gt;Part 2&lt;/strong&gt;, where we'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context Windows&lt;/li&gt;
&lt;li&gt;Tokens&lt;/li&gt;
&lt;li&gt;Conversation History&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;Why bigger context isn't always better&lt;/li&gt;
&lt;li&gt;Practical strategies used by modern AI applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding these concepts will completely change how you think about interacting with—and building—AI systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  Key Takeaways
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Prompt Engineering and Context Engineering are related, but not the same.&lt;/li&gt;
&lt;li&gt;Great AI systems rely on much more than the user's prompt.&lt;/li&gt;
&lt;li&gt;Context includes system instructions, conversation history, retrieved information, tool outputs, and more.&lt;/li&gt;
&lt;li&gt;Better context often improves AI responses more than endlessly refining prompts.&lt;/li&gt;
&lt;li&gt;Thinking in terms of &lt;strong&gt;"What information is the model missing?"&lt;/strong&gt; is the first step toward building effective AI-powered applications.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you've ever wondered why the same prompt produces excellent results in one AI application and poor results in another, the answer often isn't the model itself.&lt;/p&gt;

&lt;p&gt;It's the &lt;strong&gt;context&lt;/strong&gt; behind the scenes.&lt;/p&gt;

&lt;p&gt;See you in &lt;strong&gt;Part 2&lt;/strong&gt; 👋&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🚨 CSS Specificity — The Hidden Reason Your UI Breaks</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 06 Jun 2026 06:57:43 +0000</pubDate>
      <link>https://dev.to/fazal_mansuri_/css-specificity-the-hidden-reason-your-ui-breaks-2jhp</link>
      <guid>https://dev.to/fazal_mansuri_/css-specificity-the-hidden-reason-your-ui-breaks-2jhp</guid>
      <description>&lt;p&gt;Most developers learn CSS specificity once.&lt;/p&gt;

&lt;p&gt;They remember:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.class&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then move on.&lt;/p&gt;

&lt;p&gt;Until one day…&lt;/p&gt;

&lt;p&gt;Everything looks correct.&lt;/p&gt;

&lt;p&gt;The CSS is present.&lt;/p&gt;

&lt;p&gt;The selector is correct.&lt;/p&gt;

&lt;p&gt;The z-index looks higher.&lt;/p&gt;

&lt;p&gt;And yet the UI is broken.&lt;/p&gt;

&lt;p&gt;That’s when CSS specificity stops being a beginner topic and becomes a production debugging problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Production Incident That Started This
&lt;/h1&gt;

&lt;p&gt;Recently, I was working on a microfrontend application.&lt;/p&gt;

&lt;p&gt;Everything worked fine initially.&lt;/p&gt;

&lt;p&gt;I opened a page, launched a modal and the UI looked correct.&lt;/p&gt;

&lt;p&gt;Then I navigated to another microfrontend.&lt;/p&gt;

&lt;p&gt;Its CSS got loaded.&lt;/p&gt;

&lt;p&gt;After returning to the original microfrontend, suddenly:&lt;/p&gt;

&lt;p&gt;❌ Modal appeared behind page content&lt;br&gt;
❌ Overlay behaved incorrectly&lt;br&gt;
❌ z-index looked correct but wasn't working&lt;/p&gt;

&lt;p&gt;DevTools showed my CSS rule still existed.&lt;/p&gt;

&lt;p&gt;Yet another CSS rule was winning.&lt;/p&gt;

&lt;p&gt;The culprit?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CSS Specificity.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h1&gt;
  
  
  🧠 What is CSS Specificity?
&lt;/h1&gt;

&lt;p&gt;CSS specificity is the algorithm browsers use to decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which CSS rule wins when multiple rules target the same element.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Browsers don't simply apply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The last CSS rule."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's one of the biggest misconceptions.&lt;/p&gt;

&lt;p&gt;Specificity is calculated first.&lt;/p&gt;

&lt;p&gt;Only when specificity is equal does source order become important.&lt;/p&gt;


&lt;h1&gt;
  
  
  ⚔️ Example
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.some-library&lt;/span&gt; &lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&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;HTML:&lt;br&gt;
&lt;/p&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"some-library"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many developers expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to win because the value is larger.&lt;/p&gt;

&lt;p&gt;But CSS doesn't compare values first.&lt;/p&gt;

&lt;p&gt;It compares selectors.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧮 How Specificity Works
&lt;/h1&gt;

&lt;p&gt;Specificity is usually represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ID - CLASS - TYPE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Specificity Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Selector&lt;/th&gt;
&lt;th&gt;Specificity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0-0-0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;div&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0-0-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.modal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0-1-0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[type="text"]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0-1-0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;:hover&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0-1-0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#dialog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1-0-0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inline Style&lt;/td&gt;
&lt;td&gt;Highest&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;MDN defines specificity as the weight browsers calculate to determine which declaration gets applied when multiple selectors match the same element.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Calculation
&lt;/h1&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.primary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;button&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-0-1&lt;/span&gt;
&lt;span class="nc"&gt;.primary&lt;/span&gt;   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-1-0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;






&lt;p&gt;Another selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#header&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.primary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#header&lt;/span&gt;   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;-0-0&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt;    &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-0-1&lt;/span&gt;
&lt;span class="nc"&gt;.primary&lt;/span&gt;  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-1-0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;This selector wins.&lt;/p&gt;




&lt;h1&gt;
  
  
  ❌ Myth #1 — Last CSS Always Wins
&lt;/h1&gt;

&lt;p&gt;Many developers believe:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The CSS rule written last wins.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not always.&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 css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#header&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;div&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;blue&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;HTML:&lt;br&gt;
&lt;/p&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;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Hello
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#header = 1-0-0
div     = 0-0-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specificity wins before source order.&lt;/p&gt;




&lt;h1&gt;
  
  
  ❌ Myth #2 — Higher z-index Always Wins
&lt;/h1&gt;

&lt;p&gt;This causes countless production bugs.&lt;/p&gt;

&lt;p&gt;Developers often write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;99999&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;And expect it to appear above everything.&lt;/p&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;z-index works inside stacking contexts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  🧠 What is a Stacking Context?
&lt;/h1&gt;

&lt;p&gt;A stacking context is a separate layering environment.&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 css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.parent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;999999&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;Even with:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;the child cannot escape its parent's stacking context.&lt;/p&gt;

&lt;p&gt;This is why modal, tooltip, dropdown, and popover bugs often feel confusing.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Microfrontend Problem
&lt;/h1&gt;

&lt;p&gt;This is where specificity becomes extremely important.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;/p&gt;

&lt;h3&gt;
  
  
  Microfrontend A
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9999&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;
  
  
  Microfrontend B
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.layout&lt;/span&gt; &lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&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;Specificity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt;
&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-1-0&lt;/span&gt;

&lt;span class="nc"&gt;.layout&lt;/span&gt; &lt;span class="nc"&gt;.modal&lt;/span&gt;
&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-2-0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Microfrontend B wins.&lt;/p&gt;

&lt;p&gt;Even if your CSS is still loaded.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why My Fix Worked
&lt;/h1&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9999&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;But another selector had higher specificity.&lt;/p&gt;

&lt;p&gt;So I wrapped the modal:&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dialog-wrapper"&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="nc"&gt;Modal&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.dialog-wrapper&lt;/span&gt; &lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9999&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;Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal&lt;/span&gt;
&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-1-0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.dialog-wrapper&lt;/span&gt; &lt;span class="nc"&gt;.modal&lt;/span&gt;
&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;-2-0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now my selector became more specific and started winning.&lt;/p&gt;

&lt;p&gt;The CSS value never changed.&lt;/p&gt;

&lt;p&gt;Only specificity changed.&lt;/p&gt;

&lt;p&gt;And the issue disappeared.&lt;/p&gt;




&lt;h1&gt;
  
  
  🚨 Why This Happens More in Microfrontends
&lt;/h1&gt;

&lt;p&gt;Microfrontends often share:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same DOM&lt;/li&gt;
&lt;li&gt;Same global CSS&lt;/li&gt;
&lt;li&gt;Same class names&lt;/li&gt;
&lt;li&gt;Same browser environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Problems include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS leakage&lt;/li&gt;
&lt;li&gt;Style collisions&lt;/li&gt;
&lt;li&gt;Unexpected overrides&lt;/li&gt;
&lt;li&gt;Load-order changes after navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes specificity bugs significantly more common.&lt;/p&gt;




&lt;h1&gt;
  
  
  Modern CSS Specificity Features Developers Often Miss
&lt;/h1&gt;




&lt;h1&gt;
  
  
  1️⃣ &lt;code&gt;:is()&lt;/code&gt;
&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 css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.btn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.link&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;:is()&lt;/code&gt; pseudo-class itself doesn't add specificity.&lt;/p&gt;

&lt;p&gt;Instead, it takes the specificity of the most specific selector inside it.&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 css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.btn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#header&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#header&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is most specific.&lt;/p&gt;




&lt;h1&gt;
  
  
  2️⃣ &lt;code&gt;:not()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Many developers think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.hidden&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;adds nothing.&lt;/p&gt;

&lt;p&gt;Not true.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:not()&lt;/code&gt; itself doesn't contribute specificity.&lt;/p&gt;

&lt;p&gt;But selectors inside it do.&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 css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.hidden&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;






&lt;h1&gt;
  
  
  3️⃣ &lt;code&gt;:where()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;One of the most underrated CSS features.&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 css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.btn&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;Always.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:where()&lt;/code&gt; intentionally has zero specificity.&lt;/p&gt;

&lt;p&gt;This makes it extremely useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design systems&lt;/li&gt;
&lt;li&gt;Component libraries&lt;/li&gt;
&lt;li&gt;Shared UI frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because consumers can easily override styles.&lt;/p&gt;




&lt;h1&gt;
  
  
  How to Debug CSS Specificity Issues
&lt;/h1&gt;

&lt;p&gt;When CSS isn't applying:&lt;/p&gt;

&lt;p&gt;Check these in order:&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Is the rule present?
&lt;/h2&gt;

&lt;p&gt;Open DevTools.&lt;/p&gt;

&lt;p&gt;Verify the CSS exists.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Is it crossed out?
&lt;/h2&gt;

&lt;p&gt;Crossed-out CSS usually means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Another rule won.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Which selector is winning?
&lt;/h2&gt;

&lt;p&gt;DevTools shows the winning selector.&lt;/p&gt;

&lt;p&gt;Inspect it carefully.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Compare specificity
&lt;/h2&gt;

&lt;p&gt;Many bugs become obvious here.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Check CSS load order
&lt;/h2&gt;

&lt;p&gt;When specificity is equal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Last rule wins.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Check stacking contexts
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Modals&lt;/li&gt;
&lt;li&gt;Dropdowns&lt;/li&gt;
&lt;li&gt;Tooltips&lt;/li&gt;
&lt;li&gt;Popovers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Check portals
&lt;/h2&gt;

&lt;p&gt;React portals often render outside expected DOM hierarchy.&lt;/p&gt;

&lt;p&gt;This changes how CSS behaves.&lt;/p&gt;




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

&lt;p&gt;✅ Prefer class selectors over IDs&lt;/p&gt;

&lt;p&gt;✅ Avoid deeply nested selectors&lt;/p&gt;

&lt;p&gt;✅ Use low-specificity CSS in shared libraries&lt;/p&gt;

&lt;p&gt;✅ Use &lt;code&gt;:where()&lt;/code&gt; for easily overridable styles&lt;/p&gt;

&lt;p&gt;✅ Be careful with global CSS in microfrontends&lt;/p&gt;

&lt;p&gt;✅ Avoid excessive &lt;code&gt;!important&lt;/code&gt;&lt;/p&gt;




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

&lt;p&gt;Most developers think CSS specificity is a beginner topic.&lt;/p&gt;

&lt;p&gt;In reality:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's one of the most common reasons production UIs break unexpectedly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Especially in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large applications&lt;/li&gt;
&lt;li&gt;Design systems&lt;/li&gt;
&lt;li&gt;Microfrontends&lt;/li&gt;
&lt;li&gt;Shared component libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tricky part is that the CSS often looks correct.&lt;/p&gt;

&lt;p&gt;The rule exists.&lt;/p&gt;

&lt;p&gt;The value is correct.&lt;/p&gt;

&lt;p&gt;And yet another selector silently wins.&lt;/p&gt;

&lt;p&gt;Understanding specificity deeply transforms CSS debugging from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trial and Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;






&lt;h1&gt;
  
  
  Key Takeaways
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;CSS does not simply apply the last rule&lt;/li&gt;
&lt;li&gt;Specificity determines which selector wins&lt;/li&gt;
&lt;li&gt;Higher z-index does not always mean higher visibility&lt;/li&gt;
&lt;li&gt;Microfrontends make specificity issues more common&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:is()&lt;/code&gt;, &lt;code&gt;:not()&lt;/code&gt;, and &lt;code&gt;:where()&lt;/code&gt; have special specificity behavior&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!important&lt;/code&gt; should be a last resort&lt;/li&gt;
&lt;li&gt;DevTools can quickly reveal specificity conflicts when used correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding CSS specificity is one of those skills that feels minor — until it saves you hours of debugging a production UI issue.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>css</category>
      <category>learning</category>
    </item>
    <item>
      <title>API Pagination - Offset vs Cursor Pagination Explained</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sat, 16 May 2026 10:42:41 +0000</pubDate>
      <link>https://dev.to/fazal_mansuri_/api-pagination-offset-vs-cursor-pagination-explained-2bb5</link>
      <guid>https://dev.to/fazal_mansuri_/api-pagination-offset-vs-cursor-pagination-explained-2bb5</guid>
      <description>&lt;p&gt;Most APIs don’t return all records at once.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Millions of users&lt;/li&gt;
&lt;li&gt;Thousands of orders&lt;/li&gt;
&lt;li&gt;Endless social media posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Returning everything in a single response would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consume huge memory&lt;/li&gt;
&lt;li&gt;Slow down queries&lt;/li&gt;
&lt;li&gt;Increase network payload&lt;/li&gt;
&lt;li&gt;Crash clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why APIs use:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pagination&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But here’s where many developers make mistakes:&lt;/p&gt;

&lt;p&gt;Not all pagination strategies are equal.&lt;/p&gt;

&lt;p&gt;The two most common approaches are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Offset Pagination&lt;/li&gt;
&lt;li&gt;Cursor Pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And choosing the wrong one can create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow APIs&lt;/li&gt;
&lt;li&gt;Duplicate records&lt;/li&gt;
&lt;li&gt;Missing data&lt;/li&gt;
&lt;li&gt;Poor user experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s understand everything properly.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 What is Pagination?
&lt;/h1&gt;

&lt;p&gt;Pagination means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Splitting large datasets into smaller chunks (pages).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of:&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;GET /posts
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You request:&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;GET /posts?page=1&amp;amp;limit=10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;User experience&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  📦 Offset Pagination
&lt;/h1&gt;

&lt;p&gt;Offset pagination is the most common approach.&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 http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /posts?offset=20&amp;amp;limit=10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skip first 20 rows&lt;/li&gt;
&lt;li&gt;Return next 10 rows&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚙️ SQL Behind It
&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;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Simple Go Example - Offset Pagination
&lt;/h1&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;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"strconv"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Post&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;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"title"`&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;posts&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Post "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getPosts&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;query&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;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;offset&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;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;"offset"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;limit&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;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;"limit"&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;limit&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;limit&lt;/span&gt; &lt;span class="o"&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;end&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&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;end&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&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="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&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;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&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="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;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/posts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server running on http://localhost:8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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;ListenAndServe&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="no"&gt;nil&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;
  
  
  ▶️ Run It
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run offset-pagination.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  📡 API Call
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://localhost:8080/posts?offset=20&amp;amp;limit=5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  📦 Response
&lt;/h1&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 21"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 22"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 23"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 24"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 25"&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;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;h1&gt;
  
  
  ✅ Advantages of Offset Pagination
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Simple to implement&lt;/li&gt;
&lt;li&gt;Easy to understand&lt;/li&gt;
&lt;li&gt;Supports random page access&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 plaintext"&gt;&lt;code&gt;?page=50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  ❌ Problems with Offset Pagination
&lt;/h1&gt;

&lt;p&gt;This is where things become interesting.&lt;/p&gt;

&lt;h1&gt;
  
  
  ⚠️ Problem 1 — Slow Queries at Scale
&lt;/h1&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Database still scans and skips 1 million rows.&lt;/p&gt;

&lt;p&gt;💥 Very expensive.&lt;/p&gt;

&lt;h1&gt;
  
  
  ⚠️ Problem 2 — Duplicate / Missing Records
&lt;/h1&gt;

&lt;p&gt;Suppose user loads:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Meanwhile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New rows inserted&lt;/li&gt;
&lt;li&gt;Old rows deleted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now user loads:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate rows&lt;/li&gt;
&lt;li&gt;Missing rows&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  📉 Visual Problem
&lt;/h1&gt;



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

1 2 3 4 5 6 7 8 9 10

User fetches:
OFFSET 0 LIMIT 5

Gets:
1 2 3 4 5

Now new record inserted at top:

0 1 2 3 4 5 6 7 8 9 10

User fetches:
OFFSET 5 LIMIT 5

Gets:
5 6 7 8 9

⚠️ Duplicate "5"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  🚀 Cursor Pagination
&lt;/h1&gt;

&lt;p&gt;Cursor pagination solves these problems.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skipping rows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give records AFTER this specific item.&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 http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /posts?cursor=20&amp;amp;limit=10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give next 10 posts after ID 20&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚙️ SQL Behind It
&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;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Database uses index efficiently.&lt;/p&gt;




&lt;h1&gt;
  
  
  Simple Go Example — Cursor Pagination
&lt;/h1&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;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"strconv"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Post&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;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"title"`&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;posts&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Post "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Itoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getPosts&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;query&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;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;cursor&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;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;"cursor"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;limit&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;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;"limit"&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;limit&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;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&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;result&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;posts&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;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&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;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&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="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;break&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="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;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&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="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;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/posts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server running on http://localhost:8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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;ListenAndServe&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="no"&gt;nil&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;
  
  
  ▶️ Run It
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run cursor-pagination.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  📡 API Call
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://localhost:8080/posts?cursor=10&amp;amp;limit=5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  📦 Response
&lt;/h1&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 11"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 12"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 13"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 14"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Post 15"&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;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;h1&gt;
  
  
  ✅ Advantages of Cursor Pagination
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Fast for large datasets&lt;/li&gt;
&lt;li&gt;Uses indexes efficiently&lt;/li&gt;
&lt;li&gt;No duplicate/missing rows issue&lt;/li&gt;
&lt;li&gt;Better for real-time systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚠️ Trade-Offs of Cursor Pagination
&lt;/h1&gt;

&lt;p&gt;Not perfect either.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❌ No Random Page Access
&lt;/h2&gt;

&lt;p&gt;You cannot easily jump to:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Need sequential navigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❌ More Complex Implementation
&lt;/h2&gt;

&lt;p&gt;Need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stable sorting&lt;/li&gt;
&lt;li&gt;Unique cursor&lt;/li&gt;
&lt;li&gt;Cursor encoding sometimes&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🧠 What Companies Usually Do
&lt;/h1&gt;




&lt;h2&gt;
  
  
  🟢 Offset Pagination
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Admin panels&lt;/li&gt;
&lt;li&gt;Internal dashboards&lt;/li&gt;
&lt;li&gt;Small datasets&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🟣 Cursor Pagination
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Social media feeds&lt;/li&gt;
&lt;li&gt;Infinite scroll&lt;/li&gt;
&lt;li&gt;Messaging apps&lt;/li&gt;
&lt;li&gt;Large-scale APIs&lt;/li&gt;
&lt;/ul&gt;




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

&lt;h2&gt;
  
  
  Instagram / Twitter Feed
&lt;/h2&gt;

&lt;p&gt;Do you think they use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;5000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❌ No chance.&lt;/p&gt;

&lt;p&gt;They use cursor-based pagination.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚡ Performance Difference
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Offset Pagination
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DB scans huge rows ❌&lt;/p&gt;




&lt;h2&gt;
  
  
  Cursor Pagination
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Direct index lookup ✅&lt;/p&gt;




&lt;h1&gt;
  
  
  🔐 Important Cursor Pagination Rule
&lt;/h1&gt;

&lt;p&gt;Cursor field must be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Indexed&lt;/li&gt;
&lt;li&gt;Unique&lt;/li&gt;
&lt;li&gt;Stable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;Created timestamp&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚠️ Common Developer Mistakes
&lt;/h1&gt;

&lt;h3&gt;
  
  
  ❌ Using OFFSET for infinite scroll
&lt;/h3&gt;

&lt;p&gt;Bad at scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Cursor based on non-unique column
&lt;/h3&gt;

&lt;p&gt;Can create duplicates.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Forgetting stable ordering
&lt;/h3&gt;

&lt;p&gt;Pagination becomes inconsistent.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 Key Mental Model
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Offset Pagination
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Skip N rows”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cursor Pagination
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Continue after this row”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  📊 Quick Comparison
&lt;/h1&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;Offset Pagination&lt;/th&gt;
&lt;th&gt;Cursor Pagination&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Easy implementation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Random page access&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large dataset performance&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infinite scroll&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate/missing record safety&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;Pagination seems simple.&lt;/p&gt;

&lt;p&gt;But poor pagination strategy can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow down APIs&lt;/li&gt;
&lt;li&gt;Break user experience&lt;/li&gt;
&lt;li&gt;Create inconsistent data&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🎯 Key Takeaways
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Offset pagination is simple but doesn’t scale well&lt;/li&gt;
&lt;li&gt;Cursor pagination is efficient and production-friendly&lt;/li&gt;
&lt;li&gt;Infinite scroll systems should prefer cursor pagination&lt;/li&gt;
&lt;li&gt;Always use indexed &amp;amp; stable cursor fields&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Good API design is not just about returning data.&lt;/p&gt;

&lt;p&gt;It’s about returning data efficiently — even at massive scale.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>api</category>
      <category>softwaredevelopment</category>
      <category>performance</category>
    </item>
    <item>
      <title>GraphQL vs REST - Which One Should You Really Use?</title>
      <dc:creator>Fazal Mansuri</dc:creator>
      <pubDate>Sun, 26 Apr 2026 07:04:52 +0000</pubDate>
      <link>https://dev.to/fazal_mansuri_/graphql-vs-rest-which-one-should-you-really-use-2na0</link>
      <guid>https://dev.to/fazal_mansuri_/graphql-vs-rest-which-one-should-you-really-use-2na0</guid>
      <description>&lt;p&gt;For years, REST APIs have been the standard.&lt;/p&gt;

&lt;p&gt;Then GraphQL came in with promises like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Fetch exactly what you need”&lt;/li&gt;
&lt;li&gt;“Reduce API calls”&lt;/li&gt;
&lt;li&gt;“More flexible APIs”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here’s the reality:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GraphQL is not a replacement for REST.&lt;br&gt;
It’s a different trade-off.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s break it down — with &lt;strong&gt;real code you can run&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 What is REST?
&lt;/h1&gt;

&lt;p&gt;REST is a resource-based API design.&lt;/p&gt;

&lt;p&gt;You expose endpoints 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;GET /users/1
GET /users/1/orders
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each endpoint returns &lt;strong&gt;fixed structure data&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚙️ REST API — Fully Working Go Example
&lt;/h1&gt;

&lt;p&gt;👉 Save as &lt;code&gt;rest.go&lt;/code&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="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;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&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;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"email"`&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;getUserHandler&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;user&lt;/span&gt; &lt;span class="o"&gt;:=&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;ID&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;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"john@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&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;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;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;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/users/1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getUserHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"REST server running on http://localhost:8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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;ListenAndServe&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="no"&gt;nil&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;
  
  
  ▶️ Run it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run rest.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📡 Call API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/users/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📦 Response
&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@example.com"&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;h1&gt;
  
  
  🧠 What is GraphQL?
&lt;/h1&gt;

&lt;p&gt;GraphQL is a &lt;strong&gt;query-based API system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of multiple endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You use a &lt;strong&gt;single endpoint&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client decides what data it needs&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ⚙️ GraphQL API — Fully Working Go Example
&lt;/h1&gt;

&lt;p&gt;👉 Save as &lt;code&gt;graphql.go&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install dependency
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go mod init graphql-example
go get github.com/graphql-go/graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Full working code
&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;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/graphql-go/graphql"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&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;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"email"`&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;userData&lt;/span&gt; &lt;span class="o"&gt;=&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;ID&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;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"john@example.com"&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// Define User type&lt;/span&gt;
    &lt;span class="n"&gt;userType&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"User"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;graphql&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;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;graphql&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;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="c"&gt;// Root query&lt;/span&gt;
    &lt;span class="n"&gt;rootQuery&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="o"&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;p&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResolveParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;interface&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;userData&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="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;schema&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;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SchemaConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rootQuery&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;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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// GraphQL handler&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;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/graphql"&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;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="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;params&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;Query&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"query"`&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;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&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;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&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;params&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;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;"invalid request body"&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="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;RequestString&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;,&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;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&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="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GraphQL server running on http://localhost:8080/graphql"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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;ListenAndServe&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="no"&gt;nil&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;
  
  
  ▶️ Run it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run graphql.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📡 Call API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/graphql &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"query": "{ user { name email } }"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📦 Response
&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;"data"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@example.com"&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;span class="p"&gt;}&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;h1&gt;
  
  
  REST vs GraphQL — Visual Understanding
&lt;/h1&gt;

&lt;h2&gt;
  
  
  REST Flow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
  |
  |---- GET /users/1 ----------&amp;gt; Server
  |---- GET /users/1/orders ---&amp;gt; Server
  |---- GET /orders/101/items -&amp;gt; Server

Multiple requests ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  GraphQL Flow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;Client&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;|----&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/graphql&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;---------&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Server&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;query&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;span class="n"&gt;user&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;span class="n"&gt;orders&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;span class="n"&gt;items&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;span class="p"&gt;}&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;span class="err"&gt;Single&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  ⚠️ The Real Problem GraphQL Solves
&lt;/h1&gt;

&lt;h2&gt;
  
  
  REST Problem → Over-fetching
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;&lt;span class="k"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;phone&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if you need only &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  REST Problem → Under-fetching
&lt;/h2&gt;

&lt;p&gt;You need multiple calls to build UI.&lt;/p&gt;




&lt;h2&gt;
  
  
  GraphQL Solution
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&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;span class="n"&gt;user&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;span class="n"&gt;name&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;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;👉 Exact data only.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚖️ REST vs GraphQL — Honest Comparison
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🧩 REST
&lt;/h2&gt;

&lt;p&gt;✅ Simple&lt;br&gt;
✅ Easy caching&lt;br&gt;
✅ Easy debugging&lt;br&gt;
❌ Multiple calls&lt;br&gt;
❌ Over-fetching&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 GraphQL
&lt;/h2&gt;

&lt;p&gt;✅ Flexible&lt;br&gt;
✅ Single request&lt;br&gt;
❌ Complex&lt;br&gt;
❌ Hard caching&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: REST uses native HTTP caching (like CDNs and browser headers), while GraphQL requires complex, custom caching strategies because queries are typically sent via POST.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;❌ Query abuse risk&lt;/p&gt;


&lt;h1&gt;
  
  
  ⚠️ Common Mistakes
&lt;/h1&gt;
&lt;h3&gt;
  
  
  ❌ “GraphQL is always better”
&lt;/h3&gt;

&lt;p&gt;No.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Using GraphQL for simple CRUD
&lt;/h3&gt;

&lt;p&gt;Overkill.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Ignoring query complexity
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users → posts → comments → replies → ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💥 Performance issue&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 When to Use What
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ✅ Use REST when:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Simple APIs&lt;/li&gt;
&lt;li&gt;CRUD operations&lt;/li&gt;
&lt;li&gt;Strong caching needed&lt;/li&gt;
&lt;li&gt;Easy debugging required&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Use GraphQL when:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Complex frontend&lt;/li&gt;
&lt;li&gt;Aggregated data&lt;/li&gt;
&lt;li&gt;Multiple services&lt;/li&gt;
&lt;li&gt;Frequent UI changes&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🔗 Real-World Architecture
&lt;/h1&gt;

&lt;p&gt;Many companies use the GraphQL Gateway (or BFF) pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend → GraphQL Gateway → REST microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 GraphQL acts as an aggregation layer, allowing you to combine multiple REST responses into one, without refactoring the legacy backend.&lt;/p&gt;




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

&lt;p&gt;GraphQL vs REST is not a battle.&lt;/p&gt;

&lt;p&gt;It’s a &lt;strong&gt;design decision&lt;/strong&gt;.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;REST = simple and predictable&lt;/li&gt;
&lt;li&gt;GraphQL = flexible but complex&lt;/li&gt;
&lt;li&gt;Both solve real problems&lt;/li&gt;
&lt;li&gt;Choose based on use-case&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🚀 Final Tip
&lt;/h1&gt;

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

&lt;p&gt;👉 Is simple → use REST&lt;br&gt;
👉 Needs flexibility → use GraphQL&lt;/p&gt;

</description>
      <category>backend</category>
      <category>programming</category>
      <category>api</category>
      <category>learning</category>
    </item>
    <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://dev.to/fazal_mansuri_/race-conditions-in-apis-the-bug-you-cant-see-5c0h</link>
      <guid>https://dev.to/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://dev.to/fazal_mansuri_/feature-flags-the-secret-behind-safe-deployments-4ine</link>
      <guid>https://dev.to/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://dev.to/fazal_mansuri_/idempotency-in-apis-why-your-retry-logic-can-break-everything-and-how-to-fix-it-345k</link>
      <guid>https://dev.to/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://dev.to/fazal_mansuri_/uuidv4-vs-uuidv7-in-postgresql-2m0l</link>
      <guid>https://dev.to/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://dev.to/fazal_mansuri_/javascript-precision-loss-with-large-numbers-the-silent-bug-that-breaks-applications-without-4lhg</link>
      <guid>https://dev.to/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://dev.to/fazal_mansuri_/memory-leaks-in-javascript-react-the-hidden-enemy-74p</link>
      <guid>https://dev.to/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://dev.to/fazal_mansuri_/controlled-vs-uncontrolled-components-in-react-a-deep-dive-1hhb</link>
      <guid>https://dev.to/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>
  </channel>
</rss>
