Skip to main content

Benchmarks

Lesan is built for performance: a client-driven projection model that embeds relationships inside documents means reads need a fraction of the queries other stacks require, and the framework adds almost no overhead on top of the official MongoDB driver. These benchmarks quantify that across the three supported runtimes.

HTTP Server Throughputโ€‹

These benchmarks measure the raw HTTP throughput of Lesan's server using autocannon โ€” 100 concurrent connections for 10 seconds per scenario.

Scenariosโ€‹

  • Hello World (Sync) โ€” a simple endpoint returning a static JSON object.
  • Async Task (10ms delay) โ€” an endpoint that simulates a 10ms asynchronous database or network call before returning.
  • Echo Payload โ€” an endpoint that parses an incoming JSON payload and echoes a property back.

Resultsโ€‹

RuntimeScenarioReq/SecLatency (ms)Errors
Node.jsHello World (Sync)~2,99132.920
Node.jsAsync Task (10ms delay)~3,28729.910
Node.jsEcho Payload~3,24030.350
BunHello World (Sync)~10,6988.880
BunAsync Task (10ms delay)~10,5629.000
BunEcho Payload~10,7138.870
DenoHello World (Sync)~8,31611.530
DenoAsync Task (10ms delay)~10,1479.390
DenoEcho Payload~10,2949.240

Analysisโ€‹

  • Bun provides the highest raw HTTP throughput and the lowest latency, consistently handling over 10,500 requests per second.
  • Deno is a very close second, especially in asynchronous and payload-parsing scenarios, handling around 10,000 requests per second.
  • Node.js is the baseline, handling around 3,000 requests per second. While slower than Bun and Deno, it remains highly stable and reliable for production workloads.

ODM Operationsโ€‹

These benchmarks measure the performance of Lesan's core ODM logic. The tests perform operations on 1,000 documents using an in-memory MongoDB instance (mongodb-memory-server).

Scenariosโ€‹

  • insertOne (Sequential) โ€” inserting 1,000 documents one by one in a loop.
  • insertMany (Batch) โ€” inserting 1,000 documents in a single batch operation.
  • find (Fetch All) โ€” fetching 1,000 documents in a single query.
  • updateOne (Sequential) โ€” updating 1,000 documents one by one in a loop.
  • deleteOne (Sequential) โ€” deleting 1,000 documents one by one in a loop.

Results (Operations Per Second)โ€‹

OperationNode.js (ops/sec)Bun (ops/sec)Deno (ops/sec)
insertOne (Sequential)~1,679~1,764~2,092
insertMany (Batch)~33,737~32,041~27,145
find (Fetch All)~3,173~2,508~3,017
updateOne (Sequential)~1,880~2,131~2,335
deleteOne (Sequential)~1,092~902~1,162

Analysisโ€‹

  • Batch Operations: insertMany is exponentially faster than sequential inserts across all runtimes, highlighting the efficiency of MongoDB's bulk operations. Node.js slightly edged out the others in batch insertion speed.
  • Sequential Operations: Deno and Bun generally outperform Node.js in sequential operations (insertOne, updateOne, deleteOne), likely due to faster event loop execution and Promise resolution in V8/JavaScriptCore.
  • Overall: The ODM performance is heavily bound by the MongoDB driver and the database itself. Lesan's abstraction layer adds minimal overhead, ensuring that database operations remain fast regardless of the chosen runtime.

Reading Data Is Where Lesan Winsโ€‹

The numbers above are single-operation throughput. Where Lesan's architecture really shines is data retrieval with relationships: because related documents are embedded inside their parent (see What Is the Relationship Really?), a country arrives with its cities and users already inside it โ€” one request to the database instead of three. The benchmark compares this head-to-head against traditional stacks:

  • Lesan returns data to the client 1,168% faster than prisma-express-rest (Postgres).
  • 1,417% faster than prisma-express-graphql (Postgres).
  • 4,435% faster than mongoose-express-rest (unsorted query).
  • 72,289% faster than mongo-express-rest (unsorted query).
  • 298,971% faster than mongoose-express-rest (with sort).

How to Run Benchmarksโ€‹

You can run these benchmarks yourself using the scripts provided in the repository. Ensure you have autocannon installed globally or available via npx, and that you have Node.js, Bun, and Deno installed on your system.

# Run all benchmarks
npm run bench

# Run only HTTP benchmarks
npm run bench:http

# Run only ODM benchmarks
npm run bench:odm