Skip to content
/ quickv Public

A fast, SQLite-backed key-value cache for Bun. No Redis required.

License

Notifications You must be signed in to change notification settings

brielov/quickv

Repository files navigation

quickv

A fast, SQLite-backed key-value cache for Bun. No Redis required.

Features

  • Zero dependencies - Uses Bun's built-in SQLite
  • Persistent storage - Data survives restarts
  • TTL support - Automatic expiration with lazy + periodic cleanup
  • Atomic operations - incr/decr are transaction-safe
  • Batch operations - mget/mset/mdel for bulk operations
  • Type-safe - Full TypeScript support

Installation

bun add quickv

Quick Start

import { Cache } from "quickv";

const cache = new Cache();

// Basic operations
cache.set("user:1", { name: "Alice", email: "alice@example.com" });
const user = cache.get<User>("user:1");

// With TTL (in seconds)
cache.set("session:abc", sessionData, 3600); // 1 hour

API Reference

Constructor

const cache = new Cache({
  path: "./cache.db", // Default: ":memory:" (in-memory)
  cleanupInterval: 60_000, // Default: 60000ms (1 min). Set to 0 to disable.
});

Basic Operations

Method Description
set(key, value, ttl?) Store a value with optional TTL in seconds
get<T>(key) Retrieve a value. Returns undefined if not found or expired
del(key) Delete a key
has(key) Check if a key exists and is not expired

TTL Management

Method Description
ttl(key) Get remaining TTL in seconds. Returns undefined if missing, null if no expiry
expire(key, ttl) Set/update expiry. Pass null to remove expiry. Returns false if key doesn't exist

Counters

cache.incr("views"); // 1
cache.incr("views"); // 2
cache.incr("views", 5); // 7
cache.decr("views"); // 6

Both preserve existing TTL on the key.

Batch Operations

// Set multiple values
cache.mset({ a: 1, b: 2, c: 3 }, ttl?);
cache.mset(new Map([["a", 1], ["b", 2]]));
cache.mset([["a", 1], ["b", 2]]);

// Get multiple values
const values = cache.mget<number>(["a", "b", "c"]); // Map<string, number>

// Delete multiple keys
cache.mdel(["a", "b"]);

Utility Methods

Method Description
keys(pattern?) List keys. Supports * and ? wildcards
size() Count of non-expired entries
clear() Delete all entries
cleanup() Manually remove expired entries. Returns count removed
close() Close database and stop cleanup timer

Pattern Matching

cache.set("user:1", "alice");
cache.set("user:2", "bob");
cache.set("post:1", "hello");

cache.keys("user:*"); // ["user:1", "user:2"]
cache.keys("*:1"); // ["user:1", "post:1"]

Persistence

// In-memory (default) - fastest, lost on restart
const cache = new Cache();

// File-based - persists across restarts
const cache = new Cache({ path: "./cache.db" });

SQLite WAL mode is enabled automatically for better concurrent performance.

Performance

Benchmarked on Apple M4 Pro:

~600,000 writes/sec
~1,650,000 reads/sec

When to Use

Use quickv when:

  • Single Bun instance
  • Need persistent caching without external dependencies
  • Want Redis-like API with zero setup

Use Redis when:

  • Multiple instances need shared cache
  • Need pub/sub or streams
  • Distributed systems

License

MIT

About

A fast, SQLite-backed key-value cache for Bun. No Redis required.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •