Skip to content

SQLite Driver Benchmark: better-sqlite3 vs node:sqlite

SQG (SQL Query Generator) is a build-time tool that generates type-safe database access code from annotated SQL files. You write SQL queries with simple comment annotations, and SQG generates TypeScript or Java code with full type safety—no ORM required, just pure SQL with generated types.

We’ve added support for Node.js’s built-in SQLite module (node:sqlite) as an alternative to better-sqlite3. To help you choose the right driver, we ran comprehensive benchmarks comparing both options using SQG-generated code.

  • better-sqlite3 is 20-39% faster for read operations
  • Write operations are essentially equal (better-sqlite3 slightly ahead by 1-4%)
  • node:sqlite requires zero external dependencies
  • My recommendation: Use better-sqlite3, maybe node:sqlite for zero-dependency requirements

The de facto standard for SQLite in Node.js. It’s a mature, well-optimized native addon that’s been battle-tested in production for years.

generator: typescript/sqlite # or typescript/sqlite/better-sqlite3

Node.js 22 introduced a built-in SQLite module. It’s still experimental but offers zero-dependency SQLite access.

generator: typescript/sqlite/node

We tested both drivers with:

  • 10,000 users and 500,000 posts (50 per user)
  • Optimized pragma settings (WAL mode, 64MB cache, memory-mapped I/O)
  • Various query patterns: simple selects, JOINs, aggregates, inserts, updates

Note: The better-sqlite3 API is synchronous, we compared it against the synchronous API of node:sqlite.

  • Node.js: v25.3.0
  • Platform: Linux x64
  • CPU: 12th Gen Intel Core i9-12900K (24 cores)
  • Memory: 31.07 GB

Both databases used these settings:

PRAGMA journal_mode = WAL; -- Write-Ahead Logging
PRAGMA synchronous = NORMAL; -- Balance safety/speed
PRAGMA cache_size = -64000; -- 64MB cache
PRAGMA temp_store = MEMORY; -- Temp tables in memory
PRAGMA mmap_size = 268435456; -- 256MB memory-mapped I/O

SQLite Driver Benchmark Report

Comparing better-sqlite3 vs node:sqlite

System Information

Node.js Versionv25.3.0
Platformlinux
Architecturex64
CPU12th Gen Intel(R) Core(TM) i9-12900K
CPU Cores24
Total Memory31.07 GB

Summary

Operation better-sqlite3 node:sqlite Winner Multiplier
getAllUsers 292 ops/s 243 ops/s better-sqlite3 1.20x
getUserById 737,634 ops/s 563,591 ops/s better-sqlite3 1.31x
getUserByEmail 547,567 ops/s 449,381 ops/s better-sqlite3 1.22x
countUsers (pluck) 480,932 ops/s 344,879 ops/s better-sqlite3 1.39x
getPostsByUser 44,106 ops/s 35,542 ops/s better-sqlite3 1.24x
getPublishedPosts (JOIN) 25 ops/s 25 ops/s better-sqlite3 1.02x
getPostWithAuthor (JOIN :one) 435,409 ops/s 359,493 ops/s better-sqlite3 1.21x
countPostsByUser (pluck) 537,029 ops/s 417,325 ops/s better-sqlite3 1.29x
insertUser 42,859 ops/s 42,604 ops/s better-sqlite3 1.01x
updatePostViews 104,811 ops/s 100,631 ops/s better-sqlite3 1.04x

SQG can generate code for both drivers from the same SQL file, making it easy to benchmark or switch drivers:

version: 1
name: my-app
sql:
- files:
- queries.sql
gen:
- generator: typescript/sqlite/better-sqlite3
output: ./src/db-better-sqlite3.ts
- generator: typescript/sqlite/node
output: ./src/db-node-sqlite.ts

This lets you:

  • Benchmark with your actual queries - See real-world performance differences
  • Switch drivers without changing SQL - Just update your imports
  • A/B test in production - Run both and compare

The benchmark code is available in our examples repository:

Terminal window
git clone https://github.com/sqg-dev/sqg
cd sqg/examples/typescript-sqlite-benchmark
pnpm install
pnpm generate
pnpm bench

This will generate an HTML report with detailed bar charts and system information. You can run it on your own hardware to see how the drivers perform in your environment.

I’ve been a long-time fan of better-sqlite3 and have used it extensively in production. After running these benchmarks, I’m sticking with it.

The great news is that SQG supports both generators, so you can easily benchmark with your actual queries and make an informed decision. For me, better-sqlite3 remains the default choice—it’s proven, fast, and reliable.


Have questions or feedback? Open an issue on GitHub.