Skip to content

A fast, high-speed ACID-based persistent cache layer with LRU, supporting sharding and TTL, automatic checkpoints, and simple integration.

Notifications You must be signed in to change notification settings

johanlabs/rust-scriba

Repository files navigation

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-scriba

Requires 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 a Statement.
  • 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 a Promise<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:

  • get and set latency.
  • Concurrent operations.
  • Latency percentiles (p50, p95, p99).
  • Mixed get/set operations.
  • 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.

About

A fast, high-speed ACID-based persistent cache layer with LRU, supporting sharding and TTL, automatic checkpoints, and simple integration.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published