slang

Benchmarks

Every cross-language run, including the ones slang loses.

Markdown version · llms.txt · api.json

slang is measured against C, Go, Rust, C#, Java, Python, Bun and Node.js by bench/suite: the same SQL, the same response contracts, the same dataset, and a conformance gate that runs before anything is timed — a language that fails to build or fails conformance is reported as failed, not measured, so a number here means the implementation actually did the work, not just that it ran.

Two tiers: light (raw HTTP connection handling, CPU + allocation throughput) and heavy (a Postgres-backed JSON API and a big-data batch job). Full contract in bench/SPEC.md. The full record below is reproduced verbatim from bench/RESULTS.md, including the runs where slang loses and the runs that are only partial.

RPS alone is not a win. A result worth trusting needs throughput considered alongside tail latency and memory together, measured on a dedicated host at the scale the SPEC calls for — not whichever single number happens to flatter one runtime. Benchmarks that quote only the number that flatters them are the reason nobody believes benchmarks.

Also measured #

Beyond the cross-language comparison, stress_test/ holds a scaling suite for slang on its own: request-count scaling from 10k to 100k, concurrency scaling to 2,000 connections, per-endpoint characterisation, a breaking-point probe, a soak test, CPU profiles, and a concurrent-task curve with no network in the way at all. Its write-up is stress_test/reports/stress_report.html.

Cross-language suite — interim results (light tier only)#

This is a partial run, published early. It covers only the light tier (http-static, compute) of the suite defined in bench/SPEC.md: raw connection handling and CPU + allocation throughput, with no database and no JSON in the loop. The heavy tier (a Postgres-backed JSON API and a big-data batch job — the workloads that exercise a driver, a connection pool, and a JSON codec under load) was aborted partway through a ROUNDS=3 run to stop runaway compute spend, and is not included here. A full run, heavy tier included, is queued; this page will be replaced when it lands.

The host was undersized for a publish-grade run. 4 vCPUs / 15 GiB RAM on Docker overlay storage, run via a Cursor background agent — well below the 16+ cores / 64 GiB+ / local NVMe, dedicated-host bar bench/CURSOR.md sets for a result meant to be trusted. Absolute numbers here (a 4-core box serving both the app and the load generator and Postgres on the same four cores) are lower and noisier than a dedicated box would give; treat rankings as a rough first read, not a final word.

Shown here: C#, Java, Go, Rust, Bun, Node.js, and slang. The suite also measures C and Python on every run (see the run's own results.json for those), but this page's comparison set is restricted to the seven above.

The suite gates every language behind a conformance check before measuring it (bench/suite/lib/conformance.py) — a language that fails to build or fails conformance is reported as failed, not measured, so a number here means the implementation actually did the work, not just that it ran. All nine languages passed the light-tier gate on this run.

Machine#

fieldvalue
date (UTC)2026-09-17 20:34
OS / kernelUbuntu 24.04.4 LTS, 6.12.94+
CPUIntel Xeon (cloud vCPU), 4 cores, 1 thread/core, 1 socket
RAM15 GiB, no swap
virtualizationDocker (overlay storage)
CPU splitserver 0-1 (2 cores), load generator 2, db 3 (unused by the light tier)
rounds3
gogo1.24.1 linux/amd64
rustc1.95.0
dotnet10.0.401
java / javacOpenJDK 21.0.12
bun1.2.5
nodev22.14.0
wrkdebian/4.1.0-4build2 \[epoll\]
commit measured0fad8dcc9bf191519fe3a15b1eb6e56ef8715aab

Run id 20260917T203432Z-cursor-scaled20. Full env.json / results.json / raw logs are in the PR this run shipped in.

compute#

CPU-bound: prime counting plus small allocations across many concurrent tasks (bench/suite/light/compute/*, CC_TASKS=1000 CC_WORK=20000 CC_ALLOC=200), every language checked against Go's total_primes/total_alloc_sum for correctness before timing counts. Median of 3 rounds, sorted fastest first.

langwall mstasks/speak RSS MBCPU s
rust1,49866710.12.73
slang1,75756913.33.21
bun1,78556088.43.21
node1,80155581.13.58
java1,99050272.53.69
csharp2,07248241.73.60
go2,6373798.35.22

http-static#

GET /, a fixed 200-byte body, wrk -c{50,200} -d30s --latency. Median of 3 rounds, sorted by req/s (fastest first).

None of these implementations parse an HTTP request -- every language's http-static entry is a raw-socket responder (slang's is bench/http/main.sl/go_raw's shape; see bench/http/README.md's axis table). This tier answers "how fast is the socket layer," not "what does a real HTTP server cost" -- bench/run_http_realserver.sh is the harness for that question, and it is not this one.

50 connections#

langreq/sp50 msp99 mspeak RSS MBCPU cores
slang39,8570.331.012.91.03
java38,9420.361.14125.61.30
go38,4390.301.069.61.12
bun38,0430.271.19146.00.73
rust38,0210.260.973.21.22
csharp33,0300.311.1640.01.86
node29,1901.604.26184.61.64

200 connections#

langreq/sp50 msp99 mspeak RSS MBCPU cores
bun38,1171.304.65238.30.88
rust37,5951.003.683.61.16
java37,0171.164.13124.31.29
go36,4921.134.139.81.09
slang35,5531.314.444.21.04
csharp35,3051.204.3540.81.78
node29,5416.669.28205.51.60

Reading these numbers#

All seven are within a fairly narrow band on raw throughput at this scale — a few thousand req/s apart on a 4-core box is not a strong signal either way, and Node's lower numbers here are a known shape for its single-process baseline HTTP server under this harness, not a general Node.js finding. Memory is the more legible gap: slang, Rust, Go and C sit in single-digit-to-low-double-digit MB; Bun, Node, and Java's JIT-warmed footprint run into the hundreds. None of this substitutes for the heavy tier, which is where a driver, a connection pool, and JSON encode/decode under sustained load will separate these runtimes more than an empty HTTP response does.

Known gaps in this run#

  • Heavy tier not run. No api (Postgres-backed JSON service) or batch (big-data CSV aggregate) numbers exist yet for any language.
  • Java's api implementation failed conformance on this host (no bench.Main sources were present for the Maven build to compile) — irrelevant to the light-tier numbers above, which don't touch it, but it means Java's heavy-tier numbers aren't just missing, they're currently broken and need a fix before the next run.
  • Host is a 4-core cloud VM sharing its cores between the server under test, the load generator, and Postgres — see bench/CURSOR.md for why that matters and what a publish-grade host looks like.