<?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: Rupesh Mangal</title>
    <description>The latest articles on DEV Community by Rupesh Mangal (@rupesh).</description>
    <link>https://dev.to/rupesh</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%2F547847%2F5f8c0c8e-58f3-449c-9933-c4660661e7cf.jpeg</url>
      <title>DEV Community: Rupesh Mangal</title>
      <link>https://dev.to/rupesh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rupesh"/>
    <language>en</language>
    <item>
      <title>Sync vs Async Django servers - Load testing</title>
      <dc:creator>Rupesh Mangal</dc:creator>
      <pubDate>Sun, 27 Dec 2020 18:06:52 +0000</pubDate>
      <link>https://dev.to/rupesh/sync-vs-async-django-servers-load-testing-35lh</link>
      <guid>https://dev.to/rupesh/sync-vs-async-django-servers-load-testing-35lh</guid>
      <description>&lt;p&gt;If you are using &lt;strong&gt;Gunicorn&lt;/strong&gt; as &lt;strong&gt;API server Gateway&lt;/strong&gt; and you want to reduce the &lt;strong&gt;response time&lt;/strong&gt; drastically. then you are in the right place.&lt;/p&gt;

&lt;p&gt;A while ago our application experienced a surge in the number of active users and our API &lt;strong&gt;response time&lt;/strong&gt; started to rise up and then &lt;strong&gt;Asynchronous server&lt;/strong&gt; came to our rescue.&lt;/p&gt;

&lt;p&gt;This post covers the &lt;strong&gt;Load testing&lt;/strong&gt; result comparison between &lt;strong&gt;Sync and Async Gunicorn servers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load testing&lt;/strong&gt; was done using &lt;a href="https://locust.io/" rel="noopener noreferrer"&gt;Locust&lt;/a&gt;. one of the best tools out there IMO&lt;/p&gt;

&lt;h1&gt;
  
  
  Synchronous Gunicorn Server
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F50qhk61t0jpvne6j4sdx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F50qhk61t0jpvne6j4sdx.jpeg" alt="Sync Gunicorn server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  &lt;a href="https://medium.com/@nhudinhtuan/gunicorn-worker-types-practice-advice-for-better-performance-7a299bb8f929" rel="noopener noreferrer"&gt;credits&lt;/a&gt;
&lt;/h6&gt;

&lt;h2&gt;
  
  
  100 concurrent Users
&lt;/h2&gt;

&lt;h3&gt;
  
  
  RPS(Requests per second): &lt;strong&gt;12&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Response time:
&lt;/h3&gt;

&lt;p&gt;--&amp;gt; median: &lt;strong&gt;11000&lt;/strong&gt; ms&lt;br&gt;
--&amp;gt; 95 %tile: &lt;strong&gt;17000&lt;/strong&gt; ms (95% requests finish before this time)&lt;/p&gt;

&lt;h4&gt;
  
  
  RPS
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkljtptd43uxoffr146gv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkljtptd43uxoffr146gv.png" alt="RPS 100 users Sync Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Response Time
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3lgvj3l2dyfah5e5uqs3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3lgvj3l2dyfah5e5uqs3.png" alt="Response time 100 users Sync Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  350 concurrent Users &lt;em&gt;(max supported with synchronous server)&lt;/em&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  RPS: &lt;strong&gt;6&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Response time:
&lt;/h3&gt;

&lt;p&gt;--&amp;gt; median: &lt;strong&gt;25000&lt;/strong&gt; ms&lt;br&gt;
--&amp;gt; 95 %tile: &lt;strong&gt;30000&lt;/strong&gt; ms (95% requests finish before this time)&lt;/p&gt;

&lt;h4&gt;
  
  
  RPS
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fof8zf6t2ods6l86i8lal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fof8zf6t2ods6l86i8lal.png" alt="RPS 350 users Sync Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Response time
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F02o6s07hm937vwk7o9sp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F02o6s07hm937vwk7o9sp.png" alt="Response time 350 users Sync Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  400 concurrent users
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;server started to respond with **ConnectionError&lt;/em&gt;* for 100% for requests*&lt;/p&gt;

&lt;h1&gt;
  
  
  Asynchronous Gunicorn Server(&lt;em&gt;Gevent&lt;/em&gt;)
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0gi1wvmav0snlos99djb.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0gi1wvmav0snlos99djb.jpeg" alt="Asynchronous Gunicorn Server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  &lt;a href="https://medium.com/@nhudinhtuan/gunicorn-worker-types-practice-advice-for-better-performance-7a299bb8f929" rel="noopener noreferrer"&gt;credits&lt;/a&gt;
&lt;/h6&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;100 concurrent Users&lt;/em&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  RPS: &lt;strong&gt;50&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Response time:
&lt;/h3&gt;

&lt;p&gt;--&amp;gt; median: &lt;strong&gt;2200&lt;/strong&gt; ms&lt;br&gt;
--&amp;gt; 95 %tile: &lt;strong&gt;5000&lt;/strong&gt; ms (95% requests finish before this time)&lt;/p&gt;

&lt;h4&gt;
  
  
  RPS:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa8sk2e2jot7sds3ug5dv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa8sk2e2jot7sds3ug5dv.png" alt="RPS 100 users Async Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Response time:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F22beuhk65fgszuv5mp9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F22beuhk65fgszuv5mp9i.png" alt="Response time 100 users Async Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;500 concurrent Users&lt;/em&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  RPS: &lt;strong&gt;50&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Response time:
&lt;/h3&gt;

&lt;p&gt;--&amp;gt; median: &lt;strong&gt;6500&lt;/strong&gt; ms&lt;br&gt;
--&amp;gt; 95 %tile: &lt;strong&gt;18000&lt;/strong&gt; ms (95% requests finish before this time)&lt;/p&gt;

&lt;h4&gt;
  
  
  RPS:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqy3sz0z1zrvzjjtwr11q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqy3sz0z1zrvzjjtwr11q.png" alt="RPS 500 users Async Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Response time:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F24e38x2391a7rurltapr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F24e38x2391a7rurltapr.png" alt="Response time 500 users Async Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;1000 concurrent Users&lt;/em&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  RPS: &lt;strong&gt;~25-30&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Response time:
&lt;/h3&gt;

&lt;p&gt;--&amp;gt; median: &lt;strong&gt;20000&lt;/strong&gt; ms&lt;br&gt;
--&amp;gt; 95 %tile: &lt;strong&gt;50000&lt;/strong&gt; ms (95% requests finish before this time)&lt;/p&gt;

&lt;h4&gt;
  
  
  RPS:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk0f33ylb7plnyp404lry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk0f33ylb7plnyp404lry.png" alt="RPS 1000 users Async Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Response time:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyb23y10ygryps7ycvcyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyb23y10ygryps7ycvcyu.png" alt="Response time 1000 users Async Gunicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Observations:
&lt;/h1&gt;

&lt;p&gt;1) &lt;strong&gt;RPS&lt;/strong&gt; starts to &lt;strong&gt;decrease&lt;/strong&gt; with &lt;strong&gt;increased load&lt;/strong&gt;.&lt;br&gt;
2) &lt;strong&gt;RPS&lt;/strong&gt; &lt;strong&gt;increased&lt;/strong&gt; by at least &lt;strong&gt;400%&lt;/strong&gt; in &lt;strong&gt;Async&lt;/strong&gt; server.&lt;br&gt;
3) With the &lt;strong&gt;same&lt;/strong&gt; number of &lt;strong&gt;users&lt;/strong&gt; response time was just &lt;strong&gt;20%&lt;/strong&gt; in the case of the async server (&lt;strong&gt;500%&lt;/strong&gt; better performance).&lt;br&gt;
4) with the &lt;strong&gt;same&lt;/strong&gt; response time &lt;strong&gt;async&lt;/strong&gt; server was able to serve &lt;strong&gt;400%&lt;/strong&gt; more users than &lt;strong&gt;sync&lt;/strong&gt; server. (&lt;strong&gt;500&lt;/strong&gt; users in async vs &lt;strong&gt;100&lt;/strong&gt; users in sync).&lt;/p&gt;

</description>
      <category>django</category>
      <category>gunicorn</category>
      <category>server</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
