Trama

Production Readiness

Use this guide to deploy Trama reliably in production with Redis Cluster, worker scaling, resilience controls, and strong operational visibility. This page is for teams moving from evaluation into real operational ownership.

Best for operators Deployment guidance Scale and resilience

Baseline Configuration

Running Redis Cluster in Production

Use Redis Cluster when one global ready queue becomes a hotspot. Trama spreads queue traffic across virtual shards and uses rendezvous hashing so each worker pod only polls the shards it owns.

redis:
  topology: "CLUSTER"
  cluster:
    nodes:
      - "redis://redis-cluster-0.redis:6379"
      - "redis://redis-cluster-1.redis:6379"
      - "redis://redis-cluster-2.redis:6379"
  sharding:
    podId: "${HOSTNAME}"
    virtualShardCount: 64
    membershipKey: "saga:runtime:pods"
    membershipTtlMillis: 10000
    heartbeatIntervalMillis: 3000
    refreshIntervalMillis: 2000
    claimerCount: 4

During shutdown, a worker marks itself as not ready, stops claiming new Redis queue work, unregisters from shard membership, and drains already-claimed executions before closing Redis. That lets another worker take ownership without abandoning in-flight items.

While a worker is processing an execution it keeps renewing its claim (every third of redis.consumer.processingTimeoutMillis, 20 s by default), so slow but healthy executions are never handed to a second worker. If a pod dies without draining, its renewals stop: once the lease expires, the shard's current owner moves that work back to the ready queue on its next claim pass, so recovery takes roughly the lease length.

A worker that pauses past its lease (long GC pause, VM migration, host suspend) is fenced. It stops before its next call, and none of its writes can land, because each one is a compare-and-set on the execution's checkpoint sequence in Postgres. Since 2.1.0.

Scaling Guidelines

Resilience Playbook

Security Checklist

Operational Checklist

AreaCheck
Availability/readyz for readiness (fails fast on Redis or consumer stalls), /healthz for liveness (fails after runtime.livenessStallMillis without progress).
Latencysaga_duration_seconds p95 tracked per definition.
Failuressaga_failed_total alert with reason dimension.
Queuesaga_enqueue_total vs saga_dequeue_total.
Recoverysaga_reconciled_total (executions re-sent after losing their queue item), saga_fenced_total (stale or paused workers stopped), saga_redis_errors_total.
Redis Clustersaga_redis_active_pods, saga_redis_owned_shards, and saga_redis_membership_refresh_age_ms tracked.
TracingOTEL exporter healthy and sampled correctly.

Upgrading

Read the changelog before upgrading.

Notes for 2.x → 3.0. This release is breaking for JSON body templates:

Notes for 2.3: redis.sharding.virtualShardCount defaults to 64 (was 1024). During a rolling deploy, pods on the old count keep claiming shards 64–1023 until they are replaced, and upgraded pods then move what is left. Set REDIS_SHARDING_VIRTUALSHARDCOUNT=1024 to keep the old count.

Notes for 2.0.x → 2.1 / 2.2:

Notes for 1.x → 2.x: