@johanlabs/rust-scriba
v0.5.7
Published
Multi-tenant, high-performance asynchronous cache library for Node.js. Uses a persistent, sharded SQLite backend (WAL mode) with automatic checkpointing and per-key TTL support, offering a drop-in alternative to Redis for many caching scenarios.
Readme
rust-scriba
Rust Scriba is a multi-tenant cache library written in Rust with Node.js bindings.
It provides a persistent SQLite LRU cache with sharding, TTL support, automatic checkpoints, and easy integration to replace Redis in many scenarios.
🚀 Features
- Multi-tenant cache with sharding to reduce contention.
- Persistent SQLite backend (WAL mode) with automatic checkpointing.
- Supports TTL per key.
- Asynchronous operations for high performance.
- Drop-in cache replacement for Node.js.
- Benchmark included to compare with Redis.
🔧 Installation
npm install @johanlabs/rust-scribaRequires Node.js 20+ and Rust (
cargo) to build the native module.
🏁 Initialization
Before using the cache, initialize the system:
const { initCacheSystem, scribaPath } = require("@johanlabs/rust-scriba");
// Set the base path for tenant databases
scribaPath(".scriba");
// Initialize the cache (automatic checkpointing)
initCacheSystem();📦 Using the Database Class
You can use the Database class to manage tenants and execute queries with caching.
const { Database } = require("@johanlabs/rust-scriba");
const db = new Database("tenant1", { ttl: 10000, path: ".scriba" });
(async () => {
// Run a SELECT and return one row
const row = await db.get("SELECT * FROM my_table WHERE id=1");
console.log(row);
// Run a SELECT and return all rows
const rows = await db.all("SELECT * FROM my_table");
console.log(rows);
// Run an INSERT/UPDATE/DELETE
const result = await db.run("INSERT INTO my_table (name) VALUES ('Alice')");
console.log(result);
})();📄 Methods
db.prepare(sql)→ returns aStatement.db.get(sql)→ returns a JSON object with one row.db.all(sql)→ returns an array of JSON rows.db.run(sql)→ executes changes (INSERT, UPDATE, DELETE).db.close()→ closes the tenant (optional, currently empty).
⚡ Direct Cache Usage
You can also interact with the cache directly:
const { query } = require("@johanlabs/rust-scriba");
// Direct GET/SET
await query("tenant1", "SELECT * FROM my_table", 5000);query(tenant, sql, ttl_ms?)→ returns aPromise<string>containing JSON result.
📊 Benchmark
A benchmark is included to compare RustCache against Redis:
const { runBenchmark } = require("@johanlabs/rust-scriba");
(async () => {
const results = await runBenchmark();
console.log(JSON.stringify(results, null, 2));
})();The benchmark measures:
getandsetlatency.- Concurrent operations.
- Latency percentiles (
p50,p95,p99). - Mixed
get/setoperations. - Large value handling (100 KB payloads).
🛠 Configuration
Global configurations are defined in Rust, but you can adjust constants internally:
tenant_cache_limit: max items per tenant.global_cache_limit: global cache limit.shard_count: number of shards per tenant.default_ttl_secs: default TTL.checkpoint_interval_secs: interval for automatic checkpoints.checkpoint_retry_attempts&checkpoint_retry_delay_ms: retry settings for checkpointing.
💡 Notes
- Each tenant is identified by its
tenantId(typically the DB path). - TTL is optional and sets cache expiration.
- SQLite persistence ensures data survives restarts.
- Supports asynchronous and concurrent operations with high throughput.
