Skip to main content
Swytch Documentation
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Sizing and Capacity Planning

This guide helps you estimate memory requirements, plan for growth, and understand when to scale your Swytch deployment.

Memory Estimation

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:

  1. Record idle process and container memory with the intended configuration.
  2. Load a representative working set and run its normal reads and writes long enough to include history and reclamation.
  3. Record cache memory, total process/container memory, eviction rate, and latency at peak load.
  4. 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.

Local Durability Capacity

--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.

Working Set Analysis

What is Working Set?

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.

Identifying Memory Pressure

Use these metrics to understand whether your working set fits in memory:

MetricMeaning
swytch_redis_cache_hits_totalSuccessful cache lookups
swytch_redis_cache_misses_totalCache misses (key not found)
swytch_redis_cache_hit_rateHit rate (0-1)
swytch_redis_evictions_totalKeys 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

Calculating Hit Rate

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.

When to Scale

Scale Memory When

SignalAction
Hit rate < 80%Increase --maxmemory
Evictions > 1000/sec sustainedIncrease --maxmemory
p99 latency increasingCheck eviction rate and hit rate
OOM killsIncrease container memory limit

Scale CPU When

SignalAction
CPU utilization > 80% sustainedAdd cores or optimize queries
Command queue backing upCheck INFO for blocked clients
Lua script timeoutsOptimize scripts or add CPU

Scale Nodes When (Cluster Mode)

SignalAction
Single node cannot hold working setAdd nodes to distribute load
High cluster_reads_remote_fetch_totalData is spread across nodes; add memory or review key distribution
Network bandwidth saturatedAdd nodes to reduce per-node traffic

Capacity Planning Worksheet

Use this worksheet to plan your deployment:

1. Measure the Working Set

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

2. Size Memory

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.

3. Set Resource Limits

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.

Monitoring for Capacity

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%"

Before Changing Capacity

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.