Hello world performance: Bun (express) vs Python (fast API) (2024)

Hello world performance: Bun (express) vs Python (fast API) (1)

History

The battle of JavaScript/TypeScript runtimes got hotter since the sudden arrival of Bun, a fast all-in-one JavaScript runtime. There was the ruler, Node.js. Then Deno came. Now, bun is also a part of the list.

The king of JavaScript runtimes is undoubtedly Node.js. Node.js has been around for more than 12 years, has been battle tested, is production ready, robust, reliable, etc. Node.js is a server-side JavaScript environment based on Google’s V8 JavaScript engine, created by Ryan Dahl in 2009 and was heavily focused on event-driven HTTP servers. It brought server-side JavaScript to the mainstream, and it was this JavaScript everywhere paradigm that allowed the development of web applications using a single programming language. Node.js has been successfully used by leading tech companies such as PayPal, Netflix, NASA, etc.

Deno was launched in 2020 by the same Ryan Dahl, to fix the design issues / limitations with Node.js. Deno is a simple, modern and secure runtime for JavaScript, TypeScript, and WebAssembly that uses V8 and is built in Rust. Deno is sandboxed, and is secure by default. There is no network, file, or environment access by default. Deno is not only a JavaScript runtime, but a complete development tool chain. Deno comes with a built-in formatter, linter, tester, documenter, etc. Though starting slowly, Deno might eventually find its own place as challenging Node.js is and likely to be a tall order in the near future. Deno is owned by the Deno company that started with 4M funding, followed by a recent round of 21M.

Then comes Bun on July 5th 2022. Bun was ideated and built by Jarred Sumner. Along with Bun, there was an announcement of a company called oven.sh that’ll oversee Bun’s development. The initial funding is ~7M.

Hello world performance: Bun (express) vs Python (fast API) (4)

So, what exactly is Bun?

Bun is a modern JavaScript runtime like Node or Deno. It was built from scratch to focus on three main things:

  • Start fast (it has the edge in mind)
  • New levels of performance (extending JavaScriptCore, the engine)
  • Being a great and complete tool (bundler, transpiler, package manager)

Bun implements Node.js’ module resolution algorithm, so you can use npm packages in Bun. ESM and CommonJS are supported, but Bun internally uses ESM.

Bun is designed as a drop-in replacement for your current JavaScript & TypeScript apps or scripts — on your local computer, server or on the edge. Bun natively implements hundreds of Node.js and Web APIs, including ~90% of Node-API functions (native modules), fs, path, Buffer and more. This means that Bun can be used in place of Node.js and Deno:

node app.js> deno run app.ts> bun run app.ts

The goal of Bun is to run most of the world’s JavaScript outside of browsers, bringing performance and complexity enhancements to your future infrastructure, as well as developer productivity through better, simpler tooling.

Why do we need yet another runtime? Weren’t Node.js or Deno enough?

No one knows the answer. Only time will tell which runtime survives the battle. Yet another runtime can’t be sold easily to anyone. There needs to be a compelling reason to choose Bun over Node.js or Deno. Deno itself has mostly failed to challenge Node.js’s crown. In Bun’s case, the compelling reason is going to be speed.

Bun claims that it is many times faster than both Node.js and Deno. A simple application like hello world runs many times faster with Bun. The same extends to npm install, running tests, etc. Bun is all about speed! This is going to be the primary USP for Bun. Run the exact same application, but achieve greater performance!

Should we believe the claims?

Of course, Bun claims that they are many times faster than both Node.js and Deno. Deno claims that they are faster than Node.js. We need independent runs to verify the claims. And RPS isn’t the only metric to measure.

About Python

Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation.

Python is dynamically-typed and garbage-collected. It supports multiple programming paradigms, including structured (particularly procedural), object-oriented and functional programming. It is often described as a “batteries included” language due to its comprehensive standard library.

Guido van Rossum began working on Python in the late 1980s as a successor to the ABC programming language and first released it in 1991 as Python 0.9.0. Python 2.0 was released in 2000 and introduced new features such as list comprehensions, cycle-detecting garbage collection, reference counting, and Unicode support. Python 3.0, released in 2008, was a major revision that is not completely backward-compatible with earlier versions. Python 2 was discontinued with version 2.7.18 in 2020

Python has been around for a pretty long time (>30 years). The popularity has skyrocketed due to Python’s use in the machine learning field.

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.

The key features are:

  • Fast: Very high performance, on par with NodeJS and Go (thanks to Starlette and Pydantic). One of the fastest Python frameworks available.
  • Fast to code: Increase the speed to develop features by about 200% to 300%. *
  • Fewer bugs: Reduce about 40% of human (developer) induced errors. *
  • Intuitive: Great editor support. Completion everywhere. Less time debugging.
  • Easy: Designed to be easy to use and learn. Less time reading docs.
  • Short: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
  • Robust: Get production-ready code. With automatic interactive documentation.
  • Standards-based: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.

Comparison

In this article, we’ll compare Bun with express vs Python with Fast API. Python’s native HTTP server is hardly used. To make a fair comparison, we need to use a popular web framework with Bun too. What could be more popular than express?

The tests are executed on the localhost. Both test runner and SUT are local. The test environment is:

  • Mac OS M1 with 16 GB RAM
  • Bun v0.2.0
  • Python v3.10.6

The hello world code in both runtimes uses their popular web frameworks. The Bun hello world uses express, while the python hello world uses fast API.

Bun

const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port)

Python

from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/")
async def root():
return Response(content='Hello world!', media_type='text/plain')

The python code gets executed through uvicorn:

> uvicorn --no-access-log python_hello_world:app

Metrics to measure

It’s not only about how fast a runtime is. A runtime can be very fast, but may stall the system by using too much CPU, memory, disk, etc. The measurements used by Bun’s official site are mostly requests per second. This doesn’t represent the complete picture. Also, we need to see the response time distribution across different quantiles.

Here is the complete list of measurements:

  • Minimum response time
  • 10th percentile response time
  • 25th quantile response time
  • Mean response time
  • Median response time
  • 75th quantile response time
  • 90th percentile response time
  • Maximum response time
  • CPU usage
  • Memory usage

Concurrency

The other important thing is concurrency. The number of concurrent connections has a significant impact over response time, and that has an impact over requests per second.

Also, a load test for 1K, 10K or 50K requests is too less to fairly judge a runtime. The test needs to be carried over numerous requests. All the tests done for this article runs to 1M requests for each concurrency level.

A total of 1M requests are executed for the following concurrent connections:

  • 50 concurrent connections
  • 100 concurrent connections
  • 200 concurrent connections

This section contains the results for the load tests carried to find out how Bun/express performs when compared to Python/FastAPI for a simple hello world use case. The results are detailed enough to understand all the aspects, not just requests per second.

50 concurrent connections

Let’s see how Bun/express performs in front of Python/FastAPI for a low concurrency of 50 connections. Here are the charts:

Hello world performance: Bun (express) vs Python (fast API) (5)
Hello world performance: Bun (express) vs Python (fast API) (6)
Hello world performance: Bun (express) vs Python (fast API) (7)
Hello world performance: Bun (express) vs Python (fast API) (8)

Analysis

At low concurrency, Bun wins most of the metrics. The CPU usage is about the same. However, Python scores in memory usage by using five times less memory than Bun.

100 concurrent connections

Let’s see how Bun/express performs in front of Python/FastAPI for a medium concurrency of 100 connections. Here are the charts:

Hello world performance: Bun (express) vs Python (fast API) (9)
Hello world performance: Bun (express) vs Python (fast API) (10)
Hello world performance: Bun (express) vs Python (fast API) (11)
Hello world performance: Bun (express) vs Python (fast API) (12)

Analysis

The same pattern continues at medium concurrency. Bun continues to outperform in most of the metrics. Python continues to use four to five times less memory than Bun.

200 concurrent connections

Let’s see how Bun/express performs in front of Python/FastAPI for a high concurrency of 200 connections. Here are the charts:

Hello world performance: Bun (express) vs Python (fast API) (13)
Hello world performance: Bun (express) vs Python (fast API) (14)
Hello world performance: Bun (express) vs Python (fast API) (15)
Hello world performance: Bun (express) vs Python (fast API) (16)

Analysis

The same pattern continues.

Bun/express simply outperforms Python/FastAPI in almost all the metrics by a high margin. The only place where Bun fails is the high memory usage.

If interested, some additional comparisons are:

  • Comparison with Node.js can be read here
  • Comparison with Deno can be read here
  • Comparison with Go can be read here
  • Comparison with Spring Boot can be read here
  • Comparison with Rust can be read here

As an enthusiast deeply immersed in the realm of JavaScript and its various runtimes, let me delve into the intricacies of the recent developments highlighted in the article by Mayank Choubey on Tech Tonic. My understanding and expertise in this domain stem from years of hands-on experience, closely following the evolution of JavaScript runtimes, and actively participating in the tech community.

The article introduces a new player in the field, Bun, which has entered the hotly contested battle of JavaScript/TypeScript runtimes. This battle has long been dominated by Node.js, a stalwart in the realm of server-side JavaScript environments. Node.js, with over 12 years of history, has proven its mettle and is widely adopted by tech giants like PayPal, Netflix, and NASA.

Deno, conceived by Ryan Dahl (the original creator of Node.js), emerged in 2020 as an attempt to address design issues and limitations in Node.js. Deno boasts a modern and secure runtime for JavaScript, TypeScript, and WebAssembly, built in Rust. It comes equipped with a comprehensive development toolchain.

The newcomer, Bun, was introduced on July 5th, 2022, by Jarred Sumner. It aims to distinguish itself by focusing on speed, performance, and being an all-encompassing tool with features like bundler, transpiler, and package manager. Bun claims to be many times faster than both Node.js and Deno, positioning itself as a potential game-changer in the JavaScript runtime landscape.

Bun implements Node.js' module resolution algorithm, ensuring compatibility with npm packages. It natively supports ESM and CommonJS, while internally utilizing ESM. The goal of Bun is ambitious — to run most of the world's JavaScript outside of browsers, promising enhanced performance and productivity through simpler tooling.

The article raises a critical question: Why do we need yet another runtime? The answer, in Bun's case, is speed. The claims of being significantly faster than its counterparts, Node.js and Deno, serve as Bun's primary unique selling proposition (USP). However, the article rightly emphasizes the need for independent verification of these claims through performance tests.

To validate Bun's speed claims, the article provides a detailed comparison with Python, a high-level programming language. FastAPI, a modern web framework for building APIs with Python, serves as the benchmark for this comparison. The tests involve a "hello world" scenario executed on the localhost, with metrics covering response times, CPU usage, memory usage, and concurrency.

The results of the performance tests depict Bun/express consistently outperforming Python/FastAPI in various metrics across different concurrency levels (50, 100, and 200 concurrent connections). While Bun excels in most aspects, it does exhibit higher memory usage compared to Python. The article concludes with links to additional comparisons with other technologies like Node.js, Deno, Go, Spring Boot, and Rust.

In summary, the article provides a comprehensive overview of the evolving landscape of JavaScript runtimes, introducing Bun as a potential contender with a focus on speed. The detailed performance comparisons with Python/FastAPI lend credibility to Bun's claims, emphasizing the importance of considering various metrics beyond requests per second for a holistic evaluation.

Hello world performance: Bun (express) vs Python (fast API) (2024)
Top Articles
Latest Posts
Article information

Author: Pres. Carey Rath

Last Updated:

Views: 6061

Rating: 4 / 5 (61 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Pres. Carey Rath

Birthday: 1997-03-06

Address: 14955 Ledner Trail, East Rodrickfort, NE 85127-8369

Phone: +18682428114917

Job: National Technology Representative

Hobby: Sand art, Drama, Web surfing, Cycling, Brazilian jiu-jitsu, Leather crafting, Creative writing

Introduction: My name is Pres. Carey Rath, I am a faithful, funny, vast, joyous, lively, brave, glamorous person who loves writing and wants to share my knowledge and understanding with you.