<?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: M Nouman Berlas</title>
    <description>The latest articles on DEV Community by M Nouman Berlas (@noumanberlas).</description>
    <link>https://dev.to/noumanberlas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005344%2Fde51c1cf-d1fc-48ed-867b-4bf4194d8267.png</url>
      <title>DEV Community: M Nouman Berlas</title>
      <link>https://dev.to/noumanberlas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noumanberlas"/>
    <language>en</language>
    <item>
      <title>Parallel Processing Gone Wrong</title>
      <dc:creator>M Nouman Berlas</dc:creator>
      <pubDate>Thu, 09 Jul 2026 09:34:00 +0000</pubDate>
      <link>https://dev.to/noumanberlas/parallel-processing-gone-wrong-4k82</link>
      <guid>https://dev.to/noumanberlas/parallel-processing-gone-wrong-4k82</guid>
      <description>&lt;p&gt;⚡ "Let's Make It Faster!" (Famous Last Words)&lt;/p&gt;

&lt;p&gt;The Scene: Sprint planning. The feature? Bulk data processing.&lt;br&gt;
Me (naive): "Let's just run everything in parallel! It'll be 10x faster!"&lt;br&gt;
Production (3 days later): catches fire 🔥&lt;br&gt;
What I Thought Would Happen:&lt;br&gt;
• 100 items to process&lt;br&gt;
• Run them all in parallel&lt;br&gt;
• Finish in 1/10th the time&lt;br&gt;
• Get promoted&lt;br&gt;
• Become CTO&lt;br&gt;
What Actually Happened:&lt;br&gt;
• 100 concurrent database connections&lt;br&gt;
• Database connection pool exhausted&lt;br&gt;
• ALL requests start failing (not just ours)&lt;br&gt;
• 2 AM phone call from the CTO (not a promotion call)&lt;br&gt;
• Emergency rollback at 3 AM&lt;br&gt;
• Very awkward Slack conversation&lt;br&gt;
The Broken Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// "I'll just parallelize everything!"&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ProcessItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// YOLO&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why This Implodes:&lt;br&gt;
❌ No limit on concurrent operations&lt;br&gt;
❌ No shared state protection&lt;br&gt;
❌ No error handling per item&lt;br&gt;
❌ Overwhelms downstream services&lt;br&gt;
❌ Database can't handle the connections&lt;br&gt;
❌ Network ports get exhausted&lt;br&gt;
❌ And my ego gets crushed&lt;br&gt;
The Fix That Saved My Job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;passCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;failCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConcurrentDictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Key: MaxDegreeOfParallelism controls concurrency&lt;/span&gt;
&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;For&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ParallelOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;MaxDegreeOfParallelism&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessorCount&lt;/span&gt; &lt;span class="c1"&gt;// Usually 4-8&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&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="nf"&gt;ProcessItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

            &lt;span class="c1"&gt;// Thread-safe counter increment&lt;/span&gt;
            &lt;span class="n"&gt;Interlocked&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;passCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; 
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Interlocked&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;failCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Thread-safe error collection&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&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="c1"&gt;// Now you can safely check results&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Success: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;passCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Failed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;failCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Golden Rules I Learned:&lt;br&gt;
1️⃣ Parallelism ≠ Performance - Too much parallelism kills performance&lt;br&gt;
2️⃣ Know Your Bottleneck - If it's I/O bound, 4-8 threads is usually optimal&lt;br&gt;
3️⃣ Protect Shared State - Use Interlocked or ConcurrentCollections&lt;br&gt;
4️⃣ Configure, Don't Hardcode - Make MaxDegreeOfParallelism environment-specific&lt;br&gt;
5️⃣ Test Under Load - It works on my machine ≠ it works in production&lt;br&gt;
The Results After Proper Implementation:&lt;br&gt;
📊 Controlled concurrency = predictable performance&lt;br&gt;
✅ Database connections stay healthy&lt;br&gt;
⚡ 6x speedup (not 100x, but sustainable)&lt;br&gt;
💰 Zero production incidents&lt;br&gt;
😊 Sleep peacefully without 3 AM alerts&lt;br&gt;
The Hard Truth:&lt;br&gt;
More threads ≠ More speed&lt;br&gt;
It's like adding more cooks to a kitchen. At some point, they just bump into each other.&lt;br&gt;
What's your parallel processing horror story? I can't be the only one who learned this the hard way 😅&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #parallelprocessing #performanceoptimization #productionissues #softwareengineering #threading #scalability #lessonslearned #debugging #csharp #techleadership
&lt;/h1&gt;




&lt;h2&gt;
  
  
  P.S. If you're using Task.Run() in a loop or unbounded Parallel.ForEach(), you're one production deployment away from a very bad day.
&lt;/h2&gt;

</description>
      <category>csharp</category>
      <category>database</category>
      <category>dotnet</category>
      <category>performance</category>
    </item>
    <item>
      <title>The Middleware Bug That Took Down Our API (Twice)</title>
      <dc:creator>M Nouman Berlas</dc:creator>
      <pubDate>Tue, 07 Jul 2026 15:52:33 +0000</pubDate>
      <link>https://dev.to/noumanberlas/the-middleware-bug-that-took-down-our-api-twice-4mej</link>
      <guid>https://dev.to/noumanberlas/the-middleware-bug-that-took-down-our-api-twice-4mej</guid>
      <description>&lt;p&gt;Picture this: Your API is humming along perfectly. 99.9% success rate. Life is good.&lt;br&gt;
Then suddenly - BAM! 🔥&lt;br&gt;
Random 500 errors. Garbled responses. Users complaining about "weird characters" in their data.&lt;br&gt;
And it only happens under load.&lt;br&gt;
The Culprit? Our "innocent" logging middleware.&lt;br&gt;
Here's what we did WRONG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;InvokeAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RequestDelegate&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Call next middleware&lt;/span&gt;

    &lt;span class="c1"&gt;// Try to log the response&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAsStringAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Logger&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="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Oops...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;

&lt;span class="n"&gt;Why&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;Fails&lt;/span&gt; &lt;span class="n"&gt;Spectacularly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;already&lt;/span&gt; &lt;span class="n"&gt;consumed&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;sent&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;Multiple&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;modify&lt;/span&gt; &lt;span class="n"&gt;streams&lt;/span&gt; &lt;span class="n"&gt;concurrently&lt;/span&gt;
&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;Streams&lt;/span&gt; &lt;span class="n"&gt;aren&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;safe&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;
&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;Gzip&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;compressed&lt;/span&gt; &lt;span class="n"&gt;responses&lt;/span&gt; &lt;span class="n"&gt;come&lt;/span&gt; &lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;garbage&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;
&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;Everything&lt;/span&gt; &lt;span class="n"&gt;breaks&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;weird&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unpredictable&lt;/span&gt; &lt;span class="n"&gt;ways&lt;/span&gt;
&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Fix&lt;/span&gt; &lt;span class="n"&gt;That&lt;/span&gt; &lt;span class="n"&gt;Actually&lt;/span&gt; &lt;span class="n"&gt;Works&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;InvokeAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RequestDelegate&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Step 1: Enable request buffering&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnableBuffering&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Step 2: Swap response stream with a buffered one&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;originalBodyStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;memoryStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memoryStream&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="c1"&gt;// Step 3: Let the pipeline execute&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 4: Safely read the buffered response&lt;/span&gt;
        &lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 5: Handle compression properly&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;responseBody&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="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentEncoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gzip"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;gzipStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;GZipStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CompressionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decompress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gzipStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;responseBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;responseBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 6: Log it&lt;/span&gt;
        &lt;span class="n"&gt;Logger&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="n"&gt;responseBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 7: Copy back to original stream&lt;/span&gt;
        &lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyToAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;originalBodyStream&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="c1"&gt;// Step 8: Restore original stream&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;originalBodyStream&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;The Hidden Gotcha Nobody Tells You:&lt;br&gt;
Modern APIs use gzip/deflate compression by default. If you don't decompress before reading, you get binary garbage that looks like: �H���W�K�M�U��Z&lt;/p&gt;

&lt;p&gt;Our Results: &lt;br&gt;
✅ Zero stream-related exceptions &lt;br&gt;
✅ Zero "garbage character" bug reports &lt;br&gt;
✅ Proper logging at 10,000+ req/min &lt;br&gt;
✅ My on-call rotation got way quieter 😴&lt;br&gt;
The Brutal Truth:&lt;br&gt;
Middleware is easy to write. Thread-safe, production-ready middleware? That's an art form.&lt;/p&gt;

&lt;p&gt;Who else has spent hours debugging middleware issues? Let's commiserate in the comments 👇&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #aspnetcore #middleware #threadsafety #debugging #productionissues #softwareengineering #webdevelopment #csharp #lessonslearned #cloudnative
&lt;/h1&gt;




&lt;h2&gt;
  
  
  P.S. Always test middleware under load. Your local machine running 1 request at a time will NEVER expose these bugs.
&lt;/h2&gt;

</description>
      <category>api</category>
      <category>backend</category>
      <category>debugging</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>HttpClient Socket Exhaustion</title>
      <dc:creator>M Nouman Berlas</dc:creator>
      <pubDate>Sat, 27 Jun 2026 13:00:21 +0000</pubDate>
      <link>https://dev.to/noumanberlas/httpclient-socket-exhaustion-3fln</link>
      <guid>https://dev.to/noumanberlas/httpclient-socket-exhaustion-3fln</guid>
      <description>&lt;p&gt;🔥 Your .NET API is Slowly Dying (And You Don't Even Know It)&lt;/p&gt;

&lt;p&gt;Last month, our production system started timing out randomly. No errors. No warnings. Just... slow death.&lt;br&gt;
After 3 sleepless nights and diving through 60+ microservices, I found the culprit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
var client = new HttpClient(); // This single line&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Here's what was happening:&lt;br&gt;
Every HTTP call was creating a NEW TCP socket. Under load, we exhausted the system's connection pool. Requests started queuing. Response times went from 200ms to 30+ seconds.&lt;/p&gt;

&lt;p&gt;The Silent Killer:&lt;br&gt;
• ✅ Your code compiles fine&lt;br&gt;
• ✅ Your tests pass&lt;br&gt;
• ✅ It works in dev/staging&lt;br&gt;
• ❌ It crashes in production under real load&lt;/p&gt;

&lt;p&gt;The Fix That Saved Our SLA:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
// In Startup.cs&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;code&gt;services.AddHttpClient("MyService", client =&amp;gt; {&lt;br&gt;
    client.Timeout = TimeSpan.FromSeconds(120);&lt;br&gt;
})&lt;/code&gt;&lt;br&gt;
&lt;code&gt;.ConfigurePrimaryHttpMessageHandler(() =&amp;gt; new SocketsHttpHandler {&lt;br&gt;
    PooledConnectionLifetime = TimeSpan.FromMinutes(2),&lt;br&gt;
    PooledConnectionIdleTimeout = TimeSpan.FromMinutes(5),&lt;br&gt;
    MaxConnectionsPerServer = 20,&lt;br&gt;
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate&lt;br&gt;
});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;// In your service&lt;br&gt;
public class MyService {&lt;br&gt;
    private readonly IHttpClientFactory _clientFactory;    &lt;br&gt;
    public MyService(IHttpClientFactory clientFactory) {&lt;br&gt;
        _clientFactory = clientFactory;&lt;br&gt;
    }    &lt;br&gt;
    public async Task&amp;lt;string&amp;gt; GetDataAsync() {&lt;br&gt;
        var client = _clientFactory.CreateClient("MyService");&lt;br&gt;
        // Use the client&lt;br&gt;
    }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The Results: &lt;br&gt;
📊 95% reduction in connection failures &lt;br&gt;
⚡ 40% improvement in throughput &lt;br&gt;
💰 Prevented potential revenue loss from timeouts&lt;/p&gt;

&lt;p&gt;The Lesson:&lt;br&gt;
IHttpClientFactory isn't just a "best practice" - it's a production survival tool.&lt;br&gt;
Microsoft documented this in 2018, but I still see this anti-pattern EVERYWHERE.&lt;br&gt;
Have you been bitten by socket exhaustion? &lt;/p&gt;

&lt;p&gt;Share your battle story in comments 👇&lt;/p&gt;

&lt;p&gt;#performance #dotnet #csharp #softwareengineering #productionissues #microservices #debugging #azure #performanceoptimization #lessonslearned #techleadership&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>networking</category>
      <category>performance</category>
    </item>
    <item>
      <title>Battle Stories Series</title>
      <dc:creator>M Nouman Berlas</dc:creator>
      <pubDate>Sat, 27 Jun 2026 12:40:11 +0000</pubDate>
      <link>https://dev.to/noumanberlas/battle-stories-series-2c50</link>
      <guid>https://dev.to/noumanberlas/battle-stories-series-2c50</guid>
      <description>&lt;p&gt;I will be writing about the real world instances that I have witnessed during my career from production issues. For almost all of the I have to spend the night figuring out the real cause and end up having to go through the team post mortem.&lt;br&gt;
Love to hear about your production experiences as well. The first story to be followed soon :)&lt;/p&gt;

</description>
      <category>performance</category>
    </item>
  </channel>
</rss>
