A Redis-compatible in-memory data store, written from scratch in Rust.
Moon is a clean-room Rust rewrite of a Redis-compatible in-memory data
store with first-class AI primitives. It speaks the Redis wire protocol
(RESP2/RESP3) and implements 250+ commands — every standard Redis data
type plus native FT.* vector + BM25 search, GRAPH.* Cypher, TXN.*
cross-store ACID, workspaces, durable message queues, bi-temporal MVCC,
and an embedded web console. Any Redis client connects out of the box.
Primary target is Linux with io_uring (monoio); a tokio runtime is
available for portability. macOS is a first-class development platform
(kqueue via monoio); production should target Linux (see
docs/PRODUCTION-CONTRACT.md Tier 1/2).
Production-grade architecture, pre-1.0 maturity. Single-node Moon is recommended for production caching, AI (vector / graph / feature-store) workloads, and Redis-compatible OLTP. Multi-node clustering and multi-shard master PSYNC are alpha — see Production readiness for the honest GA matrix. Wire protocol and on-disk format are LTS as of v0.2 (
docs/STORAGE-FORMAT-V1.md); CLI flags may evolve until v1.0. Open an issue if something breaks.
- Why Moon — the architecture in six bullets
- Install — packages, one-liner, Docker, source
- Quick start — build, run, connect, config
- Benchmarks — headline numbers (full report →)
- Moon vs Redis vs Valkey — pick the right one (deep dive →)
- Features at a glance — the full command surface
- Web console — embedded 7-view UI
- Production readiness — what's GA, what isn't
- Documentation — the full doc map
- Development · Credits · License
See Design Advantages for the full architecture story with diagrams — memory engine, persistence, vector, graph, and how they compose.
- Thread-per-core, zero shared state. Each shard owns its event loop, DashTable, WAL writer, and Pub/Sub registry. No global locks; cross-shard dispatch is a lock-free SPSC channel.
- Dual runtime. Monoio (
io_uringon Linux,kqueueon macOS) for peak throughput; Tokio for portability and CI. Same binary, feature-gated. - Forkless persistence. RDB snapshots iterate DashTable segments incrementally — no
fork(), no COW memory spike. AOF is a per-shard WAL v3 with batched fsync; the advantage over Redis grows with pipeline depth. - Tiered disk offload — for data AND engines. Keys evicted under
maxmemoryspill to NVMe instead of being deleted, with async write and read-through; idle vector-index segments demote HOT→WARM (mmap)→COLD (unloaded stub, reload-on-search) and give the memory back — measured −26% process RSS on a 40K×768d corpus with identical search results after reload. 100% crash recovery across all tiers. - Multi-tenant isolation that's actually enforced. Logical dbs get their own
FT.*/graph/full-text indexes (db 1's indexes are invisible to db 0 — across shards, restarts, and recovery), per-db memory quotas (--db-maxmemory) with Redis-style deny-OOM semantics (shrink commands always pass — a tenant can never wedge itself), and workspace key-prefix namespaces on top. - Memory-optimized types.
CompactKey(23-byte SSO),CompactValue(16-byte SSO with inline TTL),HeapString, B+ tree sorted sets, and per-request bumpalo arenas — 27–35% less RSS than Redis at 1 KB+ values. - AI-native, in-core. Vector search (HNSW + TurboQuant), BM25 full-text with three-way RRF hybrid fusion, a Cypher property-graph engine, cross-store ACID, workspaces, durable queues, and bi-temporal MVCC — one binary, no module loader.
Moon ships signed, checksummed packages for Linux, macOS, and Windows. All artifacts are listed on the latest release page.
Linux / macOS — one-liner (detects OS/arch, verifies SHA256 against the signed SHA256SUMS.txt, installs to ~/.local/bin; Linux x86_64 gets the io_uring monoio build, aarch64/macOS get tokio):
curl -fsSL https://raw.githubusercontent.com/pilotspace/moon/main/install.sh | sh
# pin: VERSION=v0.6.0 INSTALL_DIR=/usr/local/bin sh install.shWindows — PowerShell (installs moon.exe and adds it to PATH; not yet Authenticode-signed, so SmartScreen may prompt "Run anyway"):
irm https://raw.githubusercontent.com/pilotspace/moon/main/install.ps1 | iexDebian / RHEL — .deb and .rpm (amd64 + arm64) ship a systemd unit and /etc/moon/moon.conf:
sudo dpkg -i moon_<version>_arm64.deb # or: sudo rpm -i moon-<version>-1.arm64.rpm
sudo systemctl enable --now moonDocker:
docker run -p 6379:6379 ghcr.io/pilotspace/moon:latestCargo — add the moondb Rust client library to your project (moondb = "0.2"); build the server itself from source.
Homebrew — a tap is planned for v0.2.x (formula template in packaging/homebrew/).
Verify downloads — every artifact is checksummed in SHA256SUMS.txt and signed with keyless cosign (.sig + Fulcio .crt):
cosign verify-blob SHA256SUMS.txt \
--signature SHA256SUMS.txt.sig --certificate SHA256SUMS.txt.crt \
--certificate-identity-regexp 'github.com/pilotspace/moon' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comgit clone https://github.com/pilotspace/moon.git
cd moon
cargo build --release # needs Rust stable (edition 2024) + cmake (for TLS)
# Defaults: bind 127.0.0.1:6379, single shard (best non-pipelined throughput)
./target/release/moon
# Production flags (--shards 0 = auto-detect from CPU count; changing the
# count on an existing AOF dir needs a migration — see
# docs/runbooks/shard-count-change.md)
./target/release/moon \
--port 6379 --shards 8 \
--appendonly yes --appendfsync everysec \
--maxmemory 8g --maxmemory-policy allkeys-lfu
--maxmemoryis a whole-instance cap: with--shards M, each shard evicts againstmaxmemory / M, so total RSS converges on the value you set. Omit it and Moon auto-caps at ~80% of RAM withallkeys-lru(--maxmemory 0for unlimited).
Moon reads a Redis-style config file (precedence: CLI flags → conf file → defaults):
cp packaging/moon.conf.example /etc/moon/moon.conf
./target/release/moon /etc/moon/moon.conf # redis convention
./target/release/moon --config /etc/moon/moon.conf # or explicit flag
./target/release/moon /etc/moon/moon.conf --check-config # validate, don't startredis-cli -p 6379
127.0.0.1:6379> SET hello world
OK
127.0.0.1:6379> HSET user:1 name Alice age 30
(integer) 2
127.0.0.1:6379> HEXPIRE user:1 3600 FIELDS 1 age # per-field TTL (Valkey 9.0 parity)
1) (integer) 1
127.0.0.1:6379> FT.CREATE idx ON HASH PREFIX 1 doc: SCHEMA emb VECTOR HNSW 6 DIM 384 TYPE FLOAT32 DISTANCE_METRIC COSINE
OKMulti-stage cargo-chef build on a distroless runtime (~41 MB image):
docker build -t moon .
docker run -d -p 6379:6379 -v moon-data:/data moon moon --bind 0.0.0.0 --appendonly yesSee docs/quickstart.mdx for TLS setup, Docker Compose, and client-library examples.
pip install moondbfrom moondb import MoonClient, encode_vector
client = MoonClient(host="localhost", port=6379, decode_responses=True)
client.vector.create_index("docs", dim=384, metric="COSINE", prefix="doc:")
client.hset("doc:1", mapping={"title": "Hello", "vec": encode_vector([0.1] * 384)})
for r in client.vector.search("docs", [0.1] * 384, k=5):
print(r.key, r.score, r.fields)Full tutorials in examples/: RAG, Semantic Cache, GraphRAG, AI Agent Tools.
Headline numbers vs Redis 8.6.1, peak throughput, co-located client/server. Full methodology, ARM64, vector, graph, persistence, and latency tables are in BENCHMARK.md and docs/benchmarks.mdx.
| Workload | Moon | Redis 8.6.1 |
|---|---|---|
| Peak GET (c=50, p=64) | 5.11M | 2.98M (1.72×) |
| Peak SET (c=50, p=64) | 3.50M | 1.82M (1.92×) |
| GET, production defaults (AOF + offload) | 4.76M | 2.46M (1.93×) |
| Memory, values ≥ 1 KB | — | 27–35% less |
| Crash recovery (SIGKILL, 5K keys) | 100% | 100% (parity) |
On ARM64 (Neoverse-N1) Moon runs ~2.1–2.2× Redis on the same harness.
Deep pipelines were always Moon's home turf; v0.5–v0.6 closed the two classic gaps too:
- Unpipelined (p=1) single-connection — historically Redis's best case —
now a Moon win on both GCE architectures with the shipped
--io-busy-poll-us 40poll-mode park (--profile standalone, or the annotatedconf/moon-standalone.conf, sets it for you): 1.19–1.21× Redis on ARM (c4a Axion), 1.65–1.66× on x86 (c3), same-instance A/Bs, n=3. As of v0.8.1 the busy-poll auto-gates on shared cores (per-shard contention governor), so the preset is safe on any host — not just pinned ones. - Fully durable writes (
appendfsync always, p=16) went from 0.12× to 0.91× Redis via per-batch group commit + coalesced writes, whileeverysecp=16 is a 1.32× win — with kill-9-lossless recovery. - Vector time-to-index-green (bulk load → searchable at target recall) beats Qdrant 1.6–2.3× on GCE with the parallel HNSW build.
For vector (12.7K search QPS @ 384d), graph (23× FalkorDB bulk insert, 2.4× Cypher QPS; 2.78× on point-filter after the mutable property index), and hash-field TTL (Valkey-parity) benchmarks, see BENCHMARK.md.
Valkey is not yet head-to-head benched on this harness; its vendor-published 2.1M RPS (9 I/O threads, p=10) is quoted for context in the comparison below.
Three Redis-protocol servers, three bets. Moon competes on a vertical
moat — thread-per-core architecture and an AI-native in-core surface.
Valkey competes on a horizontal moat — Linux Foundation governance,
every major cloud, drop-in compatibility. Redis OSS is the upstream
reference but ships under SSPL since 2024. Full traced review:
docs/comparison-valkey.md.
| Dimension | Moon v0.6.0 | Valkey 9.1.0 | Redis 8.6.1 (OSS) |
|---|---|---|---|
| Language / license | Rust 2024 / Apache-2.0 | C99 / BSD-3 (LF TSC) | C99 / SSPL since 2024 |
| Threading | Thread-per-core, shared-nothing | Main thread + ≤9 I/O threads | Single-threaded core |
| I/O driver (Linux) | io_uring (monoio) |
epoll | epoll |
| Snapshot | Forkless (segment COW) | fork() + COW |
fork() + COW |
| Vector / BM25 / graph | In-core (HNSW+TQ, BM25, Cypher) | valkey-search module |
RediSearch module / none |
| Cross-store ACID | TXN.BEGIN/COMMIT/ABORT |
None | None |
| Hash-field TTL | Yes (Valkey-parity) | Yes (9.0+) | No |
| Tiered NVMe offload | Yes (KV under maxmemory + idle engine segments) |
No (OSS) | No (OSS) |
| Multi-tenant isolation | Per-db quotas + db-scoped indexes + workspaces | ACL only | ACL only |
| Multi-node cluster (GA) | Alpha (single-node GA today) | Production | Production |
| Peak single-server GET | 5.11M/s (c3-8 x86_64) | 2.1M RPS (vendor, p=10) | 2.98M/s (same harness) |
- Choose Moon for single-node peak throughput, ≥1 KB memory efficiency, forkless snapshots, or AI-native workloads (vector / GraphRAG / hybrid retrieval) with cross-store ACID.
- Choose Valkey for proven multi-node clusters, managed-cloud-only deployments, or strict Redis 7.2 module-ecosystem compatibility under LF governance.
- Stay on Redis OSS for existing RediSearch/RedisJSON/RedisBloom investments or Redis Enterprise features (CRDT active-active, Redis Flash).
| Category | Highlights |
|---|---|
| Data types | Strings, lists, hashes, sets, sorted sets, streams, HyperLogLog, bitmaps, vectors |
| Persistence | Forkless RDB v2, per-shard AOF (always/everysec/no), WAL v3 framing, tiered disk offload |
| Networking | RESP2/RESP3, HELLO negotiation, TLS 1.3 (rustls + aws-lc-rs), mTLS, pipelining, client-side caching |
| Clustering | 16,384 hash slots, gossip, MOVED/ASK, live slot migration, PSYNC2 replication (clustering guide), majority-vote failover |
| Scripting & security | Lua 5.4 (EVAL/EVALSHA), ACL users/keys/channels/commands, protected mode |
| Vector search | FT.CREATE/FT.SEARCH/FT.AGGREGATE, HNSW + TurboQuant 1–8-bit, auto-indexing on HSET, hybrid dense+sparse+BM25 |
| Full-text search | BM25 inverted index, typo tolerance (Levenshtein-automata), TAG/NUMERIC fields, HIGHLIGHT/SUMMARIZE, three-way RRF fusion |
| Graph engine | 14 GRAPH.* commands, Cypher subset (MATCH/WHERE/RETURN/CREATE/DELETE/SET/MERGE), hybrid graph+vector, CSR segments, SIMD cosine, temporal-decay traversal |
| Transactions | MULTI/EXEC (Redis compat) + TXN.BEGIN/COMMIT/ABORT (cross-store ACID with undo-log rollback) |
| Isolation & quotas | Db-scoped FT.*/graph/full-text indexes, per-db memory quotas (--db-maxmemory, CONFIG SET db-maxmemory) with deny-OOM shrink exemptions, truthful container-growth accounting |
| Workspaces | WS CREATE/AUTH/LIST — multi-tenant namespace isolation with transparent key prefixing |
| Memory offload | Idle vector segments HOT→WARM (mmap)→COLD (--engine-offload-idle-secs, --segment-warm-after); DEL/HDEL-correct across all tiers |
| Message queues | MQ CREATE/PUSH/POP/ACK — durable queues with dead-letter, triggers, WAL recovery |
| Temporal / CDC | Bi-temporal MVCC (TEMPORAL.SNAPSHOT_AT), PITR (--recovery-target-lsn), CDC.READ change stream |
| Web console | 7-view React app embedded in the binary, served at /ui/ |
| Observability | INFO, SLOWLOG, COMMAND DOCS, OBJECT, DEBUG, MEMORY, Prometheus metrics, structured tracing logs |
Full command list: docs/commands.mdx · Config flags: docs/configuration.mdx · Architecture: docs/architecture.mdx.
Moon ships an embedded web console — no separate install.
./target/release/moon --port 6379 --admin-port 9100 --shards 4
# open http://localhost:9100/ui/| View | What it does |
|---|---|
| Dashboard | Real-time QPS, P50/P99 latency, memory, clients, keyspace (SSE @ 1 Hz) |
| Browser | Namespace tree, virtual-scrolled key list, type-specific editors |
| Console | Monaco editor with RESP + Cypher syntax, 233-command autocomplete, multi-tab |
| Vectors | 3D UMAP projection, HNSW layer overlay, KNN search with distance rings |
| Graph | Force-directed 3D layout, Cypher editor, node/edge inspector |
| Memory | Keyspace treemap, slowlog table, command stats |
| Help | Getting-started guide with seed examples |
Populate all views with
python3 scripts/seed-console-fixtures.py --resp-port 6379 --admin-port 9100
(seeds KV + 50K vectors + 10K graph nodes). For production auth, pass
--console-auth-required --console-auth-secret … --console-cors-origin … --console-rate-limit ….
Honest matrix of where Moon is today. Read alongside
docs/PRODUCTION-CONTRACT.md (machine-checkable
GA exit criteria) and docs/OPERATOR-GUIDE.md
(memory accounting, sizing, runbooks).
Recommended for production today
- Single-node deployments — Linux aarch64 (Tier 1) or x86_64 (Tier 2),
--shards Nmaster. - Read replication — any
--shards Nmaster with--shards 1replicas (PSYNC2; multi-shard masters send one merged RDB + merged live stream, wired in v0.7).WAITreflects real replica ACKs. - AI workloads — vector, BM25, GraphRAG, semantic cache, hybrid retrieval. All in-core, all RDB/WAL durable, crash-recovery validated.
- Cache + feature store — honest durability modes (
always/everysec/no), forkless snapshots, tiered NVMe offload undermaxmemory. - Crash recovery — 100% survived across 7 persistence configs and 5K-key SIGKILL workloads (RDB v2 + WAL v3 + multi-part AOF + cold tier).
Not yet GA — avoid for production
- Multi-node clustering (16K-slot gossip, MOVED/ASK, failover) — protocol code exists but PSYNC2 atomic slot migration is not soak-tested. Scheduled for a v0.2.x follow-up.
- Multi-shard replicas — replicas run
--shards 1; scale reads with more replicas, not replica shards. CDC.SUBSCRIBEpush channel and zero-snapshot PITR (P3c) —CDC.READpolling is ready; push/live-LSN are deferred.- GPU vector acceleration (
gpu-cuda) — kernel scaffold only. - Performance SLOs in
docs/PRODUCTION-CONTRACT.mdare[provisional]until the 24-h HDR-histogram rig validates them. Treat the benchmarks above as point-in-time measurements, not committed SLOs.
Operator gotchas — multi-shard needs load (clients ≥ 25 × shards on
pipeline ≥ 16); bill on RSS, not VSZ (see
OPERATOR-GUIDE memory accounting);
for fair Redis/Valkey comparisons add --disk-offload disable --appendonly no.
Full list in CLAUDE.md "Gotchas".
Moon's goal from day one: a Redis-compatible server whose thread-per-core architecture measurably out-scales Redis on multi-core hardware — without giving up protocol compatibility or durability. The path there, release by release and measurement by measurement (including the ideas that were benchmarked and thrown out), is written up in The Moon Journey.
Three efficiency curves that each crossed Redis parity — single-connection
p=1 latency (Redis's home turf) and fsync=always durable throughput — landing
with the v0.5.x busy-poll + group-commit work and held through v0.8.1, where the
O3 governor made the p=1 spin safe to deploy anywhere. Same-instance A/B vs
Redis 8.6.1.
| Milestone | Focus | Status |
|---|---|---|
| v0.6.0 | Multi-db isolation (db-scoped indexes + per-db quotas + workspace hardening), tiered engine offload (WARM/COLD), --profile standalone, command-parity audit |
GA |
| v0.7.x | Replication GA for multi-shard masters — WAIT/ACK across all six planes, 24 h kill-9 soak (zero acked-write loss) |
GA |
| v0.8.0 | One Storage Kernel — kill-9-lossless on every plane (46-cell crash matrix) + 10× RAM datasets under disk offload | GA |
| v0.8.1 | Deploy-safe busy-poll (O3 contention governor auto-gates on shared cores) + single-shard tuning preset | GA |
| v0.8.2 | Storage kernel unification — one value codec / spill pipeline / eviction entry point / accessor skeleton, millisecond-TTL fidelity fix, batched sync-eviction manifest fsyncs | GA |
| v0.8.3 | Connection plane at scale — idle conns 56.5 → 3.25 KB (−94%, task-exit parking + idle downshift + TLS diet), loud maxclients, striped registry, c1M-ready (1 M idle ≈ 3.3 GB) | GA |
| v0.8.4 | c1M follow-ups — TLS task-parking (47 → 26 KB idle), park/wake registry handoff, park-vs-error spin fix (RST'd parked conn no longer pins a shard) | GA |
| v0.8.5 (current) | Durability hardening — AOF rewrites never drop acked writes (overflow spill + exactly-once snapshot cut, adversarially verified), fail-loud WAL mid-chain tears, sticky append/fsync degraded latches, deep-review wave (LFU/LRU arithmetic, cluster election, silent-failure hardening) | GA |
| v0.9 | Horizontal scale — cluster-on-monoio + multi-shard replicas | planned |
| v1.0 | Every PRODUCTION-CONTRACT.md GA box ticked |
gate |
Full history: The Moon Journey · RELEASES.md · CHANGELOG.md.
📖 Full documentation site: pilotspace.github.io/moon — searchable, with every guide, runbook, and reference.
Start at docs/index.md, then follow the trail:
- Get running — Quick start · Configuration · Docker · TLS
- Understand it — The journey · Architecture · Commands · Benchmarks · Storage format
- Build with it — SDKs · Full-text + vector search · Transactions · Workspaces · Message queues · Temporal
- Operate it — Operator guide · Production contract · Persistence · PITR · CDC · Clustering · Monitoring · Runbooks
- Trust it — Threat model · Unsafe policy · References & papers
cargo test --lib # unit tests
cargo fmt --check && cargo clippy -- -D warnings # lint gate
cargo test --release # full suite
./scripts/test-consistency.sh # 132 consistency tests vs Redis (1/4/12 shards)
./scripts/bench-production.sh # throughput vs Redis
cargo flamegraph --bin moon -- --port 6399 --shards 1 # profile a hot pathCoding rules — unsafe policy, hot-path allocation rules, lock discipline — are in CLAUDE.md and UNSAFE_POLICY.md. Contribution guide: CONTRIBUTING.md.
Moon stands on systems research and an open-source ecosystem. Headline credits:
- Dragonfly, ScyllaDB/Seastar, Garnet — thread-per-core shared-nothing architecture.
- Dash (VLDB 2020) + Swiss Table / Abseil — segmented hash table + SIMD probing behind
DashTable. - HNSW (arXiv 1603.09320) + TurboQuant (arXiv 2411.04405) — vector graph index and quantization for
FT.SEARCH. - BM25 (Robertson & Zaragoza 2009) + RRF (Cormack et al., SIGIR 2009) — full-text ranking and hybrid fusion.
- HyperLogLog (Flajolet et al. 2007) + Ertl estimator (2017) — cardinality estimation (
PFCOUNT). - Monoio (ByteDance) + io_uring (Axboe) — thread-per-core io_uring runtime.
- Redis Protocol Spec (RESP2/RESP3) + Redis Cluster Spec — wire protocol and cluster semantics.
Full list with per-dependency rationale and paper summaries: docs/references.mdx.



