Redis keeps everything in RAM. VeltrixDB doesn't have to.
Redis's speed comes from one thing: all data lives in memory. That's a real advantage — and a real cost ceiling. VeltrixDB stores values on NVMe with a DRAM index and LIRS cache, so hot data is still sub-millisecond and cold data doesn't cost you $18/GB-month.
This is not a "Redis killer" comparison. Redis is the right choice for millions of workloads. But there is a specific class of problem — large keyspaces under sustained write pressure — where Redis's architecture produces a problem it cannot solve cleanly: the GC death spiral.
When Redis is under heavy write load, background rewriting of AOF or RDB pauses cause P99 to spike. Engineers work around this with replica reads, manual fork tuning, and alert rules. VeltrixDB was designed so the spiral can't start — not worked around after the fact.
The P50 is similar. The P99 shape is not.
Both databases are fast. The difference is in the tail — and what happens to that tail under sustained write load over 30 minutes, not 30 seconds.
| Percentile | Redis (AOF on) | VeltrixDB | What's happening |
|---|---|---|---|
| P50 read | ~100–200 µs | ~220 ns | VeltrixDB: LIRS DRAM hit, no network round-trip overhead at local access |
| P99 read (sustained) | 1–50 ms (spikes) | ~510 µs | Redis: AOF rewrite / fork pauses cause periodic spikes. VeltrixDB: bounded by three-tier GC ceiling |
| P50 write | ~200–400 µs | ~17 µs | VeltrixDB: group-commit WAL amortizes fdatasync across 1024-entry batch |
| P99 write | varies with AOF | ~42 µs (stable) | VeltrixDB P99 does not drift over 30 min sustained load — GC tiering absorbs pressure |
| P99 under GC pressure | unpredictable | < 1 ms ceiling | VeltrixDB: RT-class I/O priority means reads preempt GC at NVMe hardware queue level |
Redis P99 numbers above reflect production reports from teams running AOF with appendfsync everysec under mixed read/write load. Your numbers depend on instance size, fork latency, and background save frequency.
The GC death spiral. When read latency rises, Redis GC pauses to protect reads. Garbage accumulates. Cache miss rate rises. Reads stay slow. GC stays paused. The spiral has no exit without operator intervention. VeltrixDB's three-tier GC has an emergency threshold at 65% garbage where it bypasses read-pressure signals unconditionally — the spiral cannot form.
RAM is 15× more expensive per gigabyte than NVMe.
This math doesn't change. At small scale it doesn't matter. At 100M+ keys, it's the difference between a $400/month database and a $4,000/month one.
| 10M keys · 128B values |
Redis: ~2.5 GB RAM → r6g.xlarge ~$150/mo VeltrixDB: ~1.5 GB NVMe → fits on any local-SSD instance |
| 100M keys · 128B values |
Redis: ~25 GB RAM → r6g.4xlarge ~$1,100/mo VeltrixDB: ~15 GB NVMe → n2-standard-8-lssd ~$280/mo |
| 1B keys · 128B values |
Redis: ~250 GB RAM → r6g.metal cluster ~$6,000–8,000/mo VeltrixDB: 160 GB NVMe across 3 nodes → ~$900/mo |
VeltrixDB's block packing puts 26 records into a single 4 KB NVMe block for 128-byte values. Legacy one-record-per-block wastes 96% of every sector. At 1 billion keys this is the difference between 160 GB and 4,096 GB of storage required.
If your dataset fits comfortably in RAM and you're not cost-constrained — Redis is the simpler choice. If your keyspace is growing and the RAM bill is growing with it, that's the signal to benchmark VeltrixDB against your workload.
Every byte should land on NVMe exactly once.
Write amplification is how many times a byte gets written to storage for every one byte of user data. At 1× you're paying for your data once. At 30× you're paying thirty times — in SSD wear, in NVMe IOPS, and in latency tail.
| Redis (AOF rewrite) | 2–5× — AOF rewrite rewrites the full dataset to a new file |
| RocksDB / LevelDB | 10–30× — LSM compaction sorts and rewrites every key multiple times across levels |
| VeltrixDB | ~1.0× — Values append-once to Value Log, never sorted, never rewritten. GC only reclaims dead space. |
VeltrixDB uses WiscKey key-value separation: the in-memory ART index holds only key metadata (offset + disk index + value size). Values go directly to an append-only Value Log on NVMe. Compaction never touches live data — it only punches holes in dead space. Write amplification drops to approximately 1.0× regardless of write rate or dataset size.
What this means for SSDs. At 100K writes/sec sustained, 1.0× write amp writes 12.8 MB/s to NVMe. At 10× write amp (RocksDB default workload) that's 128 MB/s — you'll wear out your SSDs 10× faster, pay for more IOPS provisioning, and see your P99 spike during every compaction cycle.
Redis is the right choice in these situations.
This is not a takedown of Redis. It is the right tool for a large number of workloads. Knowing when not to migrate is as important as knowing when to.
- Your full dataset fits comfortably in RAM — if you have 5M keys at 256 bytes, Redis's DRAM-only path has zero NVMe latency on any read. The advantage of VeltrixDB's cache tier disappears.
- You need pub/sub, streams, sorted sets, or Lua scripting — Redis has a rich data structure model built over decades. VeltrixDB is a key-value store. If your application relies on
ZRANGEBYSCORE,XREAD, or Lua, stay on Redis. - Your team already runs Redis and has no latency complaints — operational familiarity is real value. Don't fix what isn't broken.
- You need a fully-managed hosted service today — Redis Cloud, ElastiCache, Upstash, and Momento all exist and are production-hardened. VeltrixDB's managed offering is on the roadmap.
- Your workload is write-once, read-many with no GC pressure — if you never overwrite keys, Redis GC never runs, and the death spiral never starts.
The specific problems VeltrixDB was built to solve.
VeltrixDB earns its place when your dataset is outgrowing your RAM budget, when your production dashboards show Redis P99 spikes you can't explain, or when you're running on Kubernetes with local NVMe and want first-class tooling.
- Your dataset doesn't fit in RAM — or fitting it costs too much — VeltrixDB's LIRS cache keeps hot keys in DRAM and cold keys spill to NVMe transparently. The cache hit rate at 1 billion keys is ≥98% under Zipfian access.
- Unpredictable P99 under sustained write pressure — if your Redis P99 spikes during AOF rewrite, keyspace expiry, or background save, VeltrixDB's three-tier GC and RT-priority NVMe queue enforce a hard P99 ceiling that doesn't drift.
- High-concurrency bulk writes — MultiPut with 1024-entry batches achieves ~446K batch ops/s per node. The lock-free VLog append path (atomic offset reservation, no mutex) means throughput ceiling is NVMe IOPS, not lock contention.
- Kubernetes with local NVMe SSDs — first-class Kubernetes Operator, Helm chart, and GKE local SSD auto-detection. The nvme-prep DaemonSet handles hugepages, scheduler tuning, and NUMA pinning automatically.
- Write amplification and SSD cost matter — if you're watching your NVMe wear counter on cloud SSDs, 1.0× vs 10–30× is the difference between replacing SSDs annually vs quarterly.
- You need predictable latency at scale — not just at P50 — the benchmark goal was zero GC emergency runs across 30 minutes at 9M ops/sec combined. That's the guarantee the architecture is built around.
Everything side by side, nothing hidden.
An honest matrix. We've marked items we're still building as roadmap rather than pretending they exist.
| Feature | Redis | VeltrixDB |
|---|---|---|
| In-memory P50 (< 1 µs) | ✓ | ✓ 220 ns |
| Predictable P99 under writes | ⚠ spikes | ✓ bounded |
| NVMe storage tier | — | ✓ |
| Write amplification ~1× | — | ✓ |
| GC cannot be permanently paused | — | ✓ three-tier |
| Pub/Sub | ✓ | — |
| Sorted sets / ZRANGEBYSCORE | ✓ | — |
| Streams (XREAD/XADD) | ✓ | — |
| Lua scripting | ✓ | — |
| Atomic CAS / INCR / DECR | ✓ | ✓ |
| TTL / key expiry | ✓ | ✓ |
| Encryption at rest (AES-256-GCM) | ✓ | ✓ |
| TLS in transit | ✓ | ✓ |
| Multi-node replication | ✓ | ✓ async/quorum/strong |
| Kubernetes Operator | ⚠ third-party | ✓ first-class |
| Prometheus metrics | ✓ | ✓ |
| Change data capture (CDC) | — | ✓ built-in |
| Go / Python / Node / Rust / C++ SDKs | ✓ | ✓ |
| RESP protocol compatibility | ✓ | roadmap |
| Managed cloud service | ✓ | roadmap |
One connection string swap for most workloads.
VeltrixDB's text protocol maps directly to Redis's most common commands. For GET/SET/DEL workloads, switching is a client library change, not an application rewrite.
Try it in 30 seconds
# Linux / Windows docker run -p 9000:9000 ghcr.io/veltrixdb/veltrixdb:latest # Mac (Apple Silicon) docker run --platform linux/amd64 -p 9000:9000 ghcr.io/veltrixdb/veltrixdb:latest # Test — same semantics as Redis SET/GET echo -e "PUT hello world\nGET hello\nPING" | nc localhost 9000
SDK migration
# Before (redis-py) import redis r = redis.Redis(host='localhost', port=6379) r.set('key', 'value') val = r.get('key') # After (veltrixdb-python) import veltrixdb r = veltrixdb.Client(host='localhost', port=9000) r.put('key', 'value') val = r.get('key')
// Before (ioredis) const Redis = require('ioredis') const r = new Redis({ host: 'localhost', port: 6379 }) await r.set('key', 'value') // After (veltrixdb-client) const VeltrixDB = require('veltrixdb-client') const r = new VeltrixDB({ host: 'localhost', port: 9000 }) await r.put('key', 'value')
RESP protocol compatibility (so redis-cli works against VeltrixDB unchanged) is on the roadmap. Once available, the migration path becomes a single connection string update with zero code changes.
Recommended migration strategy. Run VeltrixDB in shadow mode — dual-write to both Redis and VeltrixDB for two weeks, compare read results, validate latency numbers against your actual key distribution. Cutover when the shadow reads match. This is zero-risk and gives you real-world latency data before you commit.