Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmark and update readme #199

Merged
merged 1 commit into from
Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ The promise-based method routing and middleware layer for [Next.js](https://next
> **Warning**
> v1 is a complete rewrite of v0 and is not backward-compatible. See [Releases](https://github.com/hoangvvo/next-connect/releases) to learn about the changes.

> [v0](https://github.com/hoangvvo/next-connect/tree/v0), which is written to be compatible with Express.js middleware, is still maintained with bug fixes. [v1] drops explicit support for Express.js middleware, but still provide a way to use them through a wrapper (see below)
> [v0](https://github.com/hoangvvo/next-connect/tree/v0), which is written to be compatible with Express.js middleware, is still maintained with bug fixes. v1 drops explicit support for Express.js middleware, but still provide a way to use them through a wrapper (see below)

## Features

- [Koa](https://koajs.com/)-like Async middleware
- Lightweight => Suitable for serverless environment
- 5x faster than Express.js with no overhead. Compatible with Express.js via [a wrapper](#expressjs-compatibility).
- Async middleware
- [Lightweight](https://bundlephobia.com/scan-results?packages=express,next-connect,koa,micro) => Suitable for serverless environment
- [way faster](https://github.com/hoangvvo/next-connect/tree/main/bench) than Express.js. Compatible with Express.js via [a wrapper](#expressjs-compatibility).
- Works with async handlers (with error catching)
- TypeScript support

Expand Down
68 changes: 68 additions & 0 deletions bench/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Benchmarks

A simple benchmark against some popular router using [wrk](https://github.com/wg/wrk)

```
wrk -t12 -c400 -d30s http://localhost:3000/user/123
```

> Remember, this benchmark is for reference only and by no means says that one is better than the others. The slowest part of the application is still the application code itself, not the library.

## How-to

Set permissions:

```bash
chmod u+x ./run.sh
chmod u+x ./runall.sh
```

Run individual benchmark

```bash
./run <library>
# ./run next-connect
```

Run all benchmarks

```bash
./runall
```

## Result

```
Machine: Linux 5.17.0-051700-generic x86_64 | 12 vCPUs | 16GB
Node: v18.0.0

express
Running 30s test @ http://localhost:3000/user/123
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 27.66ms 3.30ms 88.73ms 90.64%
Req/Sec 1.20k 137.40 2.61k 82.69%
430220 requests in 30.09s, 63.18MB read
Requests/sec: 14296.68
Transfer/sec: 2.10MB

http
Running 30s test @ http://localhost:3000/user/123
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 7.02ms 1.65ms 79.49ms 99.08%
Req/Sec 4.76k 413.57 5.64k 80.44%
1704802 requests in 30.03s, 212.98MB read
Requests/sec: 56765.13
Transfer/sec: 7.09MB

next-connect
Running 30s test @ http://localhost:3000/user/123
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 8.98ms 2.67ms 110.80ms 98.92%
Req/Sec 3.73k 370.41 6.44k 84.61%
1338233 requests in 30.05s, 167.19MB read
Requests/sec: 44531.36
Transfer/sec: 5.56MB
```
19 changes: 19 additions & 0 deletions bench/express.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import express from "express";

function one(req, res, next) {
req.one = true;
next();
}

function two(req, res, next) {
req.two = true;
next();
}

express()
.use(one, two)
.get("/", (req, res) => res.send("Hello"))
.get("/user/:id", (req, res) => {
res.end(`User: ${req.params.id}`);
})
.listen(3000);
12 changes: 12 additions & 0 deletions bench/http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createServer } from "http";

createServer((req, res) => {
req.one = true;
req.two = true;
if (req.url === "/") return res.end("Hello");
else if (req.url.startsWith("/user")) {
return res.end(`User: 123`);
}
res.statusCode = 404;
res.end("not found");
}).listen(3000);
22 changes: 22 additions & 0 deletions bench/next-connect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createServer } from "http";
import { createRouter } from "next-connect";

function one(req, res, next) {
req.one = true;
next();
}

function two(req, res, next) {
req.two = true;
next();
}

createServer(
createRouter()
.use(one, two)
.get("/", (req, res) => res.end("Hello"))
.get("/user/:id", (req, res) => {
res.end(`User: ${req.params.id}`);
})
.handler()
).listen(3000);
18 changes: 18 additions & 0 deletions bench/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "module",
"name": "bench",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"private": true,
"dependencies": {
"express": "^4.18.1",
"fastify": "^4.2.0",
"next-connect": "file:.."
}
}
17 changes: 17 additions & 0 deletions bench/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

server="$1"
url="$2"

NODE_ENV=production node $server &
pid=$!

printf "$server\n"

sleep 2

wrk -t12 -c400 -d30s http://localhost:3000/user/123

printf "\n"

kill $pid
9 changes: 9 additions & 0 deletions bench/runall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
printf "Machine: $(uname -s -r -m) | $(node -r os -p "\`\${os.cpus().length} vCPUs | \${Math.ceil(os.totalmem() / (Math.pow(1024, 3)))}GB\`")\n"
printf "Node: $(node -v)\n\n"
for path in *.js
do
file=${path##*/}
base=${file%.*}
./run.sh $base
done
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-connect",
"version": "1.0.0-next.0",
"version": "1.0.0-next.1",
"description": "The method routing and middleware layer for Next.js (and many others)",
"keywords": [
"javascript",
Expand Down