Enable AOF persistence (yes/no) — Moon is durable by default
--appendfsync
everysec
AOF fsync policy (always/everysec/no). everysec SET is ~1.32× Redis at pipeline depth and at parity non-pipelined; always (RPO 0) is fsync-device-bound — parity non-pipelined, ~0.91× Redis at depth. See BENCHMARK.md §7.3
--aof-fsync-timeout-ms
2000
Bound on a write's wait for durability — the fsync ack under always, writer-queue backpressure under everysec (0 = unbounded)
--wal-kv-log
auto
KV logging into the per-shard WAL. auto: skipped while the AOF is the recovery authority and no CDC subscriber is attached (halves write volume at --shards >= 2); on: always log (needed for PITR / full CDC history with AOF on); off: never
Replication (v0.7 GA) is initiated at runtime with the REPLICAOF <host> <port>
command — there is no startup flag. The relevant startup flags shape the
topology and durability of the pair:
Flag
On
Effect for replication
--shards N
master
Multi-core writer; the master merges all shards into one exactly-once replication feed
--shards 1
replica
Required — replicas are single-shard; scale reads by adding replicas
--appendonly yes
both
Persist the AOF so a restarted node recovers before re-syncing
--appendfsync always
master
RPO 0 on the master; pair with WAIT N for cross-node durability
--appendfsync always
replica
Required for zero-RPO — a replica ACKs on apply, not on fsync, so it must persist durably or a WAIT-acked write can still be lost if the replica crashes
Replicas are read-only (slave_read_only:1; writes return -READONLY). WAIT
numreplicas timeout reports real replica ACKs. Full setup, WAIT durability,
promotion (REPLICAOF NO ONE), and the replica TTL caveat: see the
clustering & replication guide and the
tuning guide.
Maximum simultaneous client connections (0 = unlimited)
--timeout
0 (disabled)
Close idle connections after N seconds
--tcp-keepalive
300
TCP keepalive interval in seconds (0 = disabled)
--slowlog-log-slower-than
10000
Slowlog threshold in microseconds
--slowlog-max-len
128
Maximum slowlog entries
--profile
(none)
Apply a named tuning preset (currently standalone). Only fills flags left at their default — an explicit flag always wins. Logs exactly what it set. Safe on any host (busy-poll auto-gates on shared cores). See the tuning guide
--io-driver
auto
I/O driver: auto (io_uring on Linux, kqueue on macOS) or epoll
--io-busy-poll-us
0 (off)
Busy-poll the I/O driver for N µs before parking. Large single-op latency win on dedicated cores; auto-disables on shared/oversubscribed cores via the per-shard contention governor, so it no longer regresses there. See the tuning guide
--initial-keyspace-hint
0
Pre-size the keyspace (e.g. 1000000) to avoid rehash pauses during bulk loads
--memory-arenas-cap
8
Cap jemalloc arenas — lower (e.g. 2) for a single-shard / small-container footprint. jemalloc builds only; CLI-only (read before the config file). --profile standalone sets 2
--memory-thp
(off)
Opt the jemalloc value heap into transparent huge pages (thp:always). Measured GET +12–24% on GCE, but permanently opt-in: idle khugepaged re-collapse drifts RSS ~+31% after mixed-size churn, so enable only on uniform-value-size fleets with RSS headroom. jemalloc + Linux only; CLI-only
--uring-sqpoll
(disabled)
io_uring SQPOLL idle timeout in ms. Requires CAP_SYS_NICE. Linux only
These are same-binary A/B / diagnostic overrides, not production tuning:
Env var
Effect
MOON_SPIN_ADAPTIVE=0
Disable the busy-poll contention governor — the shard spins unconditionally whenever --io-busy-poll-us > 0 (pre-governor behaviour; dedicated cores only)
MOON_SPIN_MAX_PREEMPTS_PER_SEC
Governor gate threshold in involuntary preemptions/sec (default 25). One window above this disables the spin on that shard; five quiet windows re-enable it
The default --shards 1 gives the best single-operation latency and is the right choice for most deployments. Add shards when you have many concurrent connections (8+) or pipelined/batched traffic — see the tuning guide for measured guidance.
Tip
Hash tags like {tag} in key names (e.g., user:{1234}:name) route all tagged keys to the same shard, eliminating cross-shard dispatch for MGET/MSET operations.
Warning
Testing with more than 1,000 concurrent clients may require ulimit -n 65536. At 5,000 clients with pipelining, connection drops can occur without it.
For workload-specific recipes (cache, high-concurrency API, durable store, vector search, containers), see the tuning guide.