Skip to content

NestJS Performance

Posted on:12 dicembre 2024 at 19:34

In this short post, I would like to highlight the significant performance differences between two of the most widely used Node.js frameworks currently. We will analyze their performance through a simple NestJS project, examining how performance varies between the two under different use cases, and draw final conclusions about their pros and cons.

Simple GET request

As a first test, let’s examine a simple GET request that generates a random number from 1 to 100

ExpressJS

          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: script.js
     output: -

  scenarios: (100.00%) 1 scenario, 50 max VUs, 40s max duration (incl. graceful stop):
           * default: 50 looping VUs for 10s (gracefulStop: 30s)

running (10.0s), 00/50 VUs, 90840 complete and 0 interrupted iterations
default ✓ [======================================] 50 VUs  10s

     ✓ is status 200

     checks.........................: 100.00% ✓ 90840       ✗ 0
     data_received..................: 21 MB   2.1 MB/s
     data_sent......................: 7.3 MB  726 kB/s
     http_req_blocked...............: avg=1.66µs  min=0s       med=1µs    max=2.64ms   p(90)=1µs    p(95)=1µs
     http_req_connecting............: avg=514ns   min=0s       med=0s     max=1.08ms   p(90)=0s     p(95)=0s
     http_req_duration..............: avg=5.47ms  min=695µs    med=4.99ms max=209.89ms p(90)=6.55ms p(95)=7.37ms
       { expected_response:true }...: avg=5.47ms  min=695µs    med=4.99ms max=209.89ms p(90)=6.55ms p(95)=7.37ms
     http_req_failed................: 0.00%   ✓ 0           ✗ 90840
     http_req_receiving.............: avg=11.29µs min=6µs      med=10µs   max=4.54ms   p(90)=12µs   p(95)=14µs
     http_req_sending...............: avg=3.11µs  min=1µs      med=3µs    max=1.13ms   p(90)=3µs    p(95)=4µs
     http_req_tls_handshaking.......: avg=0s      min=0s       med=0s     max=0s       p(90)=0s     p(95)=0s
     http_req_waiting...............: avg=5.46ms  min=678µs    med=4.97ms max=209.87ms p(90)=6.54ms p(95)=7.35ms
     http_reqs......................: 90840   9078.688967/s
     iteration_duration.............: avg=5.5ms   min=720.87µs med=5.01ms max=211.59ms p(90)=6.58ms p(95)=7.4ms
     iterations.....................: 90840   9078.688967/s
     vus............................: 50      min=50        max=50
     vus_max........................: 50      min=50        max=50

Fastify

          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: script.js
     output: -

  scenarios: (100.00%) 1 scenario, 50 max VUs, 40s max duration (incl. graceful stop):
           * default: 50 looping VUs for 10s (gracefulStop: 30s)

scenarios: (100.00%) 1 scenario, 50 max VUs, 40s max duration (incl. graceful stop):
           * default: 50 looping VUs for 10s (gracefulStop: 30s)
running (10.0s), 00/50 VUs, 231809 complete and 0 interrupted iterations
default ✓ [======================================] 50 VUs  10s
     ✓ is status 200
     checks.........................: 100.00% ✓ 231809       ✗ 0
     data_received..................: 40 MB   4.0 MB/s
     data_sent......................: 19 MB   1.9 MB/s
     http_req_blocked...............: avg=1.66µs  min=0s       med=1µs    max=4.88ms  p(90)=2µs    p(95)=2µs
     http_req_connecting............: avg=189ns   min=0s       med=0s     max=1.29ms  p(90)=0s     p(95)=0s
     http_req_duration..............: avg=2.1ms   min=86µs     med=1.97ms max=89.75ms p(90)=2.56ms p(95)=3.51ms
       { expected_response:true }...: avg=2.1ms   min=86µs     med=1.97ms max=89.75ms p(90)=2.56ms p(95)=3.51ms
     http_req_failed................: 0.00%   ✓ 0            ✗ 231809
     http_req_receiving.............: avg=17.67µs min=5µs      med=11µs   max=9.13ms  p(90)=30µs   p(95)=43µs
     http_req_sending...............: avg=6.51µs  min=1µs      med=4µs    max=8.02ms  p(90)=8µs    p(95)=17µs
     http_req_tls_handshaking.......: avg=0s      min=0s       med=0s     max=0s      p(90)=0s     p(95)=0s
     http_req_waiting...............: avg=2.08ms  min=60µs     med=1.95ms max=89.72ms p(90)=2.53ms p(95)=3.46ms
     http_reqs......................: 231809  23176.774534/s
     iteration_duration.............: avg=2.15ms  min=144.79µs med=2.01ms max=91.3ms  p(90)=2.6ms  p(95)=3.58ms
     iterations.....................: 231809  23176.774534/s
     vus............................: 50      min=50         max=50
     vus_max........................: 50      min=50         max=50

Here’s a comparative summary of the benchmark results between Express.js and Fastify

Number of Requests

Time Performance

Express.js:

Fastify:

Data Transferred

Express.js:

Fastify:

Conclusion

Fastify shows significantly better performance compared to Express.js, processes about 2.5x more requests and have a lower avarage latency (2.1 ms vs 5.47 ms). Both frameworks handled all requests perfectly (0% failures)

In summary, Fastify demonstrates notably superior efficiency and processing speed in this test scenario.