Jekyll2022-03-14T17:18:54+00:00http://klen.github.io/py-frameworks-bench/feed.xmlPython Async (ASGI) Web Frameworks BenchmarkThis is a simple benchmark for python async frameworks.Kirill KlenovResults (2022-03-14)2022-03-14T00:00:00+00:002022-03-14T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2022/03/14/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','sanic','muffin','falcon','starlette','baize','emmett','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['18546','16571','15558','15554','13880','13797','13380','9060','7240','3425','3232','1002',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10777','10505','10319','10133','8135','7091','6581','5882','4496','2780','2146','883',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['5604','5025','4425','3433','2834','2434','2218','2099','2067','1746','1414','689',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.5</code></td> <td style="text-align: right">18546</td> <td style="text-align: right">2.80</td> <td style="text-align: right">4.53</td> <td style="text-align: right">3.41</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.87.0</code></td> <td style="text-align: right">16571</td> <td style="text-align: right">3.09</td> <td style="text-align: right">5.17</td> <td style="text-align: right">3.83</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.1</code></td> <td style="text-align: right">15558</td> <td style="text-align: right">4.70</td> <td style="text-align: right">5.14</td> <td style="text-align: right">4.08</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">15554</td> <td style="text-align: right">3.29</td> <td style="text-align: right">5.49</td> <td style="text-align: right">4.08</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">13880</td> <td style="text-align: right">3.69</td> <td style="text-align: right">6.21</td> <td style="text-align: right">4.58</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">13797</td> <td style="text-align: right">3.70</td> <td style="text-align: right">6.16</td> <td style="text-align: right">4.60</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.4.5</code></td> <td style="text-align: right">13380</td> <td style="text-align: right">5.54</td> <td style="text-align: right">6.10</td> <td style="text-align: right">4.75</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.75.0</code></td> <td style="text-align: right">9060</td> <td style="text-align: right">5.46</td> <td style="text-align: right">9.79</td> <td style="text-align: right">7.03</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">7240</td> <td style="text-align: right">8.74</td> <td style="text-align: right">9.01</td> <td style="text-align: right">8.84</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.3</code></td> <td style="text-align: right">3425</td> <td style="text-align: right">18.99</td> <td style="text-align: right">20.08</td> <td style="text-align: right">18.68</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3232</td> <td style="text-align: right">19.76</td> <td style="text-align: right">19.94</td> <td style="text-align: right">19.81</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0.3</code></td> <td style="text-align: right">1002</td> <td style="text-align: right">59.00</td> <td style="text-align: right">66.26</td> <td style="text-align: right">63.72</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.1</code></td> <td style="text-align: right">10777</td> <td style="text-align: right">6.97</td> <td style="text-align: right">7.67</td> <td style="text-align: right">5.90</td> </tr> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.5</code></td> <td style="text-align: right">10505</td> <td style="text-align: right">4.70</td> <td style="text-align: right">8.16</td> <td style="text-align: right">6.07</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.87.0</code></td> <td style="text-align: right">10319</td> <td style="text-align: right">4.79</td> <td style="text-align: right">8.41</td> <td style="text-align: right">6.17</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">10133</td> <td style="text-align: right">4.88</td> <td style="text-align: right">8.61</td> <td style="text-align: right">6.28</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">8135</td> <td style="text-align: right">6.03</td> <td style="text-align: right">10.76</td> <td style="text-align: right">7.83</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.4.5</code></td> <td style="text-align: right">7091</td> <td style="text-align: right">7.17</td> <td style="text-align: right">11.58</td> <td style="text-align: right">9.12</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">6581</td> <td style="text-align: right">9.96</td> <td style="text-align: right">10.24</td> <td style="text-align: right">9.71</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.75.0</code></td> <td style="text-align: right">5882</td> <td style="text-align: right">8.36</td> <td style="text-align: right">15.16</td> <td style="text-align: right">10.85</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">4496</td> <td style="text-align: right">14.15</td> <td style="text-align: right">14.32</td> <td style="text-align: right">14.24</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2780</td> <td style="text-align: right">22.95</td> <td style="text-align: right">23.17</td> <td style="text-align: right">23.02</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.3</code></td> <td style="text-align: right">2146</td> <td style="text-align: right">29.42</td> <td style="text-align: right">30.05</td> <td style="text-align: right">29.81</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0.3</code></td> <td style="text-align: right">883</td> <td style="text-align: right">68.00</td> <td style="text-align: right">71.74</td> <td style="text-align: right">72.37</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.5</code></td> <td style="text-align: right">5604</td> <td style="text-align: right">8.87</td> <td style="text-align: right">15.77</td> <td style="text-align: right">11.40</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.1</code></td> <td style="text-align: right">5025</td> <td style="text-align: right">10.44</td> <td style="text-align: right">16.83</td> <td style="text-align: right">12.72</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.87.0</code></td> <td style="text-align: right">4425</td> <td style="text-align: right">11.14</td> <td style="text-align: right">19.99</td> <td style="text-align: right">14.43</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3433</td> <td style="text-align: right">14.56</td> <td style="text-align: right">25.48</td> <td style="text-align: right">18.73</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">2834</td> <td style="text-align: right">21.89</td> <td style="text-align: right">24.48</td> <td style="text-align: right">22.57</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">2434</td> <td style="text-align: right">20.10</td> <td style="text-align: right">36.39</td> <td style="text-align: right">26.26</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">2218</td> <td style="text-align: right">28.81</td> <td style="text-align: right">29.09</td> <td style="text-align: right">28.84</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.75.0</code></td> <td style="text-align: right">2099</td> <td style="text-align: right">23.61</td> <td style="text-align: right">41.91</td> <td style="text-align: right">30.44</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2067</td> <td style="text-align: right">30.89</td> <td style="text-align: right">31.09</td> <td style="text-align: right">30.95</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.3</code></td> <td style="text-align: right">1746</td> <td style="text-align: right">36.68</td> <td style="text-align: right">37.58</td> <td style="text-align: right">36.63</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.4.5</code></td> <td style="text-align: right">1414</td> <td style="text-align: right">41.83</td> <td style="text-align: right">50.86</td> <td style="text-align: right">45.21</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0.3</code></td> <td style="text-align: right">689</td> <td style="text-align: right">86.45</td> <td style="text-align: right">89.44</td> <td style="text-align: right">92.51</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.5</code></td> <td style="text-align: right">519825</td> <td style="text-align: right">5.46</td> <td style="text-align: right">9.49</td> <td style="text-align: right">6.96</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.1</code></td> <td style="text-align: right">470400</td> <td style="text-align: right">7.37</td> <td style="text-align: right">9.88</td> <td style="text-align: right">7.57</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.87.0</code></td> <td style="text-align: right">469725</td> <td style="text-align: right">6.34</td> <td style="text-align: right">11.19</td> <td style="text-align: right">8.14</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">436800</td> <td style="text-align: right">7.58</td> <td style="text-align: right">13.19</td> <td style="text-align: right">9.7</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">365490</td> <td style="text-align: right">9.94</td> <td style="text-align: right">17.77</td> <td style="text-align: right">12.9</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">349425</td> <td style="text-align: right">11.85</td> <td style="text-align: right">13.64</td> <td style="text-align: right">12.29</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.4.5</code></td> <td style="text-align: right">328275</td> <td style="text-align: right">18.18</td> <td style="text-align: right">22.85</td> <td style="text-align: right">19.69</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.75.0</code></td> <td style="text-align: right">255615</td> <td style="text-align: right">12.48</td> <td style="text-align: right">22.29</td> <td style="text-align: right">16.11</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">209310</td> <td style="text-align: right">17.23</td> <td style="text-align: right">17.47</td> <td style="text-align: right">17.31</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">121185</td> <td style="text-align: right">24.53</td> <td style="text-align: right">24.73</td> <td style="text-align: right">24.59</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.3</code></td> <td style="text-align: right">109755</td> <td style="text-align: right">28.36</td> <td style="text-align: right">29.24</td> <td style="text-align: right">28.37</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0.3</code></td> <td style="text-align: right">38610</td> <td style="text-align: right">71.15</td> <td style="text-align: right">75.81</td> <td style="text-align: right">76.2</td> </tr> </tbody> </table>Kirill KlenovResults (2021-12-27)2021-12-27T00:00:00+00:002021-12-27T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/12/27/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','baize','emmett','fastapi','aiohttp','tornado','quart','sanic','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['17085','14801','14133','13154','12233','12200','8834','6419','3073','2969','1511','900',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['9393','9323','9101','7198','6490','5874','5632','3986','2457','1925','1427','800',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['5051','3914','3161','2402','2142','1926','1913','1910','1572','1270','1186','614',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.2</code></td> <td style="text-align: right">17085</td> <td style="text-align: right">3.07</td> <td style="text-align: right">4.89</td> <td style="text-align: right">3.71</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.3</code></td> <td style="text-align: right">14801</td> <td style="text-align: right">3.56</td> <td style="text-align: right">5.58</td> <td style="text-align: right">4.30</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">14133</td> <td style="text-align: right">3.63</td> <td style="text-align: right">6.01</td> <td style="text-align: right">4.49</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.14.1</code></td> <td style="text-align: right">13154</td> <td style="text-align: right">3.98</td> <td style="text-align: right">6.37</td> <td style="text-align: right">4.83</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">12233</td> <td style="text-align: right">4.32</td> <td style="text-align: right">6.84</td> <td style="text-align: right">5.19</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">12200</td> <td style="text-align: right">4.20</td> <td style="text-align: right">6.93</td> <td style="text-align: right">5.21</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.1</code></td> <td style="text-align: right">8834</td> <td style="text-align: right">5.78</td> <td style="text-align: right">9.64</td> <td style="text-align: right">7.21</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">6419</td> <td style="text-align: right">9.74</td> <td style="text-align: right">9.97</td> <td style="text-align: right">9.97</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.2</code></td> <td style="text-align: right">3073</td> <td style="text-align: right">21.34</td> <td style="text-align: right">22.30</td> <td style="text-align: right">20.82</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2969</td> <td style="text-align: right">21.59</td> <td style="text-align: right">21.86</td> <td style="text-align: right">21.56</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.0</code></td> <td style="text-align: right">1511</td> <td style="text-align: right">31.88</td> <td style="text-align: right">59.87</td> <td style="text-align: right">42.29</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0</code></td> <td style="text-align: right">900</td> <td style="text-align: right">65.57</td> <td style="text-align: right">79.01</td> <td style="text-align: right">71.02</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.2</code></td> <td style="text-align: right">9393</td> <td style="text-align: right">5.37</td> <td style="text-align: right">9.13</td> <td style="text-align: right">6.78</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.3</code></td> <td style="text-align: right">9323</td> <td style="text-align: right">5.47</td> <td style="text-align: right">9.16</td> <td style="text-align: right">6.83</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">9101</td> <td style="text-align: right">5.54</td> <td style="text-align: right">9.53</td> <td style="text-align: right">6.99</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">7198</td> <td style="text-align: right">7.06</td> <td style="text-align: right">11.91</td> <td style="text-align: right">8.86</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">6490</td> <td style="text-align: right">7.68</td> <td style="text-align: right">13.06</td> <td style="text-align: right">9.93</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.14.1</code></td> <td style="text-align: right">5874</td> <td style="text-align: right">11.08</td> <td style="text-align: right">11.44</td> <td style="text-align: right">10.87</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.1</code></td> <td style="text-align: right">5632</td> <td style="text-align: right">8.81</td> <td style="text-align: right">15.61</td> <td style="text-align: right">11.33</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">3986</td> <td style="text-align: right">15.84</td> <td style="text-align: right">16.08</td> <td style="text-align: right">16.08</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2457</td> <td style="text-align: right">26.01</td> <td style="text-align: right">26.34</td> <td style="text-align: right">26.05</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.2</code></td> <td style="text-align: right">1925</td> <td style="text-align: right">32.96</td> <td style="text-align: right">33.77</td> <td style="text-align: right">33.22</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.0</code></td> <td style="text-align: right">1427</td> <td style="text-align: right">34.55</td> <td style="text-align: right">63.80</td> <td style="text-align: right">44.79</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0</code></td> <td style="text-align: right">800</td> <td style="text-align: right">74.32</td> <td style="text-align: right">88.01</td> <td style="text-align: right">79.89</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.2</code></td> <td style="text-align: right">5051</td> <td style="text-align: right">9.98</td> <td style="text-align: right">17.19</td> <td style="text-align: right">12.64</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.3</code></td> <td style="text-align: right">3914</td> <td style="text-align: right">13.24</td> <td style="text-align: right">21.83</td> <td style="text-align: right">16.36</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3161</td> <td style="text-align: right">16.65</td> <td style="text-align: right">26.87</td> <td style="text-align: right">20.30</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.14.1</code></td> <td style="text-align: right">2402</td> <td style="text-align: right">26.02</td> <td style="text-align: right">29.43</td> <td style="text-align: right">26.64</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">2142</td> <td style="text-align: right">34.13</td> <td style="text-align: right">38.92</td> <td style="text-align: right">29.82</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">1926</td> <td style="text-align: right">32.94</td> <td style="text-align: right">33.21</td> <td style="text-align: right">33.22</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">1913</td> <td style="text-align: right">33.49</td> <td style="text-align: right">33.82</td> <td style="text-align: right">33.44</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.1</code></td> <td style="text-align: right">1910</td> <td style="text-align: right">38.28</td> <td style="text-align: right">43.16</td> <td style="text-align: right">33.44</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.2</code></td> <td style="text-align: right">1572</td> <td style="text-align: right">40.84</td> <td style="text-align: right">41.99</td> <td style="text-align: right">40.67</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">1270</td> <td style="text-align: right">47.26</td> <td style="text-align: right">55.91</td> <td style="text-align: right">50.31</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.0</code></td> <td style="text-align: right">1186</td> <td style="text-align: right">42.27</td> <td style="text-align: right">75.83</td> <td style="text-align: right">53.86</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0</code></td> <td style="text-align: right">614</td> <td style="text-align: right">97.99</td> <td style="text-align: right">104.67</td> <td style="text-align: right">104.02</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.2</code></td> <td style="text-align: right">472935</td> <td style="text-align: right">6.14</td> <td style="text-align: right">10.4</td> <td style="text-align: right">7.71</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.3</code></td> <td style="text-align: right">420570</td> <td style="text-align: right">7.42</td> <td style="text-align: right">12.19</td> <td style="text-align: right">9.16</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">395925</td> <td style="text-align: right">8.61</td> <td style="text-align: right">14.14</td> <td style="text-align: right">10.59</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.17.1</code></td> <td style="text-align: right">323595</td> <td style="text-align: right">15.17</td> <td style="text-align: right">19.22</td> <td style="text-align: right">14.62</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.14.1</code></td> <td style="text-align: right">321450</td> <td style="text-align: right">13.69</td> <td style="text-align: right">15.75</td> <td style="text-align: right">14.11</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">299400</td> <td style="text-align: right">19.71</td> <td style="text-align: right">25.3</td> <td style="text-align: right">21.82</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.1</code></td> <td style="text-align: right">245640</td> <td style="text-align: right">17.62</td> <td style="text-align: right">22.8</td> <td style="text-align: right">17.33</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.1</code></td> <td style="text-align: right">184965</td> <td style="text-align: right">19.51</td> <td style="text-align: right">19.75</td> <td style="text-align: right">19.76</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">110085</td> <td style="text-align: right">27.03</td> <td style="text-align: right">27.34</td> <td style="text-align: right">27.02</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.16.2</code></td> <td style="text-align: right">98550</td> <td style="text-align: right">31.71</td> <td style="text-align: right">32.69</td> <td style="text-align: right">31.57</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.12.0</code></td> <td style="text-align: right">61860</td> <td style="text-align: right">36.23</td> <td style="text-align: right">66.5</td> <td style="text-align: right">46.98</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">4.0</code></td> <td style="text-align: right">34710</td> <td style="text-align: right">79.29</td> <td style="text-align: right">90.56</td> <td style="text-align: right">84.98</td> </tr> </tbody> </table>Kirill KlenovResults (2021-11-02)2021-11-02T00:00:00+00:002021-11-02T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/11/02/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','baize','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['18312','16350','15212','13746','13505','13085','9570','8684','7292','3423','3318','1883',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10490','10346','9659','8011','7433','6797','6488','6062','4658','2860','2158','1581',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['5699','4398','3982','3471','2702','2435','2253','2178','2121','1775','1455','996',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.0</code></td> <td style="text-align: right">18312</td> <td style="text-align: right">2.96</td> <td style="text-align: right">4.47</td> <td style="text-align: right">3.47</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">16350</td> <td style="text-align: right">3.37</td> <td style="text-align: right">4.98</td> <td style="text-align: right">3.90</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">15212</td> <td style="text-align: right">3.43</td> <td style="text-align: right">5.50</td> <td style="text-align: right">4.18</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12.1</code></td> <td style="text-align: right">13746</td> <td style="text-align: right">3.92</td> <td style="text-align: right">5.95</td> <td style="text-align: right">4.63</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">13505</td> <td style="text-align: right">3.84</td> <td style="text-align: right">6.12</td> <td style="text-align: right">4.71</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">13085</td> <td style="text-align: right">3.96</td> <td style="text-align: right">6.34</td> <td style="text-align: right">4.86</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">9570</td> <td style="text-align: right">5.17</td> <td style="text-align: right">8.86</td> <td style="text-align: right">6.66</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">8684</td> <td style="text-align: right">5.77</td> <td style="text-align: right">9.57</td> <td style="text-align: right">7.41</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.0</code></td> <td style="text-align: right">7292</td> <td style="text-align: right">8.57</td> <td style="text-align: right">8.71</td> <td style="text-align: right">8.78</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3423</td> <td style="text-align: right">19.27</td> <td style="text-align: right">19.86</td> <td style="text-align: right">18.68</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3318</td> <td style="text-align: right">18.93</td> <td style="text-align: right">19.11</td> <td style="text-align: right">19.29</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.9</code></td> <td style="text-align: right">1883</td> <td style="text-align: right">33.61</td> <td style="text-align: right">36.74</td> <td style="text-align: right">34.28</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.0</code></td> <td style="text-align: right">10490</td> <td style="text-align: right">4.77</td> <td style="text-align: right">8.20</td> <td style="text-align: right">6.08</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">10346</td> <td style="text-align: right">4.83</td> <td style="text-align: right">8.20</td> <td style="text-align: right">6.15</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">9659</td> <td style="text-align: right">7.04</td> <td style="text-align: right">8.24</td> <td style="text-align: right">6.63</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">8011</td> <td style="text-align: right">6.20</td> <td style="text-align: right">10.63</td> <td style="text-align: right">7.96</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">7433</td> <td style="text-align: right">6.59</td> <td style="text-align: right">11.35</td> <td style="text-align: right">8.63</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">6797</td> <td style="text-align: right">9.51</td> <td style="text-align: right">11.57</td> <td style="text-align: right">9.53</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12.1</code></td> <td style="text-align: right">6488</td> <td style="text-align: right">10.07</td> <td style="text-align: right">10.32</td> <td style="text-align: right">9.86</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">6062</td> <td style="text-align: right">10.68</td> <td style="text-align: right">11.54</td> <td style="text-align: right">10.55</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.0</code></td> <td style="text-align: right">4658</td> <td style="text-align: right">13.49</td> <td style="text-align: right">13.94</td> <td style="text-align: right">13.74</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2860</td> <td style="text-align: right">22.26</td> <td style="text-align: right">22.41</td> <td style="text-align: right">22.38</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2158</td> <td style="text-align: right">29.07</td> <td style="text-align: right">29.61</td> <td style="text-align: right">29.65</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.9</code></td> <td style="text-align: right">1581</td> <td style="text-align: right">38.48</td> <td style="text-align: right">43.17</td> <td style="text-align: right">40.44</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.0</code></td> <td style="text-align: right">5699</td> <td style="text-align: right">8.80</td> <td style="text-align: right">15.31</td> <td style="text-align: right">11.27</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">4398</td> <td style="text-align: right">11.24</td> <td style="text-align: right">20.03</td> <td style="text-align: right">14.58</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">3982</td> <td style="text-align: right">12.29</td> <td style="text-align: right">21.48</td> <td style="text-align: right">16.09</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3471</td> <td style="text-align: right">18.04</td> <td style="text-align: right">22.77</td> <td style="text-align: right">18.59</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12.1</code></td> <td style="text-align: right">2702</td> <td style="text-align: right">22.74</td> <td style="text-align: right">25.60</td> <td style="text-align: right">23.67</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">2435</td> <td style="text-align: right">26.58</td> <td style="text-align: right">35.24</td> <td style="text-align: right">26.27</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.0</code></td> <td style="text-align: right">2253</td> <td style="text-align: right">28.21</td> <td style="text-align: right">28.34</td> <td style="text-align: right">28.49</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">2178</td> <td style="text-align: right">30.26</td> <td style="text-align: right">39.16</td> <td style="text-align: right">29.35</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2121</td> <td style="text-align: right">30.05</td> <td style="text-align: right">30.16</td> <td style="text-align: right">30.17</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1775</td> <td style="text-align: right">35.51</td> <td style="text-align: right">36.27</td> <td style="text-align: right">36.15</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">1455</td> <td style="text-align: right">40.99</td> <td style="text-align: right">48.11</td> <td style="text-align: right">44.10</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.9</code></td> <td style="text-align: right">996</td> <td style="text-align: right">63.49</td> <td style="text-align: right">70.47</td> <td style="text-align: right">64.26</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.2.0</code></td> <td style="text-align: right">517515</td> <td style="text-align: right">5.51</td> <td style="text-align: right">9.33</td> <td style="text-align: right">6.94</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">466410</td> <td style="text-align: right">6.48</td> <td style="text-align: right">11.07</td> <td style="text-align: right">8.21</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">425130</td> <td style="text-align: right">9.5</td> <td style="text-align: right">12.17</td> <td style="text-align: right">9.8</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">359265</td> <td style="text-align: right">12.21</td> <td style="text-align: right">17.33</td> <td style="text-align: right">12.98</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12.1</code></td> <td style="text-align: right">344040</td> <td style="text-align: right">12.24</td> <td style="text-align: right">13.96</td> <td style="text-align: right">12.72</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.2</code></td> <td style="text-align: right">320055</td> <td style="text-align: right">18.15</td> <td style="text-align: right">22.01</td> <td style="text-align: right">19.5</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">301485</td> <td style="text-align: right">8.22</td> <td style="text-align: right">14.13</td> <td style="text-align: right">10.71</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">267150</td> <td style="text-align: right">15.37</td> <td style="text-align: right">19.85</td> <td style="text-align: right">15.52</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.8.0</code></td> <td style="text-align: right">213045</td> <td style="text-align: right">16.76</td> <td style="text-align: right">17.0</td> <td style="text-align: right">17.0</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">124485</td> <td style="text-align: right">23.75</td> <td style="text-align: right">23.89</td> <td style="text-align: right">23.95</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">110340</td> <td style="text-align: right">27.95</td> <td style="text-align: right">28.58</td> <td style="text-align: right">28.16</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.9</code></td> <td style="text-align: right">66900</td> <td style="text-align: right">45.19</td> <td style="text-align: right">50.13</td> <td style="text-align: right">46.33</td> </tr> </tbody> </table>Kirill KlenovResults (2021-10-21)2021-10-21T00:00:00+00:002021-10-21T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/10/21/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','baize','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['18280','16016','14747','13481','12981','12580','9140','8547','7156','3217','3206','1744',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10142','10083','9719','7781','7179','6803','6277','6229','4363','2668','2065','1422',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['5479','4272','3905','3423','2472','2362','2143','2127','2034','1659','1354','934',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">18280</td> <td style="text-align: right">2.92</td> <td style="text-align: right">4.56</td> <td style="text-align: right">3.48</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">16016</td> <td style="text-align: right">3.35</td> <td style="text-align: right">5.17</td> <td style="text-align: right">3.97</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">14747</td> <td style="text-align: right">3.50</td> <td style="text-align: right">5.69</td> <td style="text-align: right">4.32</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12</code></td> <td style="text-align: right">13481</td> <td style="text-align: right">3.83</td> <td style="text-align: right">6.20</td> <td style="text-align: right">4.72</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">12981</td> <td style="text-align: right">3.99</td> <td style="text-align: right">6.31</td> <td style="text-align: right">4.92</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">12580</td> <td style="text-align: right">4.10</td> <td style="text-align: right">6.63</td> <td style="text-align: right">5.06</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">9140</td> <td style="text-align: right">5.59</td> <td style="text-align: right">9.17</td> <td style="text-align: right">6.98</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">8547</td> <td style="text-align: right">6.00</td> <td style="text-align: right">9.67</td> <td style="text-align: right">7.52</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">7156</td> <td style="text-align: right">8.89</td> <td style="text-align: right">9.02</td> <td style="text-align: right">8.95</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3217</td> <td style="text-align: right">19.76</td> <td style="text-align: right">20.06</td> <td style="text-align: right">19.90</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3206</td> <td style="text-align: right">19.87</td> <td style="text-align: right">21.77</td> <td style="text-align: right">19.99</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.8</code></td> <td style="text-align: right">1744</td> <td style="text-align: right">34.93</td> <td style="text-align: right">40.11</td> <td style="text-align: right">36.88</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">10142</td> <td style="text-align: right">5.02</td> <td style="text-align: right">8.45</td> <td style="text-align: right">6.27</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">10083</td> <td style="text-align: right">5.09</td> <td style="text-align: right">8.41</td> <td style="text-align: right">6.32</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">9719</td> <td style="text-align: right">5.27</td> <td style="text-align: right">8.96</td> <td style="text-align: right">6.55</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">7781</td> <td style="text-align: right">6.54</td> <td style="text-align: right">11.12</td> <td style="text-align: right">8.19</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">7179</td> <td style="text-align: right">6.99</td> <td style="text-align: right">12.09</td> <td style="text-align: right">8.94</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">6803</td> <td style="text-align: right">7.33</td> <td style="text-align: right">12.42</td> <td style="text-align: right">9.59</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12</code></td> <td style="text-align: right">6277</td> <td style="text-align: right">10.23</td> <td style="text-align: right">10.71</td> <td style="text-align: right">10.18</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">6229</td> <td style="text-align: right">8.00</td> <td style="text-align: right">13.90</td> <td style="text-align: right">10.25</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4363</td> <td style="text-align: right">14.65</td> <td style="text-align: right">14.93</td> <td style="text-align: right">14.67</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2668</td> <td style="text-align: right">23.78</td> <td style="text-align: right">23.96</td> <td style="text-align: right">24.01</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2065</td> <td style="text-align: right">29.96</td> <td style="text-align: right">32.38</td> <td style="text-align: right">31.05</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.8</code></td> <td style="text-align: right">1422</td> <td style="text-align: right">43.04</td> <td style="text-align: right">49.50</td> <td style="text-align: right">44.96</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">5479</td> <td style="text-align: right">9.63</td> <td style="text-align: right">15.56</td> <td style="text-align: right">11.67</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">4272</td> <td style="text-align: right">12.22</td> <td style="text-align: right">20.39</td> <td style="text-align: right">15.08</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">3905</td> <td style="text-align: right">13.39</td> <td style="text-align: right">21.69</td> <td style="text-align: right">16.46</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3423</td> <td style="text-align: right">15.49</td> <td style="text-align: right">24.81</td> <td style="text-align: right">18.80</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12</code></td> <td style="text-align: right">2472</td> <td style="text-align: right">24.99</td> <td style="text-align: right">28.25</td> <td style="text-align: right">25.88</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">2362</td> <td style="text-align: right">21.67</td> <td style="text-align: right">37.48</td> <td style="text-align: right">27.17</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2143</td> <td style="text-align: right">29.58</td> <td style="text-align: right">29.76</td> <td style="text-align: right">29.87</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">2127</td> <td style="text-align: right">25.19</td> <td style="text-align: right">39.96</td> <td style="text-align: right">30.08</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2034</td> <td style="text-align: right">31.36</td> <td style="text-align: right">31.61</td> <td style="text-align: right">31.46</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1659</td> <td style="text-align: right">37.33</td> <td style="text-align: right">40.91</td> <td style="text-align: right">38.58</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">1354</td> <td style="text-align: right">44.27</td> <td style="text-align: right">49.71</td> <td style="text-align: right">47.31</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.8</code></td> <td style="text-align: right">934</td> <td style="text-align: right">66.96</td> <td style="text-align: right">75.72</td> <td style="text-align: right">68.45</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">508515</td> <td style="text-align: right">5.86</td> <td style="text-align: right">9.52</td> <td style="text-align: right">7.14</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.86.0</code></td> <td style="text-align: right">455565</td> <td style="text-align: right">6.89</td> <td style="text-align: right">11.32</td> <td style="text-align: right">8.46</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">418335</td> <td style="text-align: right">8.09</td> <td style="text-align: right">13.15</td> <td style="text-align: right">9.89</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">346860</td> <td style="text-align: right">10.73</td> <td style="text-align: right">18.3</td> <td style="text-align: right">13.43</td> </tr> <tr> <td><a href="https://pypi.org/project/baize/">baize</a> <code class="language-plaintext highlighter-rouge">0.12</code></td> <td style="text-align: right">333450</td> <td style="text-align: right">13.02</td> <td style="text-align: right">15.05</td> <td style="text-align: right">13.59</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">311055</td> <td style="text-align: right">18.57</td> <td style="text-align: right">22.92</td> <td style="text-align: right">20.65</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.9.1</code></td> <td style="text-align: right">294465</td> <td style="text-align: right">8.79</td> <td style="text-align: right">14.48</td> <td style="text-align: right">10.97</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.70.0</code></td> <td style="text-align: right">262440</td> <td style="text-align: right">12.93</td> <td style="text-align: right">21.01</td> <td style="text-align: right">15.77</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">204930</td> <td style="text-align: right">17.71</td> <td style="text-align: right">17.9</td> <td style="text-align: right">17.83</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">118785</td> <td style="text-align: right">24.97</td> <td style="text-align: right">25.21</td> <td style="text-align: right">25.12</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">103950</td> <td style="text-align: right">29.05</td> <td style="text-align: right">31.69</td> <td style="text-align: right">29.87</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.8</code></td> <td style="text-align: right">61500</td> <td style="text-align: right">48.31</td> <td style="text-align: right">55.11</td> <td style="text-align: right">50.1</td> </tr> </tbody> </table>Kirill KlenovResults (2021-09-01)2021-09-01T00:00:00+00:002021-09-01T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/09/01/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['18871','16612','15754','13725','13516','9709','8866','7457','3338','3310','1852',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10385','10309','10212','7966','7432','7211','6260','4564','2783','2095','1566',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['5871','4483','4143','3743','2432','2235','2224','2218','1806','1477','986',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">18871</td> <td style="text-align: right">3.05</td> <td style="text-align: right">4.31</td> <td style="text-align: right">3.36</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.5</code></td> <td style="text-align: right">16612</td> <td style="text-align: right">3.49</td> <td style="text-align: right">4.93</td> <td style="text-align: right">3.81</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">15754</td> <td style="text-align: right">4.07</td> <td style="text-align: right">5.17</td> <td style="text-align: right">4.02</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">13725</td> <td style="text-align: right">4.22</td> <td style="text-align: right">6.01</td> <td style="text-align: right">4.63</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">13516</td> <td style="text-align: right">4.17</td> <td style="text-align: right">6.10</td> <td style="text-align: right">4.70</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.68.1</code></td> <td style="text-align: right">9709</td> <td style="text-align: right">5.86</td> <td style="text-align: right">8.56</td> <td style="text-align: right">6.56</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.2</code></td> <td style="text-align: right">8866</td> <td style="text-align: right">6.06</td> <td style="text-align: right">9.42</td> <td style="text-align: right">7.22</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">7457</td> <td style="text-align: right">8.58</td> <td style="text-align: right">8.84</td> <td style="text-align: right">8.58</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3338</td> <td style="text-align: right">19.26</td> <td style="text-align: right">20.61</td> <td style="text-align: right">19.15</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3310</td> <td style="text-align: right">19.15</td> <td style="text-align: right">19.80</td> <td style="text-align: right">19.33</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.6</code></td> <td style="text-align: right">1852</td> <td style="text-align: right">34.37</td> <td style="text-align: right">37.97</td> <td style="text-align: right">34.65</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">10385</td> <td style="text-align: right">5.20</td> <td style="text-align: right">8.05</td> <td style="text-align: right">6.13</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">10309</td> <td style="text-align: right">6.09</td> <td style="text-align: right">8.03</td> <td style="text-align: right">6.17</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.5</code></td> <td style="text-align: right">10212</td> <td style="text-align: right">5.24</td> <td style="text-align: right">8.21</td> <td style="text-align: right">6.23</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">7966</td> <td style="text-align: right">6.66</td> <td style="text-align: right">10.55</td> <td style="text-align: right">8.00</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.2</code></td> <td style="text-align: right">7432</td> <td style="text-align: right">6.97</td> <td style="text-align: right">11.28</td> <td style="text-align: right">8.60</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">7211</td> <td style="text-align: right">7.22</td> <td style="text-align: right">11.54</td> <td style="text-align: right">8.93</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.68.1</code></td> <td style="text-align: right">6260</td> <td style="text-align: right">8.49</td> <td style="text-align: right">13.46</td> <td style="text-align: right">10.19</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4564</td> <td style="text-align: right">14.05</td> <td style="text-align: right">14.38</td> <td style="text-align: right">14.03</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2783</td> <td style="text-align: right">22.95</td> <td style="text-align: right">23.63</td> <td style="text-align: right">23.00</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2095</td> <td style="text-align: right">30.16</td> <td style="text-align: right">31.36</td> <td style="text-align: right">30.53</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.6</code></td> <td style="text-align: right">1566</td> <td style="text-align: right">41.41</td> <td style="text-align: right">44.99</td> <td style="text-align: right">40.82</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">5871</td> <td style="text-align: right">9.10</td> <td style="text-align: right">14.32</td> <td style="text-align: right">10.91</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.5</code></td> <td style="text-align: right">4483</td> <td style="text-align: right">14.01</td> <td style="text-align: right">18.75</td> <td style="text-align: right">14.28</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.2</code></td> <td style="text-align: right">4143</td> <td style="text-align: right">13.95</td> <td style="text-align: right">20.19</td> <td style="text-align: right">15.44</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3743</td> <td style="text-align: right">17.80</td> <td style="text-align: right">22.05</td> <td style="text-align: right">17.19</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">2432</td> <td style="text-align: right">29.97</td> <td style="text-align: right">33.69</td> <td style="text-align: right">26.25</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2235</td> <td style="text-align: right">28.52</td> <td style="text-align: right">29.20</td> <td style="text-align: right">28.63</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2224</td> <td style="text-align: right">28.67</td> <td style="text-align: right">29.34</td> <td style="text-align: right">28.77</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.68.1</code></td> <td style="text-align: right">2218</td> <td style="text-align: right">32.63</td> <td style="text-align: right">36.66</td> <td style="text-align: right">28.81</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1806</td> <td style="text-align: right">35.19</td> <td style="text-align: right">36.32</td> <td style="text-align: right">35.42</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">1477</td> <td style="text-align: right">40.70</td> <td style="text-align: right">48.60</td> <td style="text-align: right">43.29</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.6</code></td> <td style="text-align: right">986</td> <td style="text-align: right">65.19</td> <td style="text-align: right">72.05</td> <td style="text-align: right">64.80</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">526905</td> <td style="text-align: right">5.78</td> <td style="text-align: right">8.89</td> <td style="text-align: right">6.8</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.5</code></td> <td style="text-align: right">469605</td> <td style="text-align: right">7.58</td> <td style="text-align: right">10.63</td> <td style="text-align: right">8.11</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">447090</td> <td style="text-align: right">9.32</td> <td style="text-align: right">11.75</td> <td style="text-align: right">9.13</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">361845</td> <td style="text-align: right">13.62</td> <td style="text-align: right">16.75</td> <td style="text-align: right">12.96</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.3.1</code></td> <td style="text-align: right">333060</td> <td style="text-align: right">17.36</td> <td style="text-align: right">22.08</td> <td style="text-align: right">18.97</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.2</code></td> <td style="text-align: right">306615</td> <td style="text-align: right">8.99</td> <td style="text-align: right">13.63</td> <td style="text-align: right">10.42</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.68.1</code></td> <td style="text-align: right">272805</td> <td style="text-align: right">15.66</td> <td style="text-align: right">19.56</td> <td style="text-align: right">15.19</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">213840</td> <td style="text-align: right">17.05</td> <td style="text-align: right">17.47</td> <td style="text-align: right">17.08</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">124755</td> <td style="text-align: right">23.59</td> <td style="text-align: right">24.26</td> <td style="text-align: right">23.7</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">108585</td> <td style="text-align: right">28.2</td> <td style="text-align: right">29.43</td> <td style="text-align: right">28.37</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.6</code></td> <td style="text-align: right">66060</td> <td style="text-align: right">46.99</td> <td style="text-align: right">51.67</td> <td style="text-align: right">46.76</td> </tr> </tbody> </table>Kirill KlenovResults (2021-08-02)2021-08-02T00:00:00+00:002021-08-02T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/08/02/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['19432','17250','16127','14000','13977','9929','9308','7815','3522','3422','1977',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10836','10574','10470','8298','7850','7383','6441','4884','2919','2208','1656',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['6118','4634','4434','3780','2593','2438','2275','2251','1864','1603','1047',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">19432</td> <td style="text-align: right">2.70</td> <td style="text-align: right">4.27</td> <td style="text-align: right">3.26</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.1</code></td> <td style="text-align: right">17250</td> <td style="text-align: right">3.08</td> <td style="text-align: right">4.78</td> <td style="text-align: right">3.67</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">16127</td> <td style="text-align: right">3.24</td> <td style="text-align: right">5.15</td> <td style="text-align: right">3.93</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">14000</td> <td style="text-align: right">3.61</td> <td style="text-align: right">6.00</td> <td style="text-align: right">4.54</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">13977</td> <td style="text-align: right">3.63</td> <td style="text-align: right">6.04</td> <td style="text-align: right">4.54</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.67.0</code></td> <td style="text-align: right">9929</td> <td style="text-align: right">5.06</td> <td style="text-align: right">8.49</td> <td style="text-align: right">6.41</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">9308</td> <td style="text-align: right">5.41</td> <td style="text-align: right">8.96</td> <td style="text-align: right">6.89</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">7815</td> <td style="text-align: right">8.14</td> <td style="text-align: right">8.23</td> <td style="text-align: right">8.19</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3522</td> <td style="text-align: right">18.70</td> <td style="text-align: right">19.41</td> <td style="text-align: right">18.15</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3422</td> <td style="text-align: right">18.68</td> <td style="text-align: right">18.80</td> <td style="text-align: right">18.71</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">1977</td> <td style="text-align: right">32.21</td> <td style="text-align: right">35.93</td> <td style="text-align: right">32.38</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">10836</td> <td style="text-align: right">4.67</td> <td style="text-align: right">7.84</td> <td style="text-align: right">5.87</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.1</code></td> <td style="text-align: right">10574</td> <td style="text-align: right">4.66</td> <td style="text-align: right">8.10</td> <td style="text-align: right">6.02</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">10470</td> <td style="text-align: right">4.76</td> <td style="text-align: right">8.11</td> <td style="text-align: right">6.08</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">8298</td> <td style="text-align: right">5.92</td> <td style="text-align: right">10.28</td> <td style="text-align: right">7.68</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">7850</td> <td style="text-align: right">6.23</td> <td style="text-align: right">10.67</td> <td style="text-align: right">8.16</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">7383</td> <td style="text-align: right">6.53</td> <td style="text-align: right">11.44</td> <td style="text-align: right">8.76</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.67.0</code></td> <td style="text-align: right">6441</td> <td style="text-align: right">7.59</td> <td style="text-align: right">13.31</td> <td style="text-align: right">9.90</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4884</td> <td style="text-align: right">13.11</td> <td style="text-align: right">13.26</td> <td style="text-align: right">13.10</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2919</td> <td style="text-align: right">21.96</td> <td style="text-align: right">22.07</td> <td style="text-align: right">21.93</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2208</td> <td style="text-align: right">28.58</td> <td style="text-align: right">29.09</td> <td style="text-align: right">28.97</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">1656</td> <td style="text-align: right">39.50</td> <td style="text-align: right">42.58</td> <td style="text-align: right">38.60</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">6118</td> <td style="text-align: right">8.03</td> <td style="text-align: right">14.20</td> <td style="text-align: right">10.45</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.1</code></td> <td style="text-align: right">4634</td> <td style="text-align: right">10.75</td> <td style="text-align: right">18.89</td> <td style="text-align: right">13.78</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">4434</td> <td style="text-align: right">11.05</td> <td style="text-align: right">19.37</td> <td style="text-align: right">14.44</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3780</td> <td style="text-align: right">13.30</td> <td style="text-align: right">22.46</td> <td style="text-align: right">17.01</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">2593</td> <td style="text-align: right">19.15</td> <td style="text-align: right">33.15</td> <td style="text-align: right">24.64</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2438</td> <td style="text-align: right">26.23</td> <td style="text-align: right">26.37</td> <td style="text-align: right">26.25</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.67.0</code></td> <td style="text-align: right">2275</td> <td style="text-align: right">22.18</td> <td style="text-align: right">37.71</td> <td style="text-align: right">28.09</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2251</td> <td style="text-align: right">28.38</td> <td style="text-align: right">28.49</td> <td style="text-align: right">28.43</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1864</td> <td style="text-align: right">34.31</td> <td style="text-align: right">35.01</td> <td style="text-align: right">34.31</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">1603</td> <td style="text-align: right">36.49</td> <td style="text-align: right">45.73</td> <td style="text-align: right">39.90</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">1047</td> <td style="text-align: right">60.93</td> <td style="text-align: right">67.76</td> <td style="text-align: right">61.00</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.9</code></td> <td style="text-align: right">545790</td> <td style="text-align: right">5.13</td> <td style="text-align: right">8.77</td> <td style="text-align: right">6.53</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.84.1</code></td> <td style="text-align: right">486870</td> <td style="text-align: right">6.16</td> <td style="text-align: right">10.59</td> <td style="text-align: right">7.82</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">455655</td> <td style="text-align: right">7.1</td> <td style="text-align: right">11.91</td> <td style="text-align: right">9.01</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.16.0</code></td> <td style="text-align: right">373365</td> <td style="text-align: right">9.56</td> <td style="text-align: right">16.48</td> <td style="text-align: right">12.29</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">344445</td> <td style="text-align: right">15.55</td> <td style="text-align: right">21.07</td> <td style="text-align: right">17.73</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">323880</td> <td style="text-align: right">7.56</td> <td style="text-align: right">13.0</td> <td style="text-align: right">9.83</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.67.0</code></td> <td style="text-align: right">279675</td> <td style="text-align: right">11.61</td> <td style="text-align: right">19.84</td> <td style="text-align: right">14.8</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">227055</td> <td style="text-align: right">15.83</td> <td style="text-align: right">15.95</td> <td style="text-align: right">15.85</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">128880</td> <td style="text-align: right">23.01</td> <td style="text-align: right">23.12</td> <td style="text-align: right">23.02</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">113910</td> <td style="text-align: right">27.2</td> <td style="text-align: right">27.84</td> <td style="text-align: right">27.14</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">70200</td> <td style="text-align: right">44.21</td> <td style="text-align: right">48.76</td> <td style="text-align: right">43.99</td> </tr> </tbody> </table>Kirill KlenovResults (2021-07-06)2021-07-06T00:00:00+00:002021-07-06T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/07/06/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['19405','19210','16180','15733','14041','11073','9266','7777','3534','3508','2130',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10812','10635','10515','8248','8084','7758','6440','4690','2947','2159','1659',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['6146','4722','4331','3854','2548','2377','2277','2263','1845','1663','1119',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.83.1</code></td> <td style="text-align: right">19405</td> <td style="text-align: right">3.78</td> <td style="text-align: right">4.04</td> <td style="text-align: right">3.26</td> </tr> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">19210</td> <td style="text-align: right">2.76</td> <td style="text-align: right">4.31</td> <td style="text-align: right">3.30</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">16180</td> <td style="text-align: right">3.17</td> <td style="text-align: right">5.20</td> <td style="text-align: right">3.92</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">15733</td> <td style="text-align: right">4.70</td> <td style="text-align: right">5.15</td> <td style="text-align: right">4.03</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">14041</td> <td style="text-align: right">3.58</td> <td style="text-align: right">6.10</td> <td style="text-align: right">4.53</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.66.0</code></td> <td style="text-align: right">11073</td> <td style="text-align: right">6.88</td> <td style="text-align: right">7.32</td> <td style="text-align: right">5.74</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">9266</td> <td style="text-align: right">5.30</td> <td style="text-align: right">9.04</td> <td style="text-align: right">6.92</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">7777</td> <td style="text-align: right">8.21</td> <td style="text-align: right">8.30</td> <td style="text-align: right">8.23</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3534</td> <td style="text-align: right">18.11</td> <td style="text-align: right">18.21</td> <td style="text-align: right">18.11</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3508</td> <td style="text-align: right">18.83</td> <td style="text-align: right">19.57</td> <td style="text-align: right">18.23</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">2130</td> <td style="text-align: right">29.83</td> <td style="text-align: right">32.95</td> <td style="text-align: right">30.07</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">10812</td> <td style="text-align: right">4.57</td> <td style="text-align: right">7.93</td> <td style="text-align: right">5.88</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.83.1</code></td> <td style="text-align: right">10635</td> <td style="text-align: right">4.60</td> <td style="text-align: right">8.09</td> <td style="text-align: right">5.98</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">10515</td> <td style="text-align: right">4.71</td> <td style="text-align: right">8.22</td> <td style="text-align: right">6.06</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">8248</td> <td style="text-align: right">6.01</td> <td style="text-align: right">10.62</td> <td style="text-align: right">7.73</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">8084</td> <td style="text-align: right">8.97</td> <td style="text-align: right">10.08</td> <td style="text-align: right">8.05</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">7758</td> <td style="text-align: right">6.34</td> <td style="text-align: right">11.16</td> <td style="text-align: right">8.26</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.66.0</code></td> <td style="text-align: right">6440</td> <td style="text-align: right">7.83</td> <td style="text-align: right">13.60</td> <td style="text-align: right">9.91</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4690</td> <td style="text-align: right">13.43</td> <td style="text-align: right">14.08</td> <td style="text-align: right">13.64</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2947</td> <td style="text-align: right">21.71</td> <td style="text-align: right">21.88</td> <td style="text-align: right">21.72</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2159</td> <td style="text-align: right">29.23</td> <td style="text-align: right">29.85</td> <td style="text-align: right">29.63</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">1659</td> <td style="text-align: right">37.52</td> <td style="text-align: right">42.80</td> <td style="text-align: right">38.54</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">6146</td> <td style="text-align: right">8.01</td> <td style="text-align: right">14.27</td> <td style="text-align: right">10.42</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.83.1</code></td> <td style="text-align: right">4722</td> <td style="text-align: right">10.56</td> <td style="text-align: right">18.50</td> <td style="text-align: right">13.61</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">4331</td> <td style="text-align: right">11.29</td> <td style="text-align: right">20.19</td> <td style="text-align: right">14.77</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3854</td> <td style="text-align: right">13.12</td> <td style="text-align: right">22.07</td> <td style="text-align: right">16.69</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">2548</td> <td style="text-align: right">19.42</td> <td style="text-align: right">34.34</td> <td style="text-align: right">25.08</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2377</td> <td style="text-align: right">26.87</td> <td style="text-align: right">27.39</td> <td style="text-align: right">26.90</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.66.0</code></td> <td style="text-align: right">2277</td> <td style="text-align: right">21.51</td> <td style="text-align: right">38.22</td> <td style="text-align: right">28.07</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2263</td> <td style="text-align: right">28.26</td> <td style="text-align: right">28.41</td> <td style="text-align: right">28.28</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1845</td> <td style="text-align: right">34.68</td> <td style="text-align: right">35.42</td> <td style="text-align: right">34.67</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">1663</td> <td style="text-align: right">36.43</td> <td style="text-align: right">42.10</td> <td style="text-align: right">38.46</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">1119</td> <td style="text-align: right">56.80</td> <td style="text-align: right">62.63</td> <td style="text-align: right">57.01</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">542520</td> <td style="text-align: right">5.11</td> <td style="text-align: right">8.84</td> <td style="text-align: right">6.53</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.83.1</code></td> <td style="text-align: right">521430</td> <td style="text-align: right">6.31</td> <td style="text-align: right">10.21</td> <td style="text-align: right">7.62</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">458235</td> <td style="text-align: right">7.0</td> <td style="text-align: right">11.83</td> <td style="text-align: right">8.89</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.15.0</code></td> <td style="text-align: right">397935</td> <td style="text-align: right">10.04</td> <td style="text-align: right">16.7</td> <td style="text-align: right">12.28</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">356820</td> <td style="text-align: right">16.33</td> <td style="text-align: right">19.43</td> <td style="text-align: right">17.01</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.6.0</code></td> <td style="text-align: right">320325</td> <td style="text-align: right">7.64</td> <td style="text-align: right">13.46</td> <td style="text-align: right">9.98</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.66.0</code></td> <td style="text-align: right">296850</td> <td style="text-align: right">12.07</td> <td style="text-align: right">19.71</td> <td style="text-align: right">14.57</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">222660</td> <td style="text-align: right">16.17</td> <td style="text-align: right">16.59</td> <td style="text-align: right">16.26</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">131160</td> <td style="text-align: right">22.69</td> <td style="text-align: right">22.83</td> <td style="text-align: right">22.7</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">112680</td> <td style="text-align: right">27.58</td> <td style="text-align: right">28.28</td> <td style="text-align: right">27.51</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.5</code></td> <td style="text-align: right">73620</td> <td style="text-align: right">41.38</td> <td style="text-align: right">46.13</td> <td style="text-align: right">41.87</td> </tr> </tbody> </table>Kirill KlenovResults (2021-06-22)2021-06-22T00:00:00+00:002021-06-22T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/06/22/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['17127','15098','14061','12342','12232','8726','8171','6886','2769','2727','1660',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['9280','9094','9002','7151','6871','6024','5550','4162','2445','1792','1407',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['4932','3886','3649','3187','2148','2049','1915','1832','1483','1231','904',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">17127</td> <td style="text-align: right">3.23</td> <td style="text-align: right">4.79</td> <td style="text-align: right">3.69</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.80.0</code></td> <td style="text-align: right">15098</td> <td style="text-align: right">3.49</td> <td style="text-align: right">5.52</td> <td style="text-align: right">4.20</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">14061</td> <td style="text-align: right">3.67</td> <td style="text-align: right">5.95</td> <td style="text-align: right">4.51</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">12342</td> <td style="text-align: right">4.17</td> <td style="text-align: right">6.82</td> <td style="text-align: right">5.15</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">12232</td> <td style="text-align: right">4.47</td> <td style="text-align: right">6.79</td> <td style="text-align: right">5.19</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">8726</td> <td style="text-align: right">5.82</td> <td style="text-align: right">9.76</td> <td style="text-align: right">7.29</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">8171</td> <td style="text-align: right">6.36</td> <td style="text-align: right">10.22</td> <td style="text-align: right">7.84</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">6886</td> <td style="text-align: right">9.30</td> <td style="text-align: right">9.50</td> <td style="text-align: right">9.29</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2769</td> <td style="text-align: right">23.02</td> <td style="text-align: right">24.88</td> <td style="text-align: right">23.12</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2727</td> <td style="text-align: right">22.78</td> <td style="text-align: right">24.00</td> <td style="text-align: right">23.47</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1660</td> <td style="text-align: right">38.65</td> <td style="text-align: right">42.10</td> <td style="text-align: right">38.57</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.80.0</code></td> <td style="text-align: right">9280</td> <td style="text-align: right">5.43</td> <td style="text-align: right">9.27</td> <td style="text-align: right">6.86</td> </tr> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">9094</td> <td style="text-align: right">5.84</td> <td style="text-align: right">9.18</td> <td style="text-align: right">7.01</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">9002</td> <td style="text-align: right">5.58</td> <td style="text-align: right">9.57</td> <td style="text-align: right">7.07</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">7151</td> <td style="text-align: right">7.04</td> <td style="text-align: right">12.09</td> <td style="text-align: right">8.91</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">6871</td> <td style="text-align: right">7.23</td> <td style="text-align: right">12.37</td> <td style="text-align: right">9.31</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">6024</td> <td style="text-align: right">8.73</td> <td style="text-align: right">13.73</td> <td style="text-align: right">10.71</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">5550</td> <td style="text-align: right">9.35</td> <td style="text-align: right">15.57</td> <td style="text-align: right">11.49</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4162</td> <td style="text-align: right">15.34</td> <td style="text-align: right">15.61</td> <td style="text-align: right">15.38</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2445</td> <td style="text-align: right">26.11</td> <td style="text-align: right">26.54</td> <td style="text-align: right">26.16</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1792</td> <td style="text-align: right">34.83</td> <td style="text-align: right">36.78</td> <td style="text-align: right">35.70</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1407</td> <td style="text-align: right">46.41</td> <td style="text-align: right">50.06</td> <td style="text-align: right">45.43</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">4932</td> <td style="text-align: right">10.30</td> <td style="text-align: right">17.39</td> <td style="text-align: right">12.95</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.80.0</code></td> <td style="text-align: right">3886</td> <td style="text-align: right">12.83</td> <td style="text-align: right">22.26</td> <td style="text-align: right">16.45</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">3649</td> <td style="text-align: right">14.16</td> <td style="text-align: right">23.34</td> <td style="text-align: right">17.50</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3187</td> <td style="text-align: right">16.55</td> <td style="text-align: right">26.36</td> <td style="text-align: right">20.14</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">2148</td> <td style="text-align: right">25.47</td> <td style="text-align: right">38.99</td> <td style="text-align: right">29.75</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2049</td> <td style="text-align: right">31.18</td> <td style="text-align: right">31.73</td> <td style="text-align: right">31.21</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">1915</td> <td style="text-align: right">38.09</td> <td style="text-align: right">43.03</td> <td style="text-align: right">33.37</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">1832</td> <td style="text-align: right">34.80</td> <td style="text-align: right">35.28</td> <td style="text-align: right">34.94</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1483</td> <td style="text-align: right">42.47</td> <td style="text-align: right">44.78</td> <td style="text-align: right">43.12</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">1231</td> <td style="text-align: right">49.02</td> <td style="text-align: right">57.71</td> <td style="text-align: right">51.92</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">904</td> <td style="text-align: right">69.48</td> <td style="text-align: right">78.94</td> <td style="text-align: right">70.67</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.8</code></td> <td style="text-align: right">467295</td> <td style="text-align: right">6.46</td> <td style="text-align: right">10.45</td> <td style="text-align: right">7.88</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.80.0</code></td> <td style="text-align: right">423960</td> <td style="text-align: right">7.25</td> <td style="text-align: right">12.35</td> <td style="text-align: right">9.17</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">393750</td> <td style="text-align: right">8.6</td> <td style="text-align: right">13.96</td> <td style="text-align: right">10.57</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">324615</td> <td style="text-align: right">12.23</td> <td style="text-align: right">19.3</td> <td style="text-align: right">14.6</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.3</code></td> <td style="text-align: right">292305</td> <td style="text-align: right">20.74</td> <td style="text-align: right">26.08</td> <td style="text-align: right">22.61</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">280365</td> <td style="text-align: right">9.25</td> <td style="text-align: right">15.31</td> <td style="text-align: right">11.55</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">242865</td> <td style="text-align: right">17.75</td> <td style="text-align: right">22.79</td> <td style="text-align: right">17.38</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">196455</td> <td style="text-align: right">18.61</td> <td style="text-align: right">18.95</td> <td style="text-align: right">18.63</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">105060</td> <td style="text-align: right">27.9</td> <td style="text-align: right">28.61</td> <td style="text-align: right">28.19</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">90660</td> <td style="text-align: right">33.44</td> <td style="text-align: right">35.48</td> <td style="text-align: right">33.98</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">59565</td> <td style="text-align: right">51.51</td> <td style="text-align: right">57.03</td> <td style="text-align: right">51.56</td> </tr> </tbody> </table>Kirill KlenovResults (2021-06-14)2021-06-14T00:00:00+00:002021-06-14T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/06/14/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['19097','17129','15966','14029','14026','10014','9330','7869','3520','3472','2036',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['10681','10645','10399','8209','7843','7456','6447','4854','2937','2223','1708',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, { label: 'Upload file (req/s)', data: ['6135','4672','4449','3825','2590','2468','2305','2294','1894','1627','1091',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.7</code></td> <td style="text-align: right">19097</td> <td style="text-align: right">2.76</td> <td style="text-align: right">4.32</td> <td style="text-align: right">3.31</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">17129</td> <td style="text-align: right">3.08</td> <td style="text-align: right">4.85</td> <td style="text-align: right">3.70</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">15966</td> <td style="text-align: right">3.28</td> <td style="text-align: right">5.22</td> <td style="text-align: right">3.97</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">14029</td> <td style="text-align: right">3.72</td> <td style="text-align: right">5.96</td> <td style="text-align: right">4.53</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">14026</td> <td style="text-align: right">3.64</td> <td style="text-align: right">5.96</td> <td style="text-align: right">4.53</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">10014</td> <td style="text-align: right">5.04</td> <td style="text-align: right">8.41</td> <td style="text-align: right">6.36</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">9330</td> <td style="text-align: right">5.29</td> <td style="text-align: right">8.97</td> <td style="text-align: right">6.86</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">7869</td> <td style="text-align: right">8.08</td> <td style="text-align: right">8.25</td> <td style="text-align: right">8.13</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3520</td> <td style="text-align: right">18.88</td> <td style="text-align: right">19.52</td> <td style="text-align: right">18.16</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3472</td> <td style="text-align: right">18.42</td> <td style="text-align: right">18.57</td> <td style="text-align: right">18.43</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">2036</td> <td style="text-align: right">31.48</td> <td style="text-align: right">35.03</td> <td style="text-align: right">31.48</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.7</code></td> <td style="text-align: right">10681</td> <td style="text-align: right">4.63</td> <td style="text-align: right">7.97</td> <td style="text-align: right">5.95</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">10645</td> <td style="text-align: right">4.63</td> <td style="text-align: right">8.03</td> <td style="text-align: right">5.98</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">10399</td> <td style="text-align: right">4.79</td> <td style="text-align: right">8.21</td> <td style="text-align: right">6.14</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">8209</td> <td style="text-align: right">6.03</td> <td style="text-align: right">10.50</td> <td style="text-align: right">7.76</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">7843</td> <td style="text-align: right">6.28</td> <td style="text-align: right">10.76</td> <td style="text-align: right">8.15</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">7456</td> <td style="text-align: right">6.61</td> <td style="text-align: right">11.20</td> <td style="text-align: right">8.62</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">6447</td> <td style="text-align: right">7.60</td> <td style="text-align: right">13.34</td> <td style="text-align: right">9.89</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4854</td> <td style="text-align: right">13.11</td> <td style="text-align: right">13.30</td> <td style="text-align: right">13.18</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2937</td> <td style="text-align: right">21.77</td> <td style="text-align: right">21.94</td> <td style="text-align: right">21.79</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2223</td> <td style="text-align: right">28.46</td> <td style="text-align: right">28.99</td> <td style="text-align: right">28.77</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1708</td> <td style="text-align: right">39.12</td> <td style="text-align: right">41.10</td> <td style="text-align: right">37.44</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.7</code></td> <td style="text-align: right">6135</td> <td style="text-align: right">8.02</td> <td style="text-align: right">14.05</td> <td style="text-align: right">10.45</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">4672</td> <td style="text-align: right">10.52</td> <td style="text-align: right">18.58</td> <td style="text-align: right">13.72</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">4449</td> <td style="text-align: right">11.04</td> <td style="text-align: right">19.35</td> <td style="text-align: right">14.41</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3825</td> <td style="text-align: right">13.56</td> <td style="text-align: right">21.96</td> <td style="text-align: right">16.77</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">2590</td> <td style="text-align: right">20.75</td> <td style="text-align: right">32.66</td> <td style="text-align: right">24.67</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2468</td> <td style="text-align: right">25.91</td> <td style="text-align: right">26.00</td> <td style="text-align: right">25.92</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">2305</td> <td style="text-align: right">32.90</td> <td style="text-align: right">36.64</td> <td style="text-align: right">27.72</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2294</td> <td style="text-align: right">27.90</td> <td style="text-align: right">27.95</td> <td style="text-align: right">27.89</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1894</td> <td style="text-align: right">33.69</td> <td style="text-align: right">34.27</td> <td style="text-align: right">33.78</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">1627</td> <td style="text-align: right">36.25</td> <td style="text-align: right">44.98</td> <td style="text-align: right">39.30</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1091</td> <td style="text-align: right">58.60</td> <td style="text-align: right">65.08</td> <td style="text-align: right">58.55</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.7</code></td> <td style="text-align: right">538695</td> <td style="text-align: right">5.14</td> <td style="text-align: right">8.78</td> <td style="text-align: right">6.57</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">486690</td> <td style="text-align: right">6.08</td> <td style="text-align: right">10.49</td> <td style="text-align: right">7.8</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">452850</td> <td style="text-align: right">7.21</td> <td style="text-align: right">11.8</td> <td style="text-align: right">8.96</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">372375</td> <td style="text-align: right">10.14</td> <td style="text-align: right">16.37</td> <td style="text-align: right">12.32</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">346680</td> <td style="text-align: right">15.53</td> <td style="text-align: right">20.71</td> <td style="text-align: right">17.48</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">324330</td> <td style="text-align: right">7.54</td> <td style="text-align: right">13.03</td> <td style="text-align: right">9.81</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.2</code></td> <td style="text-align: right">281490</td> <td style="text-align: right">15.18</td> <td style="text-align: right">19.46</td> <td style="text-align: right">14.66</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">227865</td> <td style="text-align: right">15.7</td> <td style="text-align: right">15.85</td> <td style="text-align: right">15.74</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">130545</td> <td style="text-align: right">22.7</td> <td style="text-align: right">22.82</td> <td style="text-align: right">22.7</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">114555</td> <td style="text-align: right">27.01</td> <td style="text-align: right">27.59</td> <td style="text-align: right">26.9</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">72525</td> <td style="text-align: right">43.07</td> <td style="text-align: right">47.07</td> <td style="text-align: right">42.49</td> </tr> </tbody> </table>Kirill KlenovResults (2021-06-07)2021-06-07T00:00:00+00:002021-06-07T00:00:00+00:00http://klen.github.io/py-frameworks-bench/results/2021/06/07/results<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> <blockquote> <p>This is a simple benchmark for python async frameworks. Almost all of the frameworks are ASGI-compatible (aiohttp and tornado are exceptions on the moment).</p> <p>The objective of the benchmark is not testing deployment (like uvicorn vs hypercorn and etc) or database (ORM, drivers) but instead test the frameworks itself. The benchmark checks request parsing (body, headers, formdata, queries), routing, responses.</p> </blockquote> <p>Read more about the benchmark: <a href="/py-frameworks-bench/about/">The Methodic</a></p> <h1 id="table-of-contents">Table of contents</h1> <ul> <li><a href="#html">Accept a request and return HTML response with a custom dynamic header</a></li> <li><a href="#upload">Parse uploaded file, store it on disk and return a text response</a></li> <li><a href="#api">Parse path params, query string, JSON body and return a json response</a></li> <li><a href="#composite">Composite stats </a></li> </ul> <canvas id="chart" style="margin-bottom: 2em"></canvas> <script> var ctx = document.getElementById('chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['blacksheep','muffin','falcon','starlette','emmett','sanic','fastapi','aiohttp','tornado','quart','django',], datasets: [ { label: 'Single HTML response (req/s)', data: ['19619','17259','16225','14199','13994','10084','9210','7755','3510','3475','1969',], backgroundColor: [ '#b9ddf1', '#afd6ed', '#a5cfe9', '#9bc7e4', '#92c0df', '#89b8da', '#80b0d5', '#79aacf', '#72a3c9', '#6a9bc3', '#6394be', '#5b8cb8', '#5485b2', '#4e7fac', '#4878a6', '#437a9f', '#3d6a98', '#376491', '#305d8a', '#2a5783', ].reverse() }, { label: 'Upload file (req/s)', data: ['6224','4711','4430','3858','2570','2436','2329','2305','1870','1586','1048',], backgroundColor: [ '#ffc685', '#fcbe75', '#f9b665', '#f7ae54', '#f5a645', '#f59c3c', '#f49234', '#f2882d', '#f07e27', '#ee7422', '#e96b20', '#e36420', '#db5e20', '#d25921', '#ca5422', '#c14f22', '#b84b23', '#af4623', '#a64122', '#9e3d22', ].reverse() }, { label: 'Work with JSON (req/s)', data: ['11029','10567','10457','8279','7792','7313','6439','4880','2905','2180','1654',], backgroundColor: [ '#b3e0a6', '#a5db96', '#98d687', '#8ed07f', '#85ca77', '#7dc370', '#75bc69', '#6eb663', '#67af5c', '#61a956', '#59a253', '#519c51', '#49964f', '#428f4d', '#398949', '#308344', '#2b7c40', '#27763d', '#256f3d', '#24693d', ].reverse() }, ] } }); </script> <h2 id="html">Accept a request and return HTML response with a custom dynamic header</h2> <p>The test simulates just a single HTML response.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.6</code></td> <td style="text-align: right">19619</td> <td style="text-align: right">2.71</td> <td style="text-align: right">4.19</td> <td style="text-align: right">3.23</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">17259</td> <td style="text-align: right">3.03</td> <td style="text-align: right">4.79</td> <td style="text-align: right">3.67</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">16225</td> <td style="text-align: right">3.16</td> <td style="text-align: right">5.17</td> <td style="text-align: right">3.91</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">14199</td> <td style="text-align: right">3.60</td> <td style="text-align: right">5.88</td> <td style="text-align: right">4.48</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">13994</td> <td style="text-align: right">3.66</td> <td style="text-align: right">6.02</td> <td style="text-align: right">4.54</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.1</code></td> <td style="text-align: right">10084</td> <td style="text-align: right">4.91</td> <td style="text-align: right">8.41</td> <td style="text-align: right">6.31</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">9210</td> <td style="text-align: right">5.38</td> <td style="text-align: right">9.12</td> <td style="text-align: right">6.97</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">7755</td> <td style="text-align: right">8.20</td> <td style="text-align: right">8.26</td> <td style="text-align: right">8.25</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">3510</td> <td style="text-align: right">18.14</td> <td style="text-align: right">18.33</td> <td style="text-align: right">18.23</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">3475</td> <td style="text-align: right">19.01</td> <td style="text-align: right">19.85</td> <td style="text-align: right">18.43</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1969</td> <td style="text-align: right">31.32</td> <td style="text-align: right">35.95</td> <td style="text-align: right">32.52</td> </tr> </tbody> </table> <h2 id="upload">Parse uploaded file, store it on disk and return a text response</h2> <p>The test simulates multipart formdata processing and work with files.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.6</code></td> <td style="text-align: right">6224</td> <td style="text-align: right">7.84</td> <td style="text-align: right">14.03</td> <td style="text-align: right">10.26</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">4711</td> <td style="text-align: right">10.48</td> <td style="text-align: right">18.75</td> <td style="text-align: right">13.56</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">4430</td> <td style="text-align: right">11.03</td> <td style="text-align: right">19.65</td> <td style="text-align: right">14.53</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">3858</td> <td style="text-align: right">12.79</td> <td style="text-align: right">22.23</td> <td style="text-align: right">16.68</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">2570</td> <td style="text-align: right">19.09</td> <td style="text-align: right">34.01</td> <td style="text-align: right">24.87</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">2436</td> <td style="text-align: right">26.25</td> <td style="text-align: right">26.42</td> <td style="text-align: right">26.26</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.1</code></td> <td style="text-align: right">2329</td> <td style="text-align: right">20.88</td> <td style="text-align: right">37.19</td> <td style="text-align: right">27.44</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2305</td> <td style="text-align: right">27.71</td> <td style="text-align: right">27.85</td> <td style="text-align: right">27.77</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">1870</td> <td style="text-align: right">34.15</td> <td style="text-align: right">34.91</td> <td style="text-align: right">34.20</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">1586</td> <td style="text-align: right">37.12</td> <td style="text-align: right">45.56</td> <td style="text-align: right">40.31</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1048</td> <td style="text-align: right">60.45</td> <td style="text-align: right">67.23</td> <td style="text-align: right">60.96</td> </tr> </tbody> </table> <h2 id="api">Parse path params, query string, JSON body and return a json response</h2> <p>The test simulates a simple JSON REST API endpoint.</p> <p>Sorted by max req/s</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests/sec</th> <th style="text-align: right">Latency 50% (ms)</th> <th style="text-align: right">Latency 75% (ms)</th> <th style="text-align: right">Latency Avg (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.6</code></td> <td style="text-align: right">11029</td> <td style="text-align: right">4.47</td> <td style="text-align: right">7.83</td> <td style="text-align: right">5.77</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">10567</td> <td style="text-align: right">4.67</td> <td style="text-align: right">8.08</td> <td style="text-align: right">6.02</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">10457</td> <td style="text-align: right">4.80</td> <td style="text-align: right">8.16</td> <td style="text-align: right">6.09</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">8279</td> <td style="text-align: right">5.93</td> <td style="text-align: right">10.36</td> <td style="text-align: right">7.70</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">7792</td> <td style="text-align: right">6.23</td> <td style="text-align: right">10.86</td> <td style="text-align: right">8.22</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">7313</td> <td style="text-align: right">6.61</td> <td style="text-align: right">11.63</td> <td style="text-align: right">8.88</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.1</code></td> <td style="text-align: right">6439</td> <td style="text-align: right">7.57</td> <td style="text-align: right">13.56</td> <td style="text-align: right">9.90</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">4880</td> <td style="text-align: right">13.04</td> <td style="text-align: right">13.27</td> <td style="text-align: right">13.11</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">2905</td> <td style="text-align: right">22.01</td> <td style="text-align: right">22.23</td> <td style="text-align: right">22.03</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">2180</td> <td style="text-align: right">28.83</td> <td style="text-align: right">29.63</td> <td style="text-align: right">29.32</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">1654</td> <td style="text-align: right">39.47</td> <td style="text-align: right">42.65</td> <td style="text-align: right">38.67</td> </tr> </tbody> </table> <h2 id="composite">Composite stats</h2> <p>Combined benchmarks results</p> <p>Sorted by completed requests</p> <table> <thead> <tr> <th>Framework</th> <th style="text-align: right">Requests completed</th> <th style="text-align: right">Avg Latency 50% (ms)</th> <th style="text-align: right">Avg Latency 75% (ms)</th> <th style="text-align: right">Avg Latency (ms)</th> </tr> </thead> <tbody> <tr> <td><a href="https://pypi.org/project/blacksheep/">blacksheep</a> <code class="language-plaintext highlighter-rouge">1.0.6</code></td> <td style="text-align: right">553080</td> <td style="text-align: right">5.01</td> <td style="text-align: right">8.68</td> <td style="text-align: right">6.42</td> </tr> <tr> <td><a href="https://pypi.org/project/muffin/">muffin</a> <code class="language-plaintext highlighter-rouge">0.79.1</code></td> <td style="text-align: right">488055</td> <td style="text-align: right">6.06</td> <td style="text-align: right">10.54</td> <td style="text-align: right">7.75</td> </tr> <tr> <td><a href="https://pypi.org/project/falcon/">falcon</a> <code class="language-plaintext highlighter-rouge">3.0.1</code></td> <td style="text-align: right">458100</td> <td style="text-align: right">6.92</td> <td style="text-align: right">11.85</td> <td style="text-align: right">8.89</td> </tr> <tr> <td><a href="https://pypi.org/project/starlette/">starlette</a> <code class="language-plaintext highlighter-rouge">0.14.2</code></td> <td style="text-align: right">375720</td> <td style="text-align: right">9.54</td> <td style="text-align: right">16.75</td> <td style="text-align: right">12.35</td> </tr> <tr> <td><a href="https://pypi.org/project/emmett/">emmett</a> <code class="language-plaintext highlighter-rouge">2.2.2</code></td> <td style="text-align: right">343395</td> <td style="text-align: right">15.8</td> <td style="text-align: right">21.07</td> <td style="text-align: right">17.91</td> </tr> <tr> <td><a href="https://pypi.org/project/sanic/">sanic</a> <code class="language-plaintext highlighter-rouge">21.3.4</code></td> <td style="text-align: right">321480</td> <td style="text-align: right">7.55</td> <td style="text-align: right">13.21</td> <td style="text-align: right">9.91</td> </tr> <tr> <td><a href="https://pypi.org/project/fastapi/">fastapi</a> <code class="language-plaintext highlighter-rouge">0.65.1</code></td> <td style="text-align: right">282780</td> <td style="text-align: right">11.12</td> <td style="text-align: right">19.72</td> <td style="text-align: right">14.55</td> </tr> <tr> <td><a href="https://pypi.org/project/aiohttp/">aiohttp</a> <code class="language-plaintext highlighter-rouge">3.7.4.post0</code></td> <td style="text-align: right">226065</td> <td style="text-align: right">15.83</td> <td style="text-align: right">15.98</td> <td style="text-align: right">15.87</td> </tr> <tr> <td><a href="https://pypi.org/project/tornado/">tornado</a> <code class="language-plaintext highlighter-rouge">6.1</code></td> <td style="text-align: right">130800</td> <td style="text-align: right">22.62</td> <td style="text-align: right">22.8</td> <td style="text-align: right">22.68</td> </tr> <tr> <td><a href="https://pypi.org/project/quart/">quart</a> <code class="language-plaintext highlighter-rouge">0.15.1</code></td> <td style="text-align: right">112875</td> <td style="text-align: right">27.33</td> <td style="text-align: right">28.13</td> <td style="text-align: right">27.32</td> </tr> <tr> <td><a href="https://pypi.org/project/django/">django</a> <code class="language-plaintext highlighter-rouge">3.2.4</code></td> <td style="text-align: right">70065</td> <td style="text-align: right">43.75</td> <td style="text-align: right">48.61</td> <td style="text-align: right">44.05</td> </tr> </tbody> </table>Kirill Klenov