Sizing and Capacity Planning
This guide helps you estimate memory requirements, plan for growth, and understand when to scale your Swytch deployment.
Swytch stores effects and their causal relationships, not just the latest key and value bytes. Memory use depends on the retained history, transaction bindings, snapshots, index entries, decoded values, and the workload’s access pattern. A fixed per-key allowance cannot describe these costs.
Measure with representative keys, value sizes, updates, and transactions:
- Record idle process and container memory with the intended configuration.
- Load a representative working set and run its normal reads and writes long enough to include history and reclamation.
- Record cache memory, total process/container memory, eviction rate, and latency at peak load.
- Repeat at a larger working set before extrapolating. Include connection buffers, scripts, and cluster traffic.
Use those measurements to choose --maxmemory and a higher process or container limit. Keep headroom for bursts and
runtime allocations; a cache budget is not a limit on the entire process. With local durability, also measure startup
recovery rather than assuming its peak matches steady operation.
--data-dir mirrors resident effects. It does not let the active dataset exceed memory or serve evicted keys from
disk. Effect reclamation also removes mirror records once they are no longer referenced.
Recovery decodes effects and builds the index and key frontiers in parallel. Budget for decoded protobufs, vertex-pool entries, TOCs, and temporary recovery structures. Mapped file pages also contribute to process and container memory use. The saved directory’s byte size is not a recovery-memory estimate.
Test a restart before reducing memory or moving storage to a smaller machine. Use an offline copy and the intended limits to measure peak memory and time until known keys can be read. If memory pressure requires eviction during recovery, Swytch cancels recovery and gives you 30 seconds to stop it. Otherwise it deletes the saved mirror and starts empty. See the recovery procedure.
Plan disk space separately:
- Records own complete filesystem blocks, so small effects can consume much more space than their payload sizes.
- TOC pages and file headers add metadata. There can be up to 64 bucket files for each originating node represented.
- Reclaimed records leave holes on supported Linux filesystems. Compare allocated space with logical file lengths.
- Without hole punching, unreachable allocations remain until their bucket file becomes empty and is removed.
- Nonempty files append new payloads; reclaimed payload space is not reused. Measure growth under a sustained update workload.
Monitor free space and storage errors as well as RAM. See local durability for directory layout, sync timing, and copying a stopped store.
Your working set is the subset of data actively accessed within a time window. Swytch keeps all data in memory — when the cache is full, the eviction algorithm removes infrequently accessed keys to make room.
Use these metrics to understand whether your working set fits in memory:
| Metric | Meaning |
|---|---|
swytch_redis_cache_hits_total | Successful cache lookups |
swytch_redis_cache_misses_total | Cache misses (key not found) |
swytch_redis_cache_hit_rate | Hit rate (0-1) |
swytch_redis_evictions_total | Keys evicted from cache |
Working set fits in memory when:
- Hit rate is high (>90%)
- Evictions are infrequent
- p99 latency is stable
Working set exceeds memory when:
- Hit rate is dropping
- Consistent eviction pressure
- Frequently accessed keys are being evicted and re-populated
Hit Rate = cache_hits / (cache_hits + cache_misses)
Or use the pre-computed gauge:
swytch_redis_cache_hit_rate
Target: Hit rate > 90% for latency-sensitive workloads.
| Signal | Action |
|---|---|
| Hit rate < 80% | Increase --maxmemory |
| Evictions > 1000/sec sustained | Increase --maxmemory |
| p99 latency increasing | Check eviction rate and hit rate |
| OOM kills | Increase container memory limit |
| Signal | Action |
|---|---|
| CPU utilization > 80% sustained | Add cores or optimize queries |
| Command queue backing up | Check INFO for blocked clients |
| Lua script timeouts | Optimize scripts or add CPU |
| Signal | Action |
|---|---|
| Single node cannot hold working set | Add nodes to distribute load |
High cluster_reads_remote_fetch_total | Data is spread across nodes; add memory or review key distribution |
| Network bandwidth saturated | Add nodes to reduce per-node traffic |
Use this worksheet to plan your deployment:
Current keys: ____________
Average key size: ____________ bytes
Average value size: ____________ bytes
Update/transaction mix: ____________
Peak cache memory: ____________ GB
Peak process memory: ____________ GB
Growth rate (monthly): ____________ %
6-month projection = measured memory × (1 + growth_rate)^6
= ____________ GB
Swytch is an in-memory cache. All active data must fit in --maxmemory. When the limit is reached, the eviction
algorithm evicts keys automatically. Use the measured working set plus headroom for your workload’s bursts.
If your total dataset is larger than available memory, Swytch functions as a cache — frequently accessed keys stay
in memory while cold keys are evicted. Start with a generous budget and monitor hit rate before reducing it. With
--data-dir, separately verify that the saved state can recover within the new budget.
container_memory = maxmemory + max(512MB, maxmemory × 0.2)
container_cpu = based on expected ops/sec (see Deployment guide)
This is a starting allowance to validate under load. Extra memory beyond --maxmemory accounts for connection
buffers, Lua scripting overhead, the Go runtime, and cluster replication state (if clustered). Local durability also
requires room for mapped pages and recovery allocations; use the measured peak, not this formula alone.
Set up alerts for proactive scaling:
# Prometheus alerting rules
groups:
- name: swytch-capacity
rules:
- alert: SwytchMemoryPressure
expr: swytch_redis_memory_bytes / swytch_redis_memory_max_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Swytch memory usage above 90%"
- alert: SwytchHighEvictionRate
expr: rate(swytch_redis_evictions_total[5m]) > 1000
for: 10m
labels:
severity: warning
annotations:
summary: "High eviction rate indicates memory pressure"
- alert: SwytchLowHitRate
expr: swytch_redis_cache_hit_rate < 0.8
for: 15m
labels:
severity: warning
annotations:
summary: "Cache hit rate below 80%"
Check the measured working set, peak process memory, and eviction rate. If local durability is enabled, include a restart trial from an offline copy. Adding nodes only helps memory distribution when the workload’s subscriptions allow it; keys read everywhere still occupy memory on each subscriber.