Chapp is a lightweight, reproducible web API benchmarking suite. It runs the same CRUD endpoints across multiple stacks and generates a Markdown report for quick, apples-to-apples comparisons.
For Turkish, see README-TR.md.
- Stacks: Django (Ninja), Express, NestJS, Go (fasthttp), Next.js (API routes), FastAPI
- Database: PostgreSQL (shared) with the same minimal schema across services
- Endpoints (all services):
GET /api/healthGET /api/items?limit=...POST /api/itemswith JSON:{ "name": "..." }GET /api/items/{id}DELETE /api/items/{id}
- Benchmark script starts/warms services, performs read/write loads, and writes
benchmark_report.md.
python-django/: Django + Django Ninja API (ASGI via uvicorn) on:8001node-express/: Express API on:8002go-gin/: Go API usingfasthttprouter on:8003node-nest/: NestJS API on:8004next-app/: Next.js API routes (dev server) on:8005python-fastapi/: FastAPI on:8006db/schema.sql: Minimal Postgres schema used by servicesscripts/: Start/stop, DB prepare, and benchmark utilitiesbenchmark_report.md: Output report generated by the runnerexample_benchmark_report.md: Example output for reference
- PostgreSQL 13+ (CLI
psqlrecommended for auto-setup) - Node.js 18+ (recommended 20+)
- Python 3.10+
- Go 1.25+
- Bash shell
Default connection (override via env):
PGHOST=localhost,PGPORT=5432,PGUSER=bench,PGPASSWORD=123456,PGDATABASE=bench- The helper
scripts/db_prepare.shcan create the role/db and applydb/schema.sql. If your Postgres requires a superuser password, setPGSUPERUSERandPGSUPERPASS.
Example (optional):
export PGHOST=localhost PGPORT=5432 PGUSER=bench PGPASSWORD=123456 PGDATABASE=bench
# If needed for provisioning:
export PGSUPERUSER=postgres PGSUPERPASS=...
./scripts/db_prepare.sh
Install dependencies per service (one-time):
# Node services
( cd node-express && npm ci )
( cd node-nest && npm ci )
( cd next-app && npm ci )
# Python services
python3 -m venv python-django/.venv
source python-django/.venv/bin/activate
pip install -q django django-ninja uvicorn psycopg2-binary
deactivate
python3 -m venv python-fastapi/.venv
source python-fastapi/.venv/bin/activate
pip install -q fastapi "uvicorn[standard]" sqlalchemy "psycopg[binary]"
deactivate
# Go service: ensure Go toolchain installed (no extra deps beyond go.mod)
Chapp ensures DB readiness, starts services if needed, warms them up, and generates a report.
./scripts/run_benchmarks.sh
Environment controls:
BENCH_CONCURRENCY(default50)BENCH_READ_REQUESTS(default500)BENCH_WRITE_REQUESTS(default100)BENCH_REPORT_PATH(default./benchmark_report.md)
Example:
BENCH_CONCURRENCY=100 BENCH_READ_REQUESTS=2000 BENCH_WRITE_REQUESTS=400 \
./scripts/run_benchmarks.sh
The report is written to benchmark_report.md with a summary table and per‑service details. See also example_benchmark_report.md.
Start (each binds to 127.0.0.1):
./scripts/start_django.sh # http://127.0.0.1:8001
./scripts/start_node.sh # http://127.0.0.1:8002 (Express)
./scripts/start_go.sh # http://127.0.0.1:8003 (fasthttp)
./scripts/start_nest.sh # http://127.0.0.1:8004 (NestJS)
./scripts/start_next.sh # http://127.0.0.1:8005 (Next.js dev)
./scripts/start_fastapi.sh # http://127.0.0.1:8006
Stop any previously backgrounded services (best-effort):
./scripts/stop_background_servers.sh
# Health
curl -s http://127.0.0.1:8002/api/health
# List items
curl -s "http://127.0.0.1:8002/api/items?limit=10"
# Create item
curl -s -X POST http://127.0.0.1:8002/api/items \
-H 'Content-Type: application/json' \
-d '{"name":"hello"}'
- All services target the same Postgres schema (tables are created on startup or via migrations/schema.sql).
- The Go service lives under
go-ginbut usesfasthttprouter for performance testing. - Next.js runs in dev mode for simplicity; production builds may behave differently.
- Results will vary per machine and background load; Chapp is designed for relative comparisons under similar conditions.