Blog
0% · 5 min read
Product·

The Cache That Knows Itself

Most caches are set-and-forget. You configure them at deploy time and hope the traffic matches your assumptions. QDKV doesn't work that way.

TL;DR

QDKV is a KV cache that watches its own hit rate, tombstone count, and load factor in real time — and adjusts without human intervention. It's 5.6× faster than Redis in pipeline mode, ships free with every EmergentDB account, and is already in production handling our own quota checks.

The problem with static tuning

Redis gives you maxmemory-policy and a handful of knobs. You set them at deploy time, your traffic pattern shifts three weeks later, and your hit rate tanks — silently, until you check a dashboard you probably forgot to set up.

The fundamental problem is that static configuration is a prediction. You're guessing what your access pattern will look like before you have any data. You're almost always wrong, and the cache has no way to correct you.

We built QDKV to solve this differently. Instead of asking you to predict access patterns upfront, the cache observes them continuously and adapts.

How it self-evolves

Every operation updates internal counters: hits, misses, sets, deletes, evictions. These aren't just for metrics — they're the input to the cache's own feedback loop.

self-monitor tick
// What QDKV tracks on every tick
{
  hit_rate:    94.2%,   // → good, no resize needed
  tombstones:  1,847,   // → above threshold → trigger sweep
  load_factor: 0.71,    // → approaching limit → pre-grow
  memory_mb:   128.4,   // → within budget
  evictions:   0        // → TTLs are well-tuned
}

When tombstone count — deleted or expired slots that haven't been reclaimed — crosses a threshold, the cache triggers a background sweep. When load factor approaches capacity, it pre-grows the hash table before performance degrades. When hit rate drops, the eviction policy adjusts.

None of this requires a restart or a config change. The cache is always tuned for right now, not for how you expected things to look at launch.

Hit rate as the cache learns

% hits over time after cold start — no config changes

Cold start at 41% — stabilizes to 94–96% within 4 hours as access patterns crystallize.

Tombstone count — automatic sweep

Deleted/expired slots that haven't been reclaimed — drops to zero on sweep

Threshold at 1,847 — background sweep fires automatically, hash table reclaimed in <1ms.

“Cold start at 41% hit rate. Stabilizes to 94–96% within 4 hours. No config changes.”

Then we benchmarked it against Redis

Redis 8.4 is the current stable release. We benchmarked against it directly — same hardware, same data set, warm cache, TCP connection reused. No connection pooling tricks, no pipelining advantage for either side.

The results surprised us.

Latency: QDKV vs Redis

p50 milliseconds, warm cache — lower is better

Redis 8.4QDKVup to 6.8× faster

Full results

OperationQDKVRedis 8.4Gain
GET (warm)0.08ms0.45ms5.6×
SET (warm)0.11ms0.52ms4.7×
MGET ×1000.31ms2.1ms6.8×
Pipeline ×10001.2ms6.7ms5.6×

p50 latency. Cloudflare Workers, warm isolate, same-region deployment. TCP connection reused.

GET and SET: 5–5.6× faster. The binary protocol eliminates RESP3 parsing overhead. A QDKV GET is a fixed-size frame decode — no tokenizer, no command dispatch table.

MGET ×100: 6.8× faster. This is where the binary protocol really shines. Redis batches RESP commands; QDKV uses a native multi-fetch frame that the server processes as a single SIMD scan.

Pipeline ×1000: 5.6× faster. At high throughput, Redis's single-threaded event loop becomes the bottleneck. QDKV's Swiss Table hash map is lock-free for reads.

Using it from Workers

If you have an EmergentDB account, QDKV is already available — 10K keys, no signup, same API key. The managed SDK routes through api.emergentdb.com so you don't need to run any infrastructure.

Node / Vercel / Cloudflare / any backend
import { QDKV } from '@emergentdb/qdkv';

// Same emdb_ key you already use for vectors
const kv = new QDKV({ apiKey: env.EMERGENTDB_API_KEY });

// Cache an embedding lookup
await kv.set(
  'embed:' + query,
  JSON.stringify(vector),
  { ttlMs: 300_000 }   // 5-minute TTL
);

// Read it back — null if expired or missing
const cached = await kv.get('embed:' + query);

// Batch fetch — one round-trip for N keys
const results = await kv.mget(['key:1', 'key:2', 'key:3']);

We eat our own cooking

The EmergentDB API uses QDKV internally to cache quota lookups. Every time a request comes in, instead of hitting the database to check your key count and plan limits, the gateway reads from QDKV first. The database only gets touched on a cache miss — roughly once every 30 seconds per tenant instead of once per request.

This means QDKV is load-tested against real production traffic before it's ever offered to customers. If it degrades, we feel it first. That's the only way we're comfortable shipping it.

Available now

01

Free with every account

Every EmergentDB account gets 10,000 QDKV keys at no cost — no opt-in, no separate signup. Log in and the QDKV widget is already showing your usage.

02

Same API key

Your emdb_ key authenticates for both vectors and QDKV. No new credentials, no new dashboard, no separate billing until you need more than 10K keys.

03

Launch ($29) and Scale ($99)

For production workloads: Launch unlocks 1M keys, Scale goes to 10M. Both are on the QDKV pricing page.

Questions

Things people ask about QDKV.

Why not just use Redis?

Redis is great. We used it too. But it has a separate server to operate, a RESP3 protocol overhead on every command, and no self-tuning. QDKV is 5–7× faster and zero-ops for managed users.

Is this production-ready?

Yes. It's handling EmergentDB's own quota cache right now under real production traffic. That's the bar we set before offering it to customers.

10K keys, free, already in your account.

Same API key. No new signup. Works from any Node server, Vercel function, Cloudflare Worker, or edge runtime.

Open Dashboard →