Stoolap/Node: A Native Node.js Driver That's Surprisingly Fast
Summary
Stoolap, a Rust SQL database, now has a Node.js driver. Benchmarks show it's significantly faster than SQLite for complex queries, offering MVCC, parallel execution, and a cost-based optimizer.
Stoolap brings Rust power to Node
Stoolap creator released a native Node.js driver this week that allows developers to embed the Rust-based SQL engine directly into JavaScript applications. The new package, @stoolap/node, uses NAPI-RS to provide direct access to the database without the overhead of an external HTTP server. This release marks a significant shift for the project, which began as a Go experiment before being rewritten entirely in Rust for better performance. The driver connects the Node.js process to the Stoolap engine through native bindings. This architecture eliminates the serialization delays usually found in database drivers that rely on network protocols. Developers can now use Stoolap as a high-performance alternative to SQLite in environments where complex queries are common. While SQLite remains the industry standard for embedded storage, Stoolap targets specific workloads that traditional B-tree databases struggle to handle. The engine includes features like Multi-Version Concurrency Control (MVCC) and a cost-based query optimizer. These tools allow the database to handle simultaneous reads and writes without the locking issues that often plague SQLite users.Benchmarks show significant performance gains
A comprehensive benchmark suite recently compared @stoolap/node against better-sqlite3, which is widely considered the fastest SQLite driver for Node.js. The tests involved 53 identical SQL operations performed on a dataset of 10,000 rows. Both databases ran entirely in-memory to ensure the hardware environment did not skew the results. Stoolap outperformed SQLite in 47 out of the 53 tests. The margins were not marginal in several key categories, particularly those involving analytical functions and complex filtering. SQLite only maintained its lead in six tests, primarily focusing on simple, single-row operations. The benchmark results highlighted several specific areas where Stoolap's architecture provides a clear advantage:- COUNT DISTINCT operations: Stoolap performed these queries 138x faster than SQLite.
- Subquery execution: Operations using EXISTS and IN clauses were 45x faster.
- Joins and aggregations: Complex multi-table queries showed a 12x to 20x improvement.
- Primary key lookups: SQLite remained 1.1x to 1.6x faster for single-row fetches.
Optimization strategies drive the speed
The speed difference stems from how Stoolap optimizes query execution at the engine level. Most embedded databases use a simple rule-based optimizer that follows a fixed set of logic. Stoolap uses a cost-based optimizer that estimates the processing requirements of different strategies before choosing the most efficient path. This optimizer is particularly effective for queries involving multiple conditions or joins. It can decide whether to use an index or perform a sequential scan based on the estimated volume of data. For subqueries, Stoolap employs semi-join optimization. It builds a HashSet from the subquery results and probes it, avoiding the row-by-row correlation that slows down SQLite. Parallel execution also plays a major role in these performance wins. Stoolap utilizes the Rayon work-stealing scheduler to distribute query tasks across all available CPU cores. Tasks like filtering, sorting, and hash joins scale automatically with the hardware. Node.js applications benefit from this because the heavy lifting happens in the background on the Rust side of the bridge.Embedded features for modern apps
Stoolap includes several advanced features that are rarely found in embedded SQL engines. One of the most prominent is temporal queries using the AS OF syntax. This allows developers to query the state of the database at a specific point in history. It simplifies the development of audit logs and "undo" features in productivity applications. The database also supports semantic query caching. This system identifies when a new query is logically identical to a previous one, even if the syntax differs slightly. By serving the result from the cache, the engine avoids redundant computation and disk I/O. This is particularly useful for dashboard applications that refresh the same data frequently. The MVCC implementation ensures that readers never block writers. In a typical SQLite setup, a long-running write operation can freeze read access to the database file. Stoolap manages multiple versions of data simultaneously, allowing the Node.js event loop to process async queries even during heavy write traffic. This makes the database more suitable for multi-user applications running on a single server.Integration with the Node ecosystem
The @stoolap/node API mirrors the patterns found in popular libraries like better-sqlite3. This design choice reduces the learning curve for developers moving from other embedded solutions. The driver supports both positional and named parameters to prevent SQL injection attacks. Developers can choose between synchronous and asynchronous APIs depending on their specific needs. The async methods run on the libuv thread pool, ensuring that the main Node.js event loop remains responsive during heavy database activity. The sync methods offer slightly lower latency and are intended for CLI tools or scripts where blocking the process is acceptable. Prepared statements are also supported for high-frequency queries. By using db.prepare(), developers can skip the parsing and optimization phase for repeated operations. This is a common optimization for "hot paths" in an application where every microsecond of latency counts.Persistence and data durability
While the benchmarks used in-memory configurations, Stoolap is designed for file-based persistence. It uses Write-Ahead Logging (WAL) to ensure data integrity during crashes or power failures. The Node.js driver allows developers to configure the durability level through connection strings. The full sync mode performs an fsync operation on every write, providing maximum data safety. A balanced mode performs batches of syncs during commits, which is the default setting for most applications. For scenarios where speed is more important than total durability, developers can disable fsync entirely to achieve maximum throughput. Stoolap also manages background snapshots to prevent the WAL file from growing indefinitely. This process happens automatically without interrupting the main application process. The database files are portable across different operating systems, making it easier to move data between development and production environments.Installation and platform support
The @stoolap/node package is available now on npm. The maintainers provide pre-built binaries for several major platforms, which means developers do not need to have a Rust toolchain installed on their local machines. Current support includes:- macOS: x64 and ARM64 (Apple Silicon)
- Linux: x64 and ARM64
- Windows: x64
Related Articles
LLMs generate wrong database queries that corrupt company revenue data
LLMs generate SQL queries that often run successfully but are semantically wrong, leading to dangerous data errors. Providing context via tools like MCP, AGENTS.md, or Agent Skills helps reduce these silent failures.
Developer abandons Rust web app after years, migrates to Node.js
A programmer's journey from Pascal to C, then web dev in PHP/Python, and finally Rust for a web app. Despite loving Rust's control and safety, they switched to Node.js due to faster iteration, better web ecosystem, and type-safe templates, concluding Rust excels in CPU-heavy tasks but Node.js is more practical for dynamic web development.
Stay in the loop
Get the best AI-curated news delivered to your inbox. No spam, unsubscribe anytime.
