<?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: Frozen Blood</title>
    <description>The latest articles on DEV Community by Frozen Blood (@frozenblood).</description>
    <link>https://dev.to/frozenblood</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3747208%2F9f70bc1d-df22-4bbe-8f34-2ccca9d14638.jpg</url>
      <title>DEV Community: Frozen Blood</title>
      <link>https://dev.to/frozenblood</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/frozenblood"/>
    <language>en</language>
    <item>
      <title>The API Was “Fast” — Until One User Made It Slow for Everyone</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Tue, 24 Mar 2026 16:37:08 +0000</pubDate>
      <link>https://dev.to/frozenblood/the-api-was-fast-until-one-user-made-it-slow-for-everyone-5c6p</link>
      <guid>https://dev.to/frozenblood/the-api-was-fast-until-one-user-made-it-slow-for-everyone-5c6p</guid>
      <description>&lt;p&gt;We had an API that was consistently fast.&lt;br&gt;
~80ms average response time. No complaints.&lt;/p&gt;

&lt;p&gt;Then one day, everything slowed down.&lt;br&gt;
Not crashed. Not broken. Just… slow.&lt;/p&gt;

&lt;p&gt;And the weird part?&lt;/p&gt;

&lt;p&gt;It was caused by &lt;strong&gt;one user&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Symptom: Latency Gradually Creeping Up
&lt;/h2&gt;

&lt;p&gt;At first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;p95 latency increased slightly&lt;/li&gt;
&lt;li&gt;CPU was fine&lt;/li&gt;
&lt;li&gt;Memory was stable&lt;/li&gt;
&lt;li&gt;No obvious errors&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Requests started taking 500ms+&lt;/li&gt;
&lt;li&gt;Some hit 2–3 seconds&lt;/li&gt;
&lt;li&gt;But only during certain times&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It wasn’t global traffic.&lt;br&gt;
It was something more subtle.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Clue: One Endpoint, One Pattern
&lt;/h2&gt;

&lt;p&gt;After digging into logs, we noticed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Almost all slow requests hit the same endpoint&lt;/li&gt;
&lt;li&gt;Same query pattern&lt;/li&gt;
&lt;li&gt;Same user ID appearing frequently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That user had… a lot of data.&lt;/p&gt;

&lt;p&gt;Way more than anyone else.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Root Cause: “Works Fine” Query That Didn’t Scale
&lt;/h2&gt;

&lt;p&gt;Here’s the query (simplified):&lt;/p&gt;

&lt;p&gt;SQL:&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;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;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&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;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks harmless, right?&lt;/p&gt;

&lt;p&gt;Except:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No pagination&lt;/li&gt;
&lt;li&gt;No limit&lt;/li&gt;
&lt;li&gt;That user had &lt;strong&gt;120,000+ rows&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pulled all rows&lt;/li&gt;
&lt;li&gt;Sorted them&lt;/li&gt;
&lt;li&gt;Serialized them into JSON&lt;/li&gt;
&lt;li&gt;Sent them over the network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For one user.&lt;/p&gt;

&lt;p&gt;Now imagine multiple requests hitting that at once.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why It Slowed Down &lt;em&gt;Everyone&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Node.js is non-blocking… but not magic.&lt;/p&gt;

&lt;p&gt;What actually happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Huge DB query time increased&lt;/li&gt;
&lt;li&gt;Large JSON serialization blocked the event loop&lt;/li&gt;
&lt;li&gt;Response size increased network time&lt;/li&gt;
&lt;li&gt;Other requests waited behind it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One “heavy” request created backpressure for everything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix (That Took 10 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Add Pagination (Always)
&lt;/h3&gt;

&lt;p&gt;SQL:&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;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;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&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;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or even better: cursor-based pagination.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Add Proper Index
&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;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_orders_user_created&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This alone drastically reduced query time.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Reduce Payload Size
&lt;/h3&gt;

&lt;p&gt;Instead of &lt;code&gt;SELECT *&lt;/code&gt;:&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;SELECT&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;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&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;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Less data → faster everything.&lt;/p&gt;




&lt;h3&gt;
  
  
  4️⃣ Optional: Protect the API
&lt;/h3&gt;

&lt;p&gt;We added a soft guard:&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Limit too high&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more accidental “give me everything.”&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lesson That Stuck With Me
&lt;/h2&gt;

&lt;p&gt;The API wasn’t fast.&lt;/p&gt;

&lt;p&gt;It was fast &lt;strong&gt;for the average case&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The moment one user had “edge-case data,” the system showed its real behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Dangerous Assumption
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“It works fine with my test data.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Test data is small. Clean. Predictable.&lt;/p&gt;

&lt;p&gt;Production data is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;messy&lt;/li&gt;
&lt;li&gt;uneven&lt;/li&gt;
&lt;li&gt;sometimes extreme&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Systems fail at the edges — not the average.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;Your backend performance isn’t defined by your average user. It’s defined by your &lt;strong&gt;heaviest one&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If one user can slow everyone else down, it’s not a user problem — it’s a system design problem.&lt;/p&gt;

&lt;p&gt;What’s the most unexpected “edge case” in your data that caused real performance issues?&lt;/p&gt;

</description>
      <category>backend</category>
      <category>webdev</category>
      <category>database</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Thu, 05 Mar 2026 04:28:56 +0000</pubDate>
      <link>https://dev.to/frozenblood/-487g</link>
      <guid>https://dev.to/frozenblood/-487g</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/frozenblood" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F3747208%2F9f70bc1d-df22-4bbe-8f34-2ccca9d14638.jpg" alt="frozenblood"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/frozenblood/our-aws-bill-spiked-3x-overnight-it-wasnt-traffic-it-was-one-missing-limit-1lje" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Our AWS Bill Spiked 3x Overnight — It Wasn’t Traffic, It Was One Missing Limit&lt;/h2&gt;
      &lt;h3&gt;Frozen Blood ・ Mar 3&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cloud&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#backend&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>devops</category>
      <category>aws</category>
      <category>cloud</category>
      <category>backend</category>
    </item>
    <item>
      <title>Our AWS Bill Spiked 3x Overnight — It Wasn’t Traffic, It Was One Missing Limit</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Tue, 03 Mar 2026 16:07:08 +0000</pubDate>
      <link>https://dev.to/frozenblood/our-aws-bill-spiked-3x-overnight-it-wasnt-traffic-it-was-one-missing-limit-1lje</link>
      <guid>https://dev.to/frozenblood/our-aws-bill-spiked-3x-overnight-it-wasnt-traffic-it-was-one-missing-limit-1lje</guid>
      <description>&lt;p&gt;One morning I opened AWS Billing and saw something that makes every DevOps engineer uncomfortable: a sharp vertical spike.&lt;br&gt;
No marketing campaign.&lt;br&gt;
No traffic surge.&lt;br&gt;
No new feature launch.&lt;/p&gt;

&lt;p&gt;Our AWS cost had tripled in less than 24 hours.&lt;/p&gt;

&lt;p&gt;Here’s what happened — and the guardrail I’ll never skip again.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Setup: “It’s Just a Background Job”
&lt;/h2&gt;

&lt;p&gt;We had a background worker running on EC2. Its job was simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull messages from SQS&lt;/li&gt;
&lt;li&gt;Process media files&lt;/li&gt;
&lt;li&gt;Upload results to S3&lt;/li&gt;
&lt;li&gt;Delete the message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Standard stuff.&lt;/p&gt;

&lt;p&gt;We had recently increased concurrency to “speed things up.”&lt;/p&gt;

&lt;p&gt;Node.js worker (simplified):&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="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sqs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;receiveMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;MaxNumberOfMessages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;processJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&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;It worked great in testing.&lt;/p&gt;

&lt;p&gt;Until production.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Silent Problem: No Concurrency Ceiling
&lt;/h2&gt;

&lt;p&gt;Under certain failure conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;processJob&lt;/code&gt; retried internally&lt;/li&gt;
&lt;li&gt;Jobs took longer&lt;/li&gt;
&lt;li&gt;Messages weren’t deleted fast enough&lt;/li&gt;
&lt;li&gt;More instances scaled up&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;An Auto Scaling Group&lt;/li&gt;
&lt;li&gt;CPU-based scaling policy&lt;/li&gt;
&lt;li&gt;No max instance cap set properly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS did exactly what it was told to do:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“CPU high? Add instances.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It added them.&lt;/p&gt;

&lt;p&gt;And kept adding them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Cascade Effect
&lt;/h2&gt;

&lt;p&gt;Here’s how it spiraled:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Jobs slow down → CPU increases&lt;/li&gt;
&lt;li&gt;ASG launches more EC2 instances&lt;/li&gt;
&lt;li&gt;More instances pull more SQS messages&lt;/li&gt;
&lt;li&gt;Downstream dependency throttles&lt;/li&gt;
&lt;li&gt;Retries increase&lt;/li&gt;
&lt;li&gt;CPU spikes more&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It wasn’t traffic.&lt;/p&gt;

&lt;p&gt;It was &lt;strong&gt;self-amplifying concurrency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By the time we noticed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EC2 count had doubled&lt;/li&gt;
&lt;li&gt;S3 PUT requests spiked&lt;/li&gt;
&lt;li&gt;Data transfer increased&lt;/li&gt;
&lt;li&gt;NAT gateway costs quietly ballooned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS didn’t fail.&lt;br&gt;
Our assumptions did.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Fix (What I Should Have Done First)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1️⃣ Hard Cap the Auto Scaling Group
&lt;/h3&gt;

&lt;p&gt;Always define a maximum instance count.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_autoscaling_group"&lt;/span&gt; &lt;span class="s2"&gt;"workers"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;max_size&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="nx"&gt;min_size&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;desired_capacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No infinite scaling. Ever.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Limit Application-Level Concurrency
&lt;/h3&gt;

&lt;p&gt;Instead of unlimited &lt;code&gt;Promise.all&lt;/code&gt;, I switched to controlled parallelism:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;pLimit&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;p-limit&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;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;limit&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;processJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&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;Infrastructure scaling + unlimited app concurrency = chaos.&lt;/p&gt;

&lt;p&gt;Pick one.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Add Circuit Breakers
&lt;/h3&gt;

&lt;p&gt;If downstream dependency fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop pulling new messages&lt;/li&gt;
&lt;li&gt;Pause briefly&lt;/li&gt;
&lt;li&gt;Fail fast instead of retrying blindly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backpressure is not optional in distributed systems.&lt;/p&gt;




&lt;h3&gt;
  
  
  4️⃣ Billing Alerts (The Obvious One)
&lt;/h3&gt;

&lt;p&gt;I added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Budget alerts at 50%, 75%, 90%&lt;/li&gt;
&lt;li&gt;Cost anomaly detection&lt;/li&gt;
&lt;li&gt;Slack notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Embarrassingly, we had none of that before.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lesson Most Teams Learn Once
&lt;/h2&gt;

&lt;p&gt;Cloud doesn’t break loudly.&lt;/p&gt;

&lt;p&gt;It scales quietly.&lt;/p&gt;

&lt;p&gt;And scaling is expensive when the trigger condition is flawed.&lt;/p&gt;

&lt;p&gt;AWS is incredibly good at doing what you configure.&lt;br&gt;
It will happily automate your mistakes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;Our AWS bill didn’t spike because of growth.&lt;br&gt;
It spiked because we removed a limit and trusted scaling without boundaries.&lt;/p&gt;

&lt;p&gt;In cloud systems, &lt;strong&gt;unbounded concurrency is a liability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Have you ever had an AWS (or cloud) cost surprise? What guardrail did you add afterward?&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>cloud</category>
      <category>backend</category>
    </item>
    <item>
      <title>The Codebase Isn’t Slow — Your Decisions Are Catching Up</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Fri, 27 Feb 2026 16:05:10 +0000</pubDate>
      <link>https://dev.to/frozenblood/the-codebase-isnt-slow-your-decisions-are-catching-up-4e9c</link>
      <guid>https://dev.to/frozenblood/the-codebase-isnt-slow-your-decisions-are-catching-up-4e9c</guid>
      <description>&lt;p&gt;At some point in every project, someone says it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The codebase is getting slow.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Slow builds. Slow feature delivery. Slow onboarding.&lt;br&gt;
But most of the time, the codebase isn’t the real problem.&lt;/p&gt;

&lt;p&gt;It’s accumulated decisions finally demanding payment.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Illusion of “It Works, Ship It”
&lt;/h2&gt;

&lt;p&gt;Early in a project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You skip validation because “we trust the input.”&lt;/li&gt;
&lt;li&gt;You duplicate logic because “we’ll refactor later.”&lt;/li&gt;
&lt;li&gt;You avoid abstraction because “it’s just one screen.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And you’re right.&lt;/p&gt;

&lt;p&gt;Until it isn’t.&lt;/p&gt;

&lt;p&gt;Because code doesn’t forget shortcuts — it compounds them.&lt;/p&gt;


&lt;h2&gt;
  
  
  Technical Debt Isn’t About Messiness
&lt;/h2&gt;

&lt;p&gt;Messy code is obvious.&lt;/p&gt;

&lt;p&gt;The real debt hides in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implicit coupling&lt;/li&gt;
&lt;li&gt;Shared mutable state&lt;/li&gt;
&lt;li&gt;Business rules scattered across files&lt;/li&gt;
&lt;li&gt;“Temporary” conditionals that became permanent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It looks clean on the surface.&lt;br&gt;
But touching one file breaks three others.&lt;/p&gt;

&lt;p&gt;That’s not slowness. That’s fragility.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Telltale Signs Your Decisions Are Expiring
&lt;/h2&gt;

&lt;p&gt;You’ll notice patterns like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding one feature requires editing 6+ files&lt;/li&gt;
&lt;li&gt;Tests fail for unrelated modules&lt;/li&gt;
&lt;li&gt;Refactors feel dangerous&lt;/li&gt;
&lt;li&gt;Junior devs avoid certain folders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That folder everyone avoids?&lt;br&gt;
That’s architectural interest accumulating.&lt;/p&gt;


&lt;h2&gt;
  
  
  A Small Example That Grows Big
&lt;/h2&gt;

&lt;p&gt;Early version:&lt;/p&gt;

&lt;p&gt;JavaScript:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculatePrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPremium&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&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;Six months later:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculatePrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPremium&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSuspended&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;digital&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.75&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coupon&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;excludeCoupons&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&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;Another quarter passes…&lt;br&gt;
Now tax logic is in there. Regional logic. Experimental pricing flags.&lt;/p&gt;

&lt;p&gt;The function isn’t bad.&lt;/p&gt;

&lt;p&gt;But the &lt;strong&gt;decision to centralize business logic without boundaries&lt;/strong&gt; eventually collapses under complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Cost Isn’t Performance
&lt;/h2&gt;

&lt;p&gt;It’s hesitation.&lt;/p&gt;

&lt;p&gt;When engineers hesitate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Velocity drops&lt;/li&gt;
&lt;li&gt;Bugs increase&lt;/li&gt;
&lt;li&gt;Refactors are avoided&lt;/li&gt;
&lt;li&gt;Workarounds multiply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s when teams say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The codebase is heavy.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s not heavy.&lt;br&gt;
It’s layered.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix Isn’t “Rewrite It”
&lt;/h2&gt;

&lt;p&gt;Rewrites are emotional reactions.&lt;/p&gt;

&lt;p&gt;Better moves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolate unstable logic behind clear interfaces&lt;/li&gt;
&lt;li&gt;Extract business rules into composable units&lt;/li&gt;
&lt;li&gt;Add guardrail tests before refactoring&lt;/li&gt;
&lt;li&gt;Reduce hidden dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture improves incrementally — not dramatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Always Happens
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Speed of shipping
eventually conflicts with&lt;/li&gt;
&lt;li&gt;Speed of change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first phase rewards momentum.&lt;br&gt;
The second phase demands structure.&lt;/p&gt;

&lt;p&gt;And most teams don’t consciously transition between the two.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;When a codebase feels slow, it’s usually not because it’s big. It’s because earlier decisions are no longer aligned with current complexity.&lt;/p&gt;

&lt;p&gt;The question isn’t:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do we make this faster?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which past decision is no longer serving us?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What’s one architectural decision you made early in a project that you’d redesign today?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwareengineering</category>
      <category>backend</category>
      <category>architecture</category>
    </item>
    <item>
      <title>I Almost Ran rm -rf / on Production — And It Changed How I Deploy Forever</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Wed, 11 Feb 2026 09:33:50 +0000</pubDate>
      <link>https://dev.to/frozenblood/i-almost-ran-rm-rf-on-production-and-it-changed-how-i-deploy-forever-njk</link>
      <guid>https://dev.to/frozenblood/i-almost-ran-rm-rf-on-production-and-it-changed-how-i-deploy-forever-njk</guid>
      <description>&lt;p&gt;There’s a specific kind of silence that happens when your terminal cursor blinks… and you realize you’re connected to production.&lt;/p&gt;

&lt;p&gt;I didn’t actually wipe the server.&lt;br&gt;
But I was one Enter key away.&lt;/p&gt;

&lt;p&gt;Here’s what happened — and the small habits I changed that probably saved me (and might save you too).&lt;/p&gt;


&lt;h2&gt;
  
  
  The Setup: A “Quick Fix” at 1:17 AM
&lt;/h2&gt;

&lt;p&gt;Classic story:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minor config bug&lt;/li&gt;
&lt;li&gt;“It’ll take 2 minutes”&lt;/li&gt;
&lt;li&gt;SSH into the server&lt;/li&gt;
&lt;li&gt;Fix a path&lt;/li&gt;
&lt;li&gt;Restart the service&lt;/li&gt;
&lt;li&gt;Go to sleep&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Except I had two terminals open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One connected to staging&lt;/li&gt;
&lt;li&gt;One connected to production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They looked almost identical.&lt;/p&gt;

&lt;p&gt;Same prompt.&lt;br&gt;
Same theme.&lt;br&gt;
Same everything.&lt;/p&gt;

&lt;p&gt;I typed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then I noticed the hostname.&lt;/p&gt;

&lt;p&gt;Production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Was Worse Than It Sounds
&lt;/h2&gt;

&lt;p&gt;That project didn’t just store build artifacts in &lt;code&gt;dist/&lt;/code&gt;.&lt;br&gt;
It also had runtime-generated files.&lt;/p&gt;

&lt;p&gt;And since I was inside the app directory, not root, &lt;code&gt;rm -rf dist&lt;/code&gt; wouldn’t nuke the whole machine — but it would absolutely break live traffic.&lt;/p&gt;

&lt;p&gt;It would have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deleted compiled output&lt;/li&gt;
&lt;li&gt;Broken running processes on restart&lt;/li&gt;
&lt;li&gt;Forced an emergency redeploy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All because I didn’t slow down for 3 seconds.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Real Problem Wasn’t the Command
&lt;/h2&gt;

&lt;p&gt;It was this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production access was too easy&lt;/li&gt;
&lt;li&gt;The environment looked too similar&lt;/li&gt;
&lt;li&gt;Destructive commands had no friction&lt;/li&gt;
&lt;li&gt;There were no guardrails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It wasn’t a technical issue.&lt;br&gt;
It was a design flaw in &lt;em&gt;my workflow&lt;/em&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  What I Changed Immediately
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1️⃣ Aggressively Different Shell Prompts
&lt;/h3&gt;

&lt;p&gt;Production is now &lt;strong&gt;bright red&lt;/strong&gt; in my terminal.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PS1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[1;31m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;[PROD] &lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="se"&gt;\h&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\w&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[0m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I SSH into prod, it screams at me.&lt;/p&gt;

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




&lt;h3&gt;
  
  
  2️⃣ Alias Protection for Dangerous Commands
&lt;/h3&gt;

&lt;p&gt;I added interactive flags to destructive commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias rm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'rm -i'&lt;/span&gt;
&lt;span class="nb"&gt;alias mv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'mv -i'&lt;/span&gt;
&lt;span class="nb"&gt;alias cp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'cp -i'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I must confirm before deleting.&lt;/p&gt;

&lt;p&gt;Is it slightly annoying?&lt;br&gt;
Yes.&lt;br&gt;
Is it better than downtime? Also yes.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Production Is Now Mostly Immutable
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;SSH → change files → restart&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Build locally or in CI&lt;/li&gt;
&lt;li&gt;Deploy artifact&lt;/li&gt;
&lt;li&gt;Restart via process manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No editing files on prod. Ever.&lt;/p&gt;

&lt;p&gt;If I need to “fix something quickly,” I fix it in code and redeploy.&lt;/p&gt;




&lt;h3&gt;
  
  
  4️⃣ Reduced Direct SSH Access
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;Logs are centralized&lt;/li&gt;
&lt;li&gt;Restarts are script-driven&lt;/li&gt;
&lt;li&gt;Environment variables are managed via config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I SSH, something is already very wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Psychological Lesson
&lt;/h2&gt;

&lt;p&gt;Most production disasters don’t come from incompetence.&lt;/p&gt;

&lt;p&gt;They come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fatigue&lt;/li&gt;
&lt;li&gt;Familiarity&lt;/li&gt;
&lt;li&gt;Repetition&lt;/li&gt;
&lt;li&gt;“Just this once”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most dangerous command isn’t &lt;code&gt;rm -rf&lt;/code&gt;.&lt;br&gt;
It’s &lt;strong&gt;confidence&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Quiet Truth About DevOps
&lt;/h2&gt;

&lt;p&gt;We talk about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;li&gt;Blue-green deploys&lt;/li&gt;
&lt;li&gt;Zero-downtime rollouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the simplest protection is often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make dangerous actions &lt;em&gt;slightly harder&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Friction is underrated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;I didn’t delete production.&lt;br&gt;
But that near-miss changed how I treat access, commands, and environments forever.&lt;/p&gt;

&lt;p&gt;The scariest production story isn’t the one where everything breaks.&lt;br&gt;
It’s the one where you realize how easily it could have.&lt;/p&gt;

&lt;p&gt;What’s the closest you’ve come to breaking production — and what guardrail did you add afterward?&lt;/p&gt;

</description>
      <category>devops</category>
      <category>webdev</category>
      <category>backend</category>
      <category>linux</category>
    </item>
    <item>
      <title>The Day I Learned Node.js “Timeouts” Don’t Mean What I Thought They Meant</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Tue, 10 Feb 2026 07:09:48 +0000</pubDate>
      <link>https://dev.to/frozenblood/the-day-i-learned-nodejs-timeouts-dont-mean-what-i-thought-they-meant-558</link>
      <guid>https://dev.to/frozenblood/the-day-i-learned-nodejs-timeouts-dont-mean-what-i-thought-they-meant-558</guid>
      <description>&lt;p&gt;I used to think timeouts were simple: set a timeout, request fails after X seconds, done. Then I shipped a Node.js service that &lt;em&gt;still&lt;/em&gt; got stuck under load even though “everything had a timeout.”&lt;/p&gt;

&lt;p&gt;Turns out Node has &lt;strong&gt;multiple layers of timeouts&lt;/strong&gt;, and if you set the wrong one (or only one), you can still end up with requests that hang, sockets that live forever, and a server that slowly stops accepting traffic.&lt;/p&gt;

&lt;p&gt;Here’s the story — and how I fixed it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Symptom: “Random” Hangs Under Load
&lt;/h2&gt;

&lt;p&gt;It started as a vague report:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“The API sometimes takes forever.”&lt;/li&gt;
&lt;li&gt;“It’s not crashing, it just… stops responding.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CPU was fine. Memory was fine. No obvious errors.&lt;/p&gt;

&lt;p&gt;But the number of open connections kept climbing. And once it crossed a certain point, even healthy endpoints felt slow.&lt;/p&gt;

&lt;p&gt;Classic “works until it doesn’t.”&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mistake: I Only Set the &lt;em&gt;Wrong&lt;/em&gt; Timeout
&lt;/h2&gt;

&lt;p&gt;I had code like this:&lt;/p&gt;

&lt;p&gt;JavaScript (Node.js):&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&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;http&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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="c1"&gt;// ...business logic&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;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ok&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="c1"&gt;// I thought this solved it:&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I believed &lt;code&gt;server.setTimeout()&lt;/code&gt; meant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Kill any request that takes longer than 10 seconds.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nope.&lt;/p&gt;

&lt;p&gt;That timeout is mainly about &lt;strong&gt;idle socket activity&lt;/strong&gt; (and behavior differs across Node versions and request patterns). If the connection is still “active” in certain ways, you can still end up with long-lived sockets.&lt;/p&gt;

&lt;p&gt;And even worse: my &lt;strong&gt;outbound calls&lt;/strong&gt; (to other services) didn’t have proper timeouts either.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Root Cause: Outbound Requests Without Timeouts
&lt;/h2&gt;

&lt;p&gt;We had a dependency call like:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;https://some-service/api/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// sometimes this never returned under network weirdness&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the real world:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS can hang&lt;/li&gt;
&lt;li&gt;TLS negotiation can stall&lt;/li&gt;
&lt;li&gt;upstream can accept the connection but never respond&lt;/li&gt;
&lt;li&gt;proxies can behave badly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don’t set timeouts on outbound calls, your handler can hang while the client connection stays open… and then your server slowly fills up with stuck requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix: Put Timeouts at the Right Layers
&lt;/h2&gt;

&lt;p&gt;I fixed it with a &lt;strong&gt;three-layer timeout strategy&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Request-level timeout (application logic)
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;AbortController&lt;/code&gt; so the &lt;em&gt;operation&lt;/em&gt; stops.&lt;/p&gt;

&lt;p&gt;JavaScript (Node.js 18+):&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchWithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5000&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;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="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;setTimeout&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="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&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;p&gt;Now my outbound call can’t hang forever.&lt;/p&gt;




&lt;h3&gt;
  
  
  2) Server headers timeout (protect against slowloris / slow clients)
&lt;/h3&gt;

&lt;p&gt;These are more reliable for “client is too slow” cases.&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;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headersTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// must be &amp;gt; requestTimeout in Node&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps when clients keep connections open and drip headers/body slowly.&lt;/p&gt;




&lt;h3&gt;
  
  
  3) Hard kill per request (safety net)
&lt;/h3&gt;

&lt;p&gt;Even if something slips through, I wanted a final cutoff.&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;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;request&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;408&lt;/span&gt;&lt;span class="p"&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;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Request timeout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&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;This makes the behavior explicit and visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: The One Change That Made Debugging Obvious
&lt;/h2&gt;

&lt;p&gt;I added logging on aborted requests and tracked active handles:&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warning&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;w&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&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;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&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;Active handles:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_getActiveHandles&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;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Yes, &lt;code&gt;_getActiveHandles()&lt;/code&gt; is not “clean,” but for debugging it quickly tells you if your server is accumulating stuck sockets/timers.)&lt;/p&gt;

&lt;p&gt;Once I saw handles steadily increasing, it confirmed the leak was &lt;em&gt;connections waiting on something&lt;/em&gt; — not memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Node timeouts aren’t one thing. They’re:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Socket / HTTP server protection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application request timeboxing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outbound client timeout enforcement&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only set one, you’ll still get weird hangs in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;If your Node service “hangs” under load, assume it’s not mysterious. It’s usually &lt;strong&gt;requests waiting forever&lt;/strong&gt; because timeouts weren’t enforced at the right layer.&lt;/p&gt;

&lt;p&gt;Have you ever shipped a service that didn’t crash — it just slowly stopped responding? What did it end up being?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>backend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your Web App’s Data Can Disappear — Even If the User Never Cleared It</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Mon, 09 Feb 2026 13:50:07 +0000</pubDate>
      <link>https://dev.to/frozenblood/your-web-apps-data-can-disappear-even-if-the-user-never-cleared-it-3ffm</link>
      <guid>https://dev.to/frozenblood/your-web-apps-data-can-disappear-even-if-the-user-never-cleared-it-3ffm</guid>
      <description>&lt;p&gt;Here’s something many developers don’t realize until it hurts: &lt;strong&gt;the browser is allowed to delete your app’s stored data at any time&lt;/strong&gt; — even if the user never clicked “Clear cache.”&lt;/p&gt;

&lt;p&gt;LocalStorage. IndexedDB. Cache Storage.&lt;br&gt;
None of them are guaranteed.&lt;/p&gt;

&lt;p&gt;Let’s talk about why this happens, when it happens, and how to design around it.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Browser Does Not Promise to Keep Your Data
&lt;/h2&gt;

&lt;p&gt;Web storage APIs feel persistent, but they’re actually &lt;strong&gt;best-effort&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Browsers enforce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storage &lt;strong&gt;quotas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eviction policies&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Priority rules based on usage patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When space is needed, something has to go — and it might be &lt;em&gt;your app&lt;/em&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Silent Killer: Storage Eviction
&lt;/h2&gt;

&lt;p&gt;Browsers may delete site data when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disk space is low&lt;/li&gt;
&lt;li&gt;The site hasn’t been used recently&lt;/li&gt;
&lt;li&gt;The user is in private / low-storage mode&lt;/li&gt;
&lt;li&gt;The browser decides your data is “less important”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No warning.&lt;br&gt;
No exception.&lt;br&gt;
Just… gone.&lt;/p&gt;

&lt;p&gt;Your app reloads like it’s the first visit.&lt;/p&gt;


&lt;h2&gt;
  
  
  “But I’m Using IndexedDB, Not LocalStorage”
&lt;/h2&gt;

&lt;p&gt;Good instinct — but still not safe.&lt;/p&gt;

&lt;p&gt;Approximate priority (simplified):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User-engaged sites&lt;/strong&gt; (frequently visited, interacted with)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent storage&lt;/strong&gt; (explicitly requested)&lt;/li&gt;
&lt;li&gt;Everything else&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is rarely opened&lt;/li&gt;
&lt;li&gt;Lives behind a login&lt;/li&gt;
&lt;li&gt;Stores large blobs (videos, offline data)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…it’s a candidate for eviction.&lt;/p&gt;


&lt;h2&gt;
  
  
  The One API Most Devs Don’t Use (But Should)
&lt;/h2&gt;

&lt;p&gt;There’s a browser API called &lt;strong&gt;Persistent Storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;JavaScript:&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;persist&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;isPersisted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;persist&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;Persistent storage granted:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPersisted&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 granted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your data is &lt;em&gt;much&lt;/em&gt; less likely to be evicted&lt;/li&gt;
&lt;li&gt;The browser treats it like important app data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most apps never request this — and many devs don’t know it exists.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Browsers Decide Who Loses Data
&lt;/h2&gt;

&lt;p&gt;It’s not random. Browsers look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How often the user visits the site&lt;/li&gt;
&lt;li&gt;Whether the site is installed (PWA)&lt;/li&gt;
&lt;li&gt;User interaction signals&lt;/li&gt;
&lt;li&gt;Storage pressure on the device&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Offline-first apps survive longer&lt;/li&gt;
&lt;li&gt;Background tools disappear faster&lt;/li&gt;
&lt;li&gt;“Internal dashboards” get wiped unexpectedly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Failure Mode
&lt;/h2&gt;

&lt;p&gt;This usually shows up as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Some users got logged out”&lt;/li&gt;
&lt;li&gt;“Drafts randomly disappeared”&lt;/li&gt;
&lt;li&gt;“Offline mode stopped working”&lt;/li&gt;
&lt;li&gt;“It only happens on mobile”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it’s brutal to reproduce.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Defensive Strategies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treat browser storage as &lt;strong&gt;a cache, not a database&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sync critical data to a backend&lt;/li&gt;
&lt;li&gt;Request persistent storage for offline apps&lt;/li&gt;
&lt;li&gt;Detect missing state and recover gracefully&lt;/li&gt;
&lt;li&gt;Never assume stored data will exist tomorrow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If losing the data breaks your app, you designed it too optimistically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;Browser storage feels permanent — but it isn’t. Once you accept that, you start building web apps that are more resilient, predictable, and user-friendly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discussion question:&lt;/strong&gt;&lt;br&gt;
Have you ever debugged “random data loss” in a web app — and later realized the browser was the culprit?&lt;/p&gt;

&lt;p&gt;If you want tomorrow’s post to be &lt;strong&gt;AI&lt;/strong&gt;, &lt;strong&gt;frontend-specific&lt;/strong&gt;, or &lt;strong&gt;pure dev horror stories&lt;/strong&gt;, tell me and I’ll tune it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>browser</category>
    </item>
    <item>
      <title>Global AI Cooperation Moves Forward</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Sun, 08 Feb 2026 17:07:39 +0000</pubDate>
      <link>https://dev.to/frozenblood/global-ai-cooperation-moves-forward-3ona</link>
      <guid>https://dev.to/frozenblood/global-ai-cooperation-moves-forward-3ona</guid>
      <description>&lt;p&gt;While AI headlines often focus on new models, a quieter shift is happening in the background: &lt;strong&gt;countries are starting to cooperate on AI development instead of racing in isolation&lt;/strong&gt;. Over the past few weeks, multiple bilateral and regional agreements have signaled that AI is now a matter of international coordination — not just competition.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Actually Happening
&lt;/h2&gt;

&lt;p&gt;Governments are increasingly signing &lt;strong&gt;AI cooperation agreements&lt;/strong&gt; that focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Joint research and knowledge sharing&lt;/li&gt;
&lt;li&gt;Standards for responsible AI use&lt;/li&gt;
&lt;li&gt;Talent exchange and education&lt;/li&gt;
&lt;li&gt;Shared approaches to safety and ethics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These deals don’t announce new products. They set the rules for how AI will be built, shared, and governed over the next decade.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Is a Big Deal (Even If It Sounds Boring)
&lt;/h2&gt;

&lt;p&gt;AI has moved into the same category as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cybersecurity&lt;/li&gt;
&lt;li&gt;Energy infrastructure&lt;/li&gt;
&lt;li&gt;Telecommunications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once technologies reach that level, countries stop treating them as “just software” and start treating them as &lt;strong&gt;strategic infrastructure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s what these agreements represent: AI is no longer experimental — it’s geopolitical.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Competition to Coordination
&lt;/h2&gt;

&lt;p&gt;For years, the narrative was simple: &lt;em&gt;whoever builds the best AI wins&lt;/em&gt;.&lt;br&gt;
Reality is proving more complex.&lt;/p&gt;

&lt;p&gt;Uncoordinated AI development creates problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Incompatible regulations&lt;/li&gt;
&lt;li&gt;Conflicting safety standards&lt;/li&gt;
&lt;li&gt;Data transfer restrictions&lt;/li&gt;
&lt;li&gt;Fragmented research efforts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cooperation helps reduce friction — especially for cross-border companies and global platforms.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Means for Developers
&lt;/h2&gt;

&lt;p&gt;You may not feel this immediately, but the effects will surface in real workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standardized AI disclosures&lt;/strong&gt; across regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stricter requirements&lt;/strong&gt; for AI auditability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clearer boundaries&lt;/strong&gt; on data usage and model training&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More documentation&lt;/strong&gt; around AI-powered features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: less “move fast and ship AI,” more “prove how and why this AI behaves.”&lt;/p&gt;




&lt;h2&gt;
  
  
  A Subtle Shift in Responsibility
&lt;/h2&gt;

&lt;p&gt;As AI becomes internationally regulated, responsibility shifts downward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From governments → companies&lt;/li&gt;
&lt;li&gt;From companies → engineering teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers won’t just write AI-powered features — they’ll help define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What’s allowed&lt;/li&gt;
&lt;li&gt;What’s traceable&lt;/li&gt;
&lt;li&gt;What’s explainable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This mirrors what happened with privacy laws years ago, except AI reaches deeper into system behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Trend Will Continue
&lt;/h2&gt;

&lt;p&gt;Global AI cooperation is still early and imperfect, but it’s accelerating because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI impacts elections, security, and economies&lt;/li&gt;
&lt;li&gt;Failures cross borders instantly&lt;/li&gt;
&lt;li&gt;No single country fully controls the ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The direction is clear: &lt;strong&gt;shared rules before shared disasters&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;AI progress is no longer just about smarter models — it’s about &lt;strong&gt;how nations agree to use them&lt;/strong&gt;. As cooperation grows, developers will increasingly build AI features inside legal, ethical, and technical guardrails shaped far beyond their codebase.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>policy</category>
      <category>technews</category>
    </item>
    <item>
      <title>Every Production Bug Is a Story — Most Teams Just Don’t Read It</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Sat, 07 Feb 2026 11:01:34 +0000</pubDate>
      <link>https://dev.to/frozenblood/every-production-bug-is-a-story-most-teams-just-dont-read-it-4n1i</link>
      <guid>https://dev.to/frozenblood/every-production-bug-is-a-story-most-teams-just-dont-read-it-4n1i</guid>
      <description>&lt;p&gt;Production bugs aren’t random. They don’t “just happen.” Every incident is the final chapter of a story your system has been telling for weeks — sometimes months — before it breaks.&lt;/p&gt;

&lt;p&gt;Most teams only start listening when users start screaming.&lt;/p&gt;




&lt;h2&gt;
  
  
  Production Bugs Are Rarely About the Line That Crashed
&lt;/h2&gt;

&lt;p&gt;When something fails in prod, the instinct is to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which line caused this?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s almost never the right question.&lt;/p&gt;

&lt;p&gt;The better ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why was this state possible?&lt;/li&gt;
&lt;li&gt;Why wasn’t this path visible earlier?&lt;/li&gt;
&lt;li&gt;Why did the system &lt;em&gt;allow&lt;/em&gt; this combination of inputs?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The crashing line is just where the story ends — not where it starts.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Warning Signs Are Usually Boring
&lt;/h2&gt;

&lt;p&gt;Before most incidents, you’ll find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs that were “a bit noisy”&lt;/li&gt;
&lt;li&gt;Metrics that slowly drifted&lt;/li&gt;
&lt;li&gt;Edge cases dismissed as “unlikely”&lt;/li&gt;
&lt;li&gt;TODOs that said “handle later”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing dramatic. Nothing urgent.&lt;/p&gt;

&lt;p&gt;That’s why they’re ignored.&lt;/p&gt;

&lt;p&gt;Teams don’t miss red flags — they miss &lt;strong&gt;gray ones&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Debugging in Prod Is Really Archaeology
&lt;/h2&gt;

&lt;p&gt;Real-world debugging looks less like problem-solving and more like excavation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Old assumptions buried in comments&lt;/li&gt;
&lt;li&gt;Workarounds added under pressure&lt;/li&gt;
&lt;li&gt;Configs changed by someone who’s no longer on the team&lt;/li&gt;
&lt;li&gt;Code paths nobody remembers approving&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the time you’re debugging prod, you’re reconstructing &lt;em&gt;decisions&lt;/em&gt;, not just logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why “Works Fine in Staging” Is Meaningless
&lt;/h2&gt;

&lt;p&gt;Production is where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real traffic shapes appear&lt;/li&gt;
&lt;li&gt;Data is messy instead of ideal&lt;/li&gt;
&lt;li&gt;Latency, retries, and partial failures exist&lt;/li&gt;
&lt;li&gt;Users behave creatively&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Staging proves correctness.&lt;br&gt;
Production reveals &lt;strong&gt;behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your system only survives because traffic is polite, it’s already broken.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Teams That Debug Less Aren’t Smarter
&lt;/h2&gt;

&lt;p&gt;They just design differently.&lt;/p&gt;

&lt;p&gt;Patterns you’ll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear ownership of data flows&lt;/li&gt;
&lt;li&gt;Fewer “magic” side effects&lt;/li&gt;
&lt;li&gt;Boring, explicit state transitions&lt;/li&gt;
&lt;li&gt;Logs written for humans, not machines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They assume things will go wrong — and plan for reading the story later.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Habit That Changes Everything
&lt;/h2&gt;

&lt;p&gt;After every incident, ask one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What did the system know before users did?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is “nothing,” you didn’t have a bug — you had &lt;strong&gt;silence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Logs, metrics, and alerts aren’t for dashboards.&lt;br&gt;
They’re for &lt;em&gt;future you&lt;/em&gt;, under pressure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion / Key takeaway
&lt;/h2&gt;

&lt;p&gt;Production bugs aren’t surprises. They’re delayed conversations. The teams that suffer less aren’t faster at fixing crashes — they’re better at listening before the crash happens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discussion question:&lt;/strong&gt;&lt;br&gt;
What’s the earliest signal you’ve learned to trust before a production issue blows up?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwareengineering</category>
      <category>debugging</category>
      <category>backend</category>
    </item>
    <item>
      <title>Nvidia’s Next-Gen Gaming Chip Delay — What It Actually Means for Developers</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Fri, 06 Feb 2026 06:33:02 +0000</pubDate>
      <link>https://dev.to/frozenblood/nvidias-next-gen-gaming-chip-delay-what-it-actually-means-for-developers-1imc</link>
      <guid>https://dev.to/frozenblood/nvidias-next-gen-gaming-chip-delay-what-it-actually-means-for-developers-1imc</guid>
      <description>&lt;p&gt;If you were hoping for a clean GPU upgrade cycle in 2026… yeah, about that.&lt;/p&gt;

&lt;p&gt;:contentReference[oaicite:0]{index=0} is reportedly &lt;strong&gt;delaying its next-generation gaming GPU&lt;/strong&gt;, and the reason isn’t poor yields or bad architecture — it’s &lt;strong&gt;memory supply pressure caused by AI&lt;/strong&gt;. And that detail matters a lot more than it sounds.&lt;/p&gt;

&lt;p&gt;::contentReference[oaicite:1]{index=1}&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s being delayed (and why)
&lt;/h2&gt;

&lt;p&gt;According to recent industry reports, Nvidia’s upcoming &lt;strong&gt;consumer gaming GPU lineup&lt;/strong&gt; is slipping because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;High-bandwidth memory (HBM) and advanced GDDR supply is tight&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;AI accelerators and data-center GPUs are getting &lt;strong&gt;absolute priority&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Cloud providers are buying memory at volumes that &lt;strong&gt;gaming GPUs can’t compete with&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI GPUs are eating the memory market alive.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When Nvidia has to choose between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shipping a gaming GPU, or&lt;/li&gt;
&lt;li&gt;Shipping a data-center card that sells for &lt;strong&gt;10×–20× more&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…that’s not a hard decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why AI workloads are breaking the GPU supply chain
&lt;/h2&gt;

&lt;p&gt;Modern AI training and inference don’t just need compute — they need &lt;strong&gt;massive memory bandwidth&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HBM3 / HBM3E&lt;/li&gt;
&lt;li&gt;Ultra-fast GDDR variants&lt;/li&gt;
&lt;li&gt;Huge, stable memory stacks per card&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those same memory fabs also serve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gaming GPUs
&lt;/li&gt;
&lt;li&gt;Consoles
&lt;/li&gt;
&lt;li&gt;High-end laptops
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when hyperscalers place giant orders, &lt;strong&gt;everyone else waits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is no longer a “temporary shortage” problem — it’s a &lt;strong&gt;structural shift&lt;/strong&gt; in GPU economics.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for developers (not just gamers)
&lt;/h2&gt;

&lt;p&gt;This delay affects more than FPS counters.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎮 Game &amp;amp; graphics devs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Slower adoption of new GPU features&lt;/li&gt;
&lt;li&gt;Longer life cycles for existing architectures&lt;/li&gt;
&lt;li&gt;More pressure to optimize for &lt;em&gt;older cards&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧠 AI &amp;amp; ML engineers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reinforces Nvidia’s dominance in data centers&lt;/li&gt;
&lt;li&gt;Confirms that &lt;strong&gt;consumer GPUs are now second-class citizens&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Expect cloud GPU prices to stay high&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧱 Backend &amp;amp; infra devs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On-prem GPU builds get more expensive&lt;/li&gt;
&lt;li&gt;Planning capacity upgrades becomes harder&lt;/li&gt;
&lt;li&gt;Cloud dependency increases (whether you like it or not)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building anything GPU-heavy in 2026, &lt;strong&gt;availability is now a first-class architectural concern&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The bigger signal Nvidia is sending
&lt;/h2&gt;

&lt;p&gt;This delay quietly confirms something many devs already suspected:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nvidia is an AI infrastructure company first. Gaming is optional.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gaming GPUs still matter for branding and ecosystem lock-in — but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Revenue growth&lt;/li&gt;
&lt;li&gt;R&amp;amp;D focus&lt;/li&gt;
&lt;li&gt;Supply allocation
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…are all clearly pointed at AI.&lt;/p&gt;

&lt;p&gt;That doesn’t mean gaming is “dead.”&lt;br&gt;&lt;br&gt;
It means &lt;strong&gt;gaming hardware is no longer the priority customer&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should you care right now?
&lt;/h2&gt;

&lt;p&gt;If you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ship games&lt;/li&gt;
&lt;li&gt;Build GPU-accelerated tools&lt;/li&gt;
&lt;li&gt;Run inference locally&lt;/li&gt;
&lt;li&gt;Plan workstation upgrades&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then yes — this affects your roadmap.&lt;/p&gt;

&lt;p&gt;If not, this is still a warning sign:&lt;br&gt;
&lt;strong&gt;AI demand is now powerful enough to reshape entire hardware markets.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Nvidia’s chip delay isn’t a logistics hiccup — it’s a signal.&lt;/p&gt;

&lt;p&gt;AI workloads are rewriting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU availability&lt;/li&gt;
&lt;li&gt;Memory economics&lt;/li&gt;
&lt;li&gt;Hardware planning timelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And for developers, that means &lt;strong&gt;optimize smarter, plan longer, and assume scarcity is the new normal&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Discussion:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Are you already feeling GPU shortages in your dev workflow — or are you fully cloud-based now?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>gaming</category>
      <category>hardware</category>
    </item>
    <item>
      <title>Indexes Aren’t Magic — How Databases Really Use Them</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Fri, 06 Feb 2026 06:06:57 +0000</pubDate>
      <link>https://dev.to/frozenblood/indexes-arent-magic-how-databases-really-use-them-412n</link>
      <guid>https://dev.to/frozenblood/indexes-arent-magic-how-databases-really-use-them-412n</guid>
      <description>&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%2Fsu7gra1z8jrkwsjyvn8f.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%2Fsu7gra1z8jrkwsjyvn8f.png" alt="Image" width="800" height="532"&gt;&lt;/a&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%2F7rk7ea91p857ujy4nxgh.jpg" 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%2F7rk7ea91p857ujy4nxgh.jpg" alt="Image" width="681" height="241"&gt;&lt;/a&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%2Fjeja1hqqdcw8svg13mvn.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%2Fjeja1hqqdcw8svg13mvn.png" alt="Image" width="800" height="336"&gt;&lt;/a&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%2Fxk5p0ide6o1xnt9hx8tt.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%2Fxk5p0ide6o1xnt9hx8tt.png" alt="Image" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Indexes are one of those things every developer &lt;em&gt;knows&lt;/em&gt; they should use — but fewer developers truly understand &lt;strong&gt;how&lt;/strong&gt; databases use them and &lt;strong&gt;why&lt;/strong&gt; they sometimes don’t work the way you expect.&lt;/p&gt;

&lt;p&gt;Ever added an index, shipped it to production, and saw… absolutely no performance improvement? Yeah. Let’s talk about why that happens and how to think about indexes like a database engine does.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What an Index Actually Is (Mentally, Not Academically)
&lt;/h2&gt;

&lt;p&gt;At a high level, most indexes are &lt;strong&gt;sorted data structures&lt;/strong&gt; (often B-trees) that let the database avoid scanning the entire table.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“Check every row to find matches”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The DB can do this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Jump directly to the matching range”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds great. But here’s the catch:&lt;br&gt;
&lt;strong&gt;Indexes are only useful if the query can actually use that ordering.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Why &lt;code&gt;SELECT *&lt;/code&gt; Can Break Index Usage
&lt;/h2&gt;

&lt;p&gt;This surprises a lot of people.&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;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;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if &lt;code&gt;email&lt;/code&gt; is indexed, the database may still:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the index to find the row&lt;/li&gt;
&lt;li&gt;Jump back to the table to fetch all columns&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That second step is called a &lt;strong&gt;heap lookup&lt;/strong&gt;, and it’s expensive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;If your query:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Returns many rows&lt;/li&gt;
&lt;li&gt;Or fetches many columns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…the cost of table lookups can dominate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better approach
&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;SELECT&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;email&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Smaller result set = fewer reads = faster query.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Index Order Matters More Than You Think
&lt;/h2&gt;

&lt;p&gt;Consider this index:&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;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_orders_user_date&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This index is great for:&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;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But &lt;strong&gt;not&lt;/strong&gt; great for:&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;WHERE&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;Indexes are sorted &lt;strong&gt;left to right&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The database can only efficiently use the index starting from the first column (&lt;code&gt;user_id&lt;/code&gt;). Skip it, and the index becomes mostly useless.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule of thumb
&lt;/h3&gt;

&lt;p&gt;Put:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highly selective columns first&lt;/li&gt;
&lt;li&gt;Frequently filtered columns before sorting columns&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Functions in WHERE Clauses Kill Indexes
&lt;/h2&gt;

&lt;p&gt;This is a classic footgun.&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="c1"&gt;-- ❌ Index will not be used&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2025-02-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if &lt;code&gt;created_at&lt;/code&gt; is indexed, the database must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the function to every row&lt;/li&gt;
&lt;li&gt;Then compare results&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fix it by flipping the logic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- ✅ Index-friendly&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2025-02-01'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'2025-02-02'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same result. Completely different performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Low-Cardinality Indexes Often Don’t Help
&lt;/h2&gt;

&lt;p&gt;Indexing a column with very few unique values is usually pointless.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;is_active&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;status&lt;/code&gt; with 3 values&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deleted = false&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;The DB still has to scan a large portion of the table&lt;/li&gt;
&lt;li&gt;The index doesn’t reduce the search space much&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When it &lt;em&gt;can&lt;/em&gt; make sense
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Combined with other columns&lt;/li&gt;
&lt;li&gt;On very large tables&lt;/li&gt;
&lt;li&gt;With partial indexes
&lt;/li&gt;
&lt;/ul&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;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_active_users&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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;em&gt;that&lt;/em&gt; index earns its keep.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Indexes Speed Reads — and Slow Writes
&lt;/h2&gt;

&lt;p&gt;Every index must be updated on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;INSERT&lt;/li&gt;
&lt;li&gt;UPDATE&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Too many indexes can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow down writes&lt;/li&gt;
&lt;li&gt;Increase lock contention&lt;/li&gt;
&lt;li&gt;Bloat memory and disk usage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The mistake
&lt;/h3&gt;

&lt;p&gt;“Query is slow? Add an index.”&lt;/p&gt;

&lt;h3&gt;
  
  
  The better question
&lt;/h3&gt;

&lt;p&gt;“Is this query hot &lt;em&gt;and&lt;/em&gt; unavoidable?”&lt;/p&gt;

&lt;p&gt;Indexes are &lt;strong&gt;trade-offs&lt;/strong&gt;, not free upgrades.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Execution Plans Are Your Best Friend
&lt;/h2&gt;

&lt;p&gt;If you’re not using &lt;code&gt;EXPLAIN&lt;/code&gt;, you’re guessing.&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;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Was the index used?&lt;/li&gt;
&lt;li&gt;How many rows were scanned?&lt;/li&gt;
&lt;li&gt;Where the time actually went?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reality check
&lt;/h3&gt;

&lt;p&gt;If the planner chooses a sequential scan, it’s usually for a reason.&lt;br&gt;
Your job is to understand &lt;em&gt;why&lt;/em&gt;, not to fight it blindly.&lt;/p&gt;


&lt;h2&gt;
  
  
  8. Covering Indexes: The Secret Weapon
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;covering index&lt;/strong&gt; includes all columns needed by the query.&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;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email_id&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this query:&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;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can be answered &lt;strong&gt;entirely from the index&lt;/strong&gt; — no table lookup at all.&lt;/p&gt;

&lt;p&gt;This is one of the biggest performance wins you can get for read-heavy workloads.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Indexes don’t make queries fast by default.&lt;br&gt;
They make &lt;em&gt;specific access patterns&lt;/em&gt; fast.&lt;/p&gt;

&lt;p&gt;To use them well, you need to think like the database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How is the data sorted?&lt;/li&gt;
&lt;li&gt;How many rows are touched?&lt;/li&gt;
&lt;li&gt;Are we forcing extra work?&lt;/li&gt;
&lt;li&gt;Is the index actually selective?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best-performing systems don’t have the &lt;strong&gt;most&lt;/strong&gt; indexes — they have the &lt;strong&gt;right&lt;/strong&gt; ones.&lt;/p&gt;




&lt;h3&gt;
  
  
  Discussion
&lt;/h3&gt;

&lt;p&gt;What’s the most misleading index you’ve ever added — the one you were &lt;em&gt;sure&lt;/em&gt; would help, but didn’t move the needle at all?&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>backend</category>
      <category>performance</category>
    </item>
    <item>
      <title>The Real Cost of Misusing React Hooks (and How to Fix It)</title>
      <dc:creator>Frozen Blood</dc:creator>
      <pubDate>Thu, 05 Feb 2026 07:23:29 +0000</pubDate>
      <link>https://dev.to/frozenblood/the-real-cost-of-misusing-react-hooks-and-how-to-fix-it-3j7h</link>
      <guid>https://dev.to/frozenblood/the-real-cost-of-misusing-react-hooks-and-how-to-fix-it-3j7h</guid>
      <description>&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%2Frepository-images.githubusercontent.com%2F196048036%2F5fae96d6-a1e5-43bc-8556-4ab9d83d4ff2" 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%2Frepository-images.githubusercontent.com%2F196048036%2F5fae96d6-a1e5-43bc-8556-4ab9d83d4ff2" alt="Image" width="1470" height="1320"&gt;&lt;/a&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%2Fawlc7w0meyhvr39dowmy.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%2Fawlc7w0meyhvr39dowmy.png" alt="Image" width="800" height="450"&gt;&lt;/a&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%2F48so6bggga7lm4ysmzlw.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%2F48so6bggga7lm4ysmzlw.png" alt="Image" width="800" height="308"&gt;&lt;/a&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%2Fg983gwdse9cmjggpnv4n.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%2Fg983gwdse9cmjggpnv4n.png" alt="Image" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Hooks feel magical at first. A few &lt;code&gt;useState&lt;/code&gt;s, a &lt;code&gt;useEffect&lt;/code&gt;, maybe a &lt;code&gt;useMemo&lt;/code&gt;, and suddenly your component is alive. But as apps grow, &lt;strong&gt;small hook mistakes quietly turn into performance bugs, stale state, and impossible-to-debug behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you’ve ever said &lt;em&gt;“Why is this effect running again?”&lt;/em&gt; or &lt;em&gt;“Why does this value feel one render behind?”&lt;/em&gt;, this post is for you.&lt;/p&gt;

&lt;p&gt;Let’s walk through the most common Hook mistakes I see in production React apps—and how experienced teams avoid them.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Treating &lt;code&gt;useEffect&lt;/code&gt; Like a Lifecycle Dumping Ground
&lt;/h2&gt;

&lt;p&gt;This is the classic one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;fetchUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;trackAnalytics&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;setIsReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this feels fine. But what’s actually happening?&lt;/p&gt;

&lt;p&gt;You’ve mixed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data fetching&lt;/li&gt;
&lt;li&gt;Side effects&lt;/li&gt;
&lt;li&gt;State transitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…into one untestable blob.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this bites later
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Dependencies become unclear&lt;/li&gt;
&lt;li&gt;Refactors accidentally break behavior&lt;/li&gt;
&lt;li&gt;Effects grow instead of being replaced&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The fix: one effect, one responsibility
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;fetchUser&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="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;trackAnalytics&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="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;setIsReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;It feels verbose—but &lt;strong&gt;clarity beats cleverness every time&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Ignoring the Dependency Array (or Fighting It)
&lt;/h2&gt;

&lt;p&gt;If you’ve ever done this, no judgment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// eslint-disable-next-line react-hooks/exhaustive-deps&lt;/span&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;doSomething&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="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;You’re telling React: &lt;em&gt;“I know better.”&lt;/em&gt;&lt;br&gt;
Most of the time… you don’t 😄&lt;/p&gt;
&lt;h3&gt;
  
  
  What actually goes wrong
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Effects read stale values&lt;/li&gt;
&lt;li&gt;Bugs appear only after re-renders&lt;/li&gt;
&lt;li&gt;Logic breaks when props change&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  The fix: embrace dependencies
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;doSomething&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="p"&gt;},&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If adding a dependency causes infinite loops, that’s a &lt;strong&gt;design smell&lt;/strong&gt;, not a React problem.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Overusing &lt;code&gt;useMemo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Hooks for performance feel responsible. Until they’re everywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;computedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;expensiveCalculation&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;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The truth
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useMemo&lt;/code&gt; is a cache, not a guarantee&lt;/li&gt;
&lt;li&gt;It adds complexity and memory overhead&lt;/li&gt;
&lt;li&gt;Most computations don’t need it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When you actually need it
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;useMemo&lt;/code&gt; or &lt;code&gt;useCallback&lt;/code&gt; &lt;strong&gt;only if&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The calculation is expensive&lt;/li&gt;
&lt;li&gt;The component re-renders often&lt;/li&gt;
&lt;li&gt;You’ve measured a problem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Otherwise, &lt;strong&gt;let React re-run the function&lt;/strong&gt;. It’s fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Storing Derived State in &lt;code&gt;useState&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This one causes subtle bugs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFullName&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="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;setFullName&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="nx"&gt;firstName&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="nx"&gt;lastName&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Source state&lt;/li&gt;
&lt;li&gt;Derived state&lt;/li&gt;
&lt;li&gt;Synchronization logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All for something React can compute instantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix: derive during render
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;firstName&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="nx"&gt;lastName&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If state can be calculated from props or other state, &lt;strong&gt;don’t store it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Mutating State Objects Accidentally
&lt;/h2&gt;

&lt;p&gt;React state must be immutable. But it’s easy to forget.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Mutates existing object&lt;/span&gt;
&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&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;New Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may not re-render at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix: always create new references
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;profile&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="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React compares references.&lt;br&gt;
If the reference doesn’t change, &lt;strong&gt;neither does the UI&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Putting Too Much Logic Inside Components
&lt;/h2&gt;

&lt;p&gt;Hooks don’t mean “everything goes in the component.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useData&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;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&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;sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&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;grouped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;groupBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sorted&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UI&lt;/span&gt; &lt;span class="na"&gt;grouped&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;grouped&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gets ugly fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix: extract custom hooks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useDashboardData&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;groupBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your component becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller&lt;/li&gt;
&lt;li&gt;Easier to test&lt;/li&gt;
&lt;li&gt;Easier to reuse&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hooks are &lt;strong&gt;abstractions&lt;/strong&gt;, not decorations.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Forgetting That Hooks Run on Every Render
&lt;/h2&gt;

&lt;p&gt;Hooks are not events. They are &lt;strong&gt;part of rendering&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useExpensiveThing&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs every render unless you control it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mental model that helps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rendering should be pure&lt;/li&gt;
&lt;li&gt;Effects handle side effects&lt;/li&gt;
&lt;li&gt;Memoization is an optimization, not a default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a hook does too much work, &lt;strong&gt;it’s probably doing the wrong job&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;React Hooks are powerful—but only if you respect their model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Effects are for side effects, not logic dumps&lt;/li&gt;
&lt;li&gt;Dependencies are your friend&lt;/li&gt;
&lt;li&gt;Derived state should stay derived&lt;/li&gt;
&lt;li&gt;Performance hooks are tools, not habits&lt;/li&gt;
&lt;li&gt;Clean abstractions beat clever tricks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most “weird React bugs” aren’t React bugs at all.&lt;br&gt;
They’re &lt;strong&gt;mental model mismatches&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Discussion
&lt;/h3&gt;

&lt;p&gt;What’s the most confusing Hook bug you’ve ever debugged—and what was the &lt;em&gt;actual&lt;/em&gt; root cause once you figured it out?&lt;/p&gt;

</description>
      <category>react</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
