I have done a full benchmark of a POST REST API on my computer: Node.js vs Fastify vs Express.js vs Deno vs Bun vs GO. Node.js is used WITH and WITHOUT clustering on 6-core I7 processor
Introducing FastAPI
Flask, FastAPI or Express: Most Cost-Efficient /best for Low Budget App with JWT, OAuth, PostgreSQL?
Real world scenario FastAPI vs Node.js k8s cluster benchmarks
Videos
After seeing SO SO many benchmarks of Node.js vs GO where GO by default can use full CPU cores whereas Node.js is just run without clustering, I decided to do my own full benchmark on my machine with and without clustering Node.js to utilize full CPU cores.
My machine specs:
1] Macos, 16'inch 2019 model, I7 - 6 core 2.6 GH processor, 32GB RAM
The test:
Exposed a simple POST /benchmark API on ALL the servers. The api receives 1.4KB of JSON as a POST body payload, converts the JSON to native JSON object (in GO's case native struct, in Node.js/Bun/Deno's case native JSON object) and responds back with the EXACT same JSON (so it de-serializes the JSON back to a stringified one to be able to send the JSON back to caller).
Benchmark command:
wrk -t8 -c5000 -d120s -s ./post.lua --latency <URL>
Results:
Node.js vs Deno vs Bun vs express vs fastify vs GO (Req/Sec) Node.js vs Deno vs Bun vs express vs fastify vs GO (Max CPU used) Node.js vs Deno vs Bun vs express vs fastify vs GO (Max memory used) Node.js vs Deno vs Bun vs express vs fastify vs GO (Avg latency in ms) Node.js vs Deno vs Bun vs express vs fastify vs GO (Total data transfer/sec) Node.js vs Deno vs Bun vs express vs fastify vs GO (raw results)TLDR:
1] With Clustering, the speed difference between Node.js/fastify vs GO (with GIN) is quite close. GO is 1.2x faster than Node.js/fastify with clustering and utilizing all CPU cores under very high load
2] Fastify speed is near identical (or even slightly better) to native Node.js HTTP module with/without clustering
3] GO (with GIN) uses almost 2x the CPU (835%) to achieve 1.2x the speed of Node.js/fastify (432% CPU) (with clustering)
4] GO (with GIN) uses 12x LESS memory compared to Node.js/fastify with clustering to achieve 1.2x more speed.
5] Bun actually is ALMOST 3x faster than Node.js (with/without fastify) on a single core without clustering. (Their claim was NOT WRONG).
6] Deno.js is ALMOST 1.5x faster than Node.js (with/without fastify) on a single core without clustering
7] Bun is ALMOST 2x faster than Deno on a single core without clustering.
8] Express.js has fallen SO SO MUCH behind and utilizes more CPU/ram and is SIGNIFICANTLY slower than everything, its not even comparable.
I hope this would be useful for the community here to have a good idea of how big a difference between Node vs GO vs Bun vs Deno vs Fastify vs Express could be.
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
Documentation: https://fastapi.tiangolo.com
Source Code: https://github.com/tiangolo/fastapi
Key Features
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 new features.
Fewer bugs: Reduce a high amount of human (developer) induced errors.
Intuitive: Great editor support. Completion (also known as auto-complete, autocompletion, IntelliSense) 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. Less 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.
Installation
$ pip install fastapi
You will also need an ASGI server, for production such as Uvicorn.
$ pip install uvicorn
Example
Create it
Create a file
main.pywith:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}Or use async def...
Check it
Open your browser at http://127.0.0.1:8000/items/5?q=somequery.
You will see the JSON response as:
{"item_id": 5, "q": "somequery"}You already created an API that:
Receives HTTP requests in the paths
/and/items/{item_id}.Both paths take
GEToperations (also known as HTTP methods).The path
/items/{item_id}has a path parameteritem_idthat should be anint.The path
/items/{item_id}has an optionalstrquery parameterq.
Interactive API docs
Now go to http://127.0.0.1:8000/docs.
You will see the automatic interactive API documentation (provided by Swagger UI):
Alternative API docs
And now, go to http://127.0.0.1:8000/redoc.
You will see the alternative automatic documentation (provided by ReDoc):