<?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: Sushil Shinde</title>
    <description>The latest articles on DEV Community by Sushil Shinde (@sushil_shinde_96cb7494dac).</description>
    <link>https://dev.to/sushil_shinde_96cb7494dac</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%2F4142720%2Fb11a1b50-f67f-4c22-a71f-46a6709e88ac.jpg</url>
      <title>DEV Community: Sushil Shinde</title>
      <link>https://dev.to/sushil_shinde_96cb7494dac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sushil_shinde_96cb7494dac"/>
    <language>en</language>
    <item>
      <title>Your service handles 80,000 requests a second. Until it doesn't.</title>
      <dc:creator>Sushil Shinde</dc:creator>
      <pubDate>Fri, 25 Sep 2026 10:39:50 +0000</pubDate>
      <link>https://dev.to/sushil_shinde_96cb7494dac/your-service-handles-80000-requests-a-second-until-it-doesnt-28g2</link>
      <guid>https://dev.to/sushil_shinde_96cb7494dac/your-service-handles-80000-requests-a-second-until-it-doesnt-28g2</guid>
      <description>&lt;p&gt;&lt;em&gt;Why utilisation is not capacity, with the numbers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every capacity conversation I have been in goes the same way. Someone runs a load test, finds the number where the service falls over, and writes it down: "each instance handles 5,000 requests a second". From then on the sizing is arithmetic. 80,000 a second at peak, divide by 5,000, that's 16 instances, round up to 18 for safety.&lt;/p&gt;

&lt;p&gt;Then the service falls over at 70,000.&lt;/p&gt;

&lt;p&gt;Nothing was wrong with the load test. What was wrong is the idea that a service has a single number called capacity, and that it is fine right up to that number. It isn't. It gets slow long before it gets full, and the slowness is what kills you.&lt;/p&gt;

&lt;h2&gt;
  
  
  A service is a queue
&lt;/h2&gt;

&lt;p&gt;Picture one instance of a redirect service. A request arrives, it takes 2 ms of actual work, it leaves. If requests arrived in perfect rhythm, one every 2 ms, the instance would be 100% busy and every request would take exactly 2 ms.&lt;/p&gt;

&lt;p&gt;Traffic does not arrive in rhythm. It arrives in clumps. Two requests land in the same millisecond, one has to wait for the other. Three land, the third waits for both. The busier the instance, the more often this happens, and the longer the clumps take to clear.&lt;/p&gt;

&lt;p&gt;The textbook result for this (the M/M/1 queue, if you want to look it up) is short:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;time in system = own work ÷ (1 − utilisation)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At 50% busy a 2 ms request takes 4 ms. At 70%, 6.7 ms. At 90%, 20 ms. At 96%, 50 ms. At 99%, 200 ms. The curve does not rise, it turns vertical.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0lhajkxe4b3q1a2spe1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0lhajkxe4b3q1a2spe1.png" alt="The latency curve: flat until about 70%, then vertical" width="720" height="1148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That denominator is the whole story. Capacity is the point where it hits zero. Everything interesting happens before that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same service, four ways
&lt;/h2&gt;

&lt;p&gt;Here is a URL shortener, the classic warm-up problem. Redirects are the read path: a lookup in a cache, occasionally a miss to the store. 23 copies of the redirect service, 5,000 requests a second each, 2 ms of work per request.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1p43xx0hbnvtofkiayue.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1p43xx0hbnvtofkiayue.png" alt="The URL shortener at 80K redirects a second: every component within its headroom" width="799" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the design's peak of 80,000 redirects a second it sits at 70% busy. This is the number everyone would call "comfortable". Look at what a request actually costs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traffic&lt;/th&gt;
&lt;th&gt;Busy&lt;/th&gt;
&lt;th&gt;Own work&lt;/th&gt;
&lt;th&gt;Waiting&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;80K/s&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;td&gt;2 ms&lt;/td&gt;
&lt;td&gt;4.6 ms&lt;/td&gt;
&lt;td&gt;6.6 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90K/s&lt;/td&gt;
&lt;td&gt;78%&lt;/td&gt;
&lt;td&gt;2 ms&lt;/td&gt;
&lt;td&gt;7.2 ms&lt;/td&gt;
&lt;td&gt;9.2 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100K/s&lt;/td&gt;
&lt;td&gt;87%&lt;/td&gt;
&lt;td&gt;2 ms&lt;/td&gt;
&lt;td&gt;13 ms&lt;/td&gt;
&lt;td&gt;15 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;110K/s&lt;/td&gt;
&lt;td&gt;96%&lt;/td&gt;
&lt;td&gt;2 ms&lt;/td&gt;
&lt;td&gt;44 ms&lt;/td&gt;
&lt;td&gt;46 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The work never changes. Two milliseconds, every row. The waiting goes from twice the work to twenty-two times the work, and traffic only grew by a third.&lt;/p&gt;

&lt;p&gt;At 120,000 a second the service is over. Not slow, over: more is arriving than it can serve, the queue grows without bound, and there is no steady answer for how long a request takes.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs2csq3p6m1lnp0g3c3km.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs2csq3p6m1lnp0g3c3km.png" alt="At 120K a second: over capacity, with the fix the engine suggests" width="799" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why 70% is the number
&lt;/h2&gt;

&lt;p&gt;This is where the "70% headroom" rule of thumb comes from, and it is not arbitrary. Below 70% the curve is nearly flat: adding load costs you little latency. Above it, every extra point of utilisation costs more than the last one. Running at 70% means you are buying the flat part of the curve and leaving the vertical part for the day the marketing email goes out.&lt;/p&gt;

&lt;p&gt;It also means something more concrete. At 70% busy with 23 copies, losing one copy puts the other 22 at 73%. Fine. At 90% busy, losing one puts them at 94%, and you are in the vertical part with a deploy half done.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with this
&lt;/h2&gt;

&lt;p&gt;Three things change once you see capacity this way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Size for latency, not for throughput.&lt;/strong&gt; The question is not "how many requests can it take" but "at how many requests does p99 cross what the caller will tolerate". For a 2 ms service and a 20 ms budget, that is about 90%, and you want to be well below it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measure own work separately from waiting.&lt;/strong&gt; If your dashboards only show total latency, you cannot tell a slow service from a busy one. They need different fixes. Slow needs a profiler. Busy needs copies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Look at the whole path.&lt;/strong&gt; A request through a load balancer, a service and a cache pays the queue at each hop. Three components at 70% do not make a 70% system; the waits add up, and the slowest hop dominates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on your own numbers
&lt;/h2&gt;

&lt;p&gt;The design above is a real one. Open it, change the traffic, watch the badges change colour:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://systemdesign101.online/s/7fzmvd7i" rel="noopener noreferrer"&gt;Open the URL shortener in the playground&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Put your own service in: own work in milliseconds, how many copies, what one copy handles. It will tell you where the curve turns vertical for you, which is a better number to write down than the one from the load test.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I built &lt;a href="https://systemdesign101.online" rel="noopener noreferrer"&gt;System Design 101&lt;/a&gt; because I kept having this conversation. It is free, runs in your browser, and every number shows its working.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>architecture</category>
      <category>performance</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
