<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: André Ribeiro</title>
    <description>The latest articles on Forem by André Ribeiro (@andresribeiro).</description>
    <link>https://forem.com/andresribeiro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F630074%2F10833dd9-4d9f-4986-8cbf-8ce4792c29b4.jpg</url>
      <title>Forem: André Ribeiro</title>
      <link>https://forem.com/andresribeiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andresribeiro"/>
    <language>en</language>
    <item>
      <title>Benchmarking Deno vs Node with GraphQL</title>
      <dc:creator>André Ribeiro</dc:creator>
      <pubDate>Tue, 20 Dec 2022 17:33:49 +0000</pubDate>
      <link>https://forem.com/andresribeiro/benchmarking-deno-vs-node-with-graphql-3ma3</link>
      <guid>https://forem.com/andresribeiro/benchmarking-deno-vs-node-with-graphql-3ma3</guid>
      <description>&lt;p&gt;Just over 1 month ago, &lt;a href="https://deno.com/blog/v1.28"&gt;Deno has announced support for NPM&lt;/a&gt;, which means that 1.3 million new modules can be used to build a Deno application. Also, it means that a lot of people can migrate from Node to Deno, just by changing some configurations and imports.&lt;/p&gt;

&lt;p&gt;This got me thinking about moving my application, &lt;a href="https://play.google.com/store/apps/details?id=com.andresribeiro.drakkle"&gt;Drakkle&lt;/a&gt;, to Deno, but I couldn't find any benchmarks on GraphQL, so I decided to do some simple tests.&lt;/p&gt;

&lt;p&gt;Instead of choosing the most popular stack (Apollo Server + Express), I decided to choose the most performant: Fastify + Mercurius.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding
&lt;/h2&gt;

&lt;p&gt;I love Typescript, but since it's a simple benchmark, Javascript seemed like a good enough choice.&lt;/p&gt;

&lt;p&gt;Using the same example from the Mercurius documentation, an &lt;code&gt;add&lt;/code&gt; query was created, which returns the sum of two numbers passed.&lt;/p&gt;

&lt;p&gt;The code for Node looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Fastify&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fastify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mercurius&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mercurius&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Fastify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  type Query {
    add(x: Int, y: Int): Int
  }
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mercurius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resolvers&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code for Deno was the same, except for the imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Fastify&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;npm:fastify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mercurius&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;npm:mercurius&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Benchmarking
&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://github.com/mcollina/autocannon"&gt;autocannon&lt;/a&gt;, I did the following script to simulate 500 concurrent connections over 30 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx autocannon &lt;span class="nt"&gt;-c&lt;/span&gt; 500 &lt;span class="nt"&gt;-d&lt;/span&gt; 30 &lt;span class="nt"&gt;-m&lt;/span&gt; POST &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s1"&gt;'query Add { add (x: 50, y: 50) }'&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type:application/graphql'&lt;/span&gt; localhost:3000/graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Node
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stat&lt;/th&gt;
&lt;th&gt;2.5%&lt;/th&gt;
&lt;th&gt;50%&lt;/th&gt;
&lt;th&gt;97.5%&lt;/th&gt;
&lt;th&gt;99%&lt;/th&gt;
&lt;th&gt;Avg&lt;/th&gt;
&lt;th&gt;Stdev&lt;/th&gt;
&lt;th&gt;Max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;48 ms&lt;/td&gt;
&lt;td&gt;72 ms&lt;/td&gt;
&lt;td&gt;118 ms&lt;/td&gt;
&lt;td&gt;234 ms&lt;/td&gt;
&lt;td&gt;75.11 ms&lt;/td&gt;
&lt;td&gt;34.03 ms&lt;/td&gt;
&lt;td&gt;581 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stat&lt;/th&gt;
&lt;th&gt;1%&lt;/th&gt;
&lt;th&gt;2.5%&lt;/th&gt;
&lt;th&gt;50%&lt;/th&gt;
&lt;th&gt;97.5%&lt;/th&gt;
&lt;th&gt;Avg&lt;/th&gt;
&lt;th&gt;Stdev&lt;/th&gt;
&lt;th&gt;Max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Req/Sec&lt;/td&gt;
&lt;td&gt;1209&lt;/td&gt;
&lt;td&gt;1209&lt;/td&gt;
&lt;td&gt;6791&lt;/td&gt;
&lt;td&gt;8231&lt;/td&gt;
&lt;td&gt;6622.27&lt;/td&gt;
&lt;td&gt;1391.98&lt;/td&gt;
&lt;td&gt;1209&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bytes/Sec&lt;/td&gt;
&lt;td&gt;231 kB&lt;/td&gt;
&lt;td&gt;231 kB&lt;/td&gt;
&lt;td&gt;1.3 MB&lt;/td&gt;
&lt;td&gt;1.57 MB&lt;/td&gt;
&lt;td&gt;1.26 MB&lt;/td&gt;
&lt;td&gt;266 kB&lt;/td&gt;
&lt;td&gt;231 kB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;199k requests in 30.23s, 37.9 MB read&lt;/p&gt;

&lt;h3&gt;
  
  
  Deno
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stat&lt;/th&gt;
&lt;th&gt;2.5%&lt;/th&gt;
&lt;th&gt;50%&lt;/th&gt;
&lt;th&gt;97.5%&lt;/th&gt;
&lt;th&gt;99%&lt;/th&gt;
&lt;th&gt;Avg&lt;/th&gt;
&lt;th&gt;Stdev&lt;/th&gt;
&lt;th&gt;Max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;114 ms&lt;/td&gt;
&lt;td&gt;155 ms&lt;/td&gt;
&lt;td&gt;240 ms&lt;/td&gt;
&lt;td&gt;420 ms&lt;/td&gt;
&lt;td&gt;162.46 ms&lt;/td&gt;
&lt;td&gt;56.72 ms&lt;/td&gt;
&lt;td&gt;1531 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stat&lt;/th&gt;
&lt;th&gt;1%&lt;/th&gt;
&lt;th&gt;2.5%&lt;/th&gt;
&lt;th&gt;50%&lt;/th&gt;
&lt;th&gt;97.5%&lt;/th&gt;
&lt;th&gt;Avg&lt;/th&gt;
&lt;th&gt;Stdev&lt;/th&gt;
&lt;th&gt;Max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Req/Sec&lt;/td&gt;
&lt;td&gt;988&lt;/td&gt;
&lt;td&gt;988&lt;/td&gt;
&lt;td&gt;3169&lt;/td&gt;
&lt;td&gt;3565&lt;/td&gt;
&lt;td&gt;3087.8&lt;/td&gt;
&lt;td&gt;569.88&lt;/td&gt;
&lt;td&gt;988&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bytes/Sec&lt;/td&gt;
&lt;td&gt;180 kB&lt;/td&gt;
&lt;td&gt;180 kB&lt;/td&gt;
&lt;td&gt;577 kB&lt;/td&gt;
&lt;td&gt;649 kB&lt;/td&gt;
&lt;td&gt;562 kB&lt;/td&gt;
&lt;td&gt;104 kB&lt;/td&gt;
&lt;td&gt;180 kB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;93k requests in 30.36s, 16.9 MB read&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As you can see, &lt;strong&gt;Node it's just over 2 times faster than the Deno&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To try this further, I tried to compare by creating a fork of the process for each CPU, using Node's cluster module, but this module has not yet been ported to Deno.&lt;/p&gt;

</description>
      <category>deno</category>
      <category>node</category>
      <category>javascript</category>
      <category>graphql</category>
    </item>
  </channel>
</rss>
