---
title: "Deploy Redis HA (w/ Cluster Mode, Sharded 3+3)"
description: "One‑click Redis Cluster (3 nodes + 3 replicas) with automatic failover"
category: "Storage"
url: https://railway.com/deploy/redis-ha-w-cluster-mode-sharded-33
---

# Deploy Redis HA (w/ Cluster Mode, Sharded 3+3)

One‑click Redis Cluster (3 nodes + 3 replicas) with automatic failover

**[Deploy Redis HA (w/ Cluster Mode, Sharded 3+3) on Railway](https://railway.com/template/redis-ha-w-cluster-mode-sharded-33)**

- **Creator:** Medim's Projects
- **Category:** Storage

## Template content

### Redis A https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ >/dev/null 2>&1 || true; echo 'Starting redis node...'; exec docker-entrypoint.sh redis-server --port 6379 --bind 0.0.0.0 :: --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes --requirepass $REDIS_PASSWORD --masterauth $REDIS_PASSWORD --dir $RAILWAY_VOLUME_MOUNT_PATH --protected-mode no --cluster-announce-hostname $RAILWAY_PRIVATE_DOMAIN --cluster-announce-port 6379 --cluster-announce-bus-port 16379"`

### Redis B https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ >/dev/null 2>&1 || true; echo 'Starting redis node...'; exec docker-entrypoint.sh redis-server --port 6379 --bind 0.0.0.0 :: --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes --requirepass $REDIS_PASSWORD --masterauth $REDIS_PASSWORD --dir $RAILWAY_VOLUME_MOUNT_PATH --protected-mode no --cluster-announce-hostname $RAILWAY_PRIVATE_DOMAIN --cluster-announce-port 6379 --cluster-announce-bus-port 16379"`

### Redis F https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ >/dev/null 2>&1 || true; echo 'Starting redis node...'; exec docker-entrypoint.sh redis-server --port 6379 --bind 0.0.0.0 :: --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes --requirepass $REDIS_PASSWORD --masterauth $REDIS_PASSWORD --dir $RAILWAY_VOLUME_MOUNT_PATH --protected-mode no --cluster-announce-hostname $RAILWAY_PRIVATE_DOMAIN --cluster-announce-port 6379 --cluster-announce-bus-port 16379"`

### Redis E https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ >/dev/null 2>&1 || true; echo 'Starting redis node...'; exec docker-entrypoint.sh redis-server --port 6379 --bind 0.0.0.0 :: --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes --requirepass $REDIS_PASSWORD --masterauth $REDIS_PASSWORD --dir $RAILWAY_VOLUME_MOUNT_PATH --protected-mode no --cluster-announce-hostname $RAILWAY_PRIVATE_DOMAIN --cluster-announce-port 6379 --cluster-announce-bus-port 16379"`

### Initiator https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "echo '--- Redis Cluster Init ---'; ALL_NODES=\"$REDIS_A_HOST:6379 $REDIS_B_HOST:6379 $REDIS_C_HOST:6379 $REDIS_D_HOST:6379 $REDIS_E_HOST:6379 $REDIS_F_HOST:6379\"; echo \"Nodes: $ALL_NODES\"; for node in $ALL_NODES; do host=\${node%%:*}; port=\${node##*:}; echo \"--> Waiting for $host:$port\"; i=0; until redis-cli -h \"$host\" -p \"$port\" -a \"$REDIS_PASSWORD\" ping >/dev/null 2>&1; do i=\$((i+1)); if [ \"\$i\" -gt 60 ]; then echo \"ERROR: $host:$port not ready after timeout\"; exit 1; fi; sleep 2; done; echo \" $host:$port ready\"; done; if redis-cli -h \"$REDIS_A_HOST\" -a \"$REDIS_PASSWORD\" cluster info 2>/dev/null | grep -q 'cluster_state:ok'; then echo 'Cluster already healthy (cluster_state:ok). Exiting.'; exit 0; fi; echo '--- Creating cluster ---'; redis-cli -a \"$REDIS_PASSWORD\" --cluster create $ALL_NODES --cluster-replicas 1 --cluster-yes; echo '--- Waiting for cluster_state:ok and all slots assigned ---'; i=0; while :; do info=\$(redis-cli -h \"$REDIS_A_HOST\" -a \"$REDIS_PASSWORD\" cluster info 2>/dev/null || true); echo \"\$info\" | grep -q 'cluster_state:ok' && echo \"\$info\" | grep -q 'cluster_slots_assigned:16384' && { echo 'Cluster is OK and all slots assigned. Done.'; exit 0; }; i=\$((i+1)); [ \"\$i\" -gt 90 ] && { echo 'ERROR: Cluster did not reach healthy state in time.'; exit 1; }; sleep 2; done"`

### Redis D https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ >/dev/null 2>&1 || true; echo 'Starting redis node...'; exec docker-entrypoint.sh redis-server --port 6379 --bind 0.0.0.0 :: --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes --requirepass $REDIS_PASSWORD --masterauth $REDIS_PASSWORD --dir $RAILWAY_VOLUME_MOUNT_PATH --protected-mode no --cluster-announce-hostname $RAILWAY_PRIVATE_DOMAIN --cluster-announce-port 6379 --cluster-announce-bus-port 16379"`

### Redis C https://cdn.sanity.io/images/sy1jschh/production/0ce0bfdcfbdbf69662b1116671f97c2dd788b655-157x157.svg

- **Image:** redis:8.4.0
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ >/dev/null 2>&1 || true; echo 'Starting redis node...'; exec docker-entrypoint.sh redis-server --port 6379 --bind 0.0.0.0 :: --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --appendonly yes --requirepass $REDIS_PASSWORD --masterauth $REDIS_PASSWORD --dir $RAILWAY_VOLUME_MOUNT_PATH --protected-mode no --cluster-announce-hostname $RAILWAY_PRIVATE_DOMAIN --cluster-announce-port 6379 --cluster-announce-bus-port 16379"`

## Documentation

# Deploy and Host Redis HA (w/ Cluster Mode, Sharded 3+3) on Railway

Redis Cluster HA (Sharded 3+3) deploys a six‑node Redis Cluster: three masters sharding the 16,384 hash slots, each with a dedicated replica for high availability. It delivers horizontal write scaling, automatic failover, and slot‑based routing. Clients connect with a cluster‑aware driver (e.g., ioredis Cluster) over Railway’s private network or through the exposed TCP proxies on each node.

## About Hosting Redis HA (w/ Cluster Mode, Sharded 3+3)

This template provisions six Redis services in cluster mode (3 masters + 3 replicas) and a one‑shot init job that forms the cluster and exits once healthy (can be deleted after reaching the "Completed" status). Masters split all 16,384 slots; replicas continuously sync and are auto‑promoted if a master fails (majority of masters required). All nodes advertise internal hostnames and run on Railway’s private network for reliable cluster‑bus communication. Connect using a cluster‑aware client like ioredis Cluster class.

## Common Use Cases

- Horizontally scalable, highly available cache/session store
- High‑throughput job/queue/stream workloads (use hash tags to co‑locate multi‑key ops)
- Read scaling via replicas for analytics and dashboards (optional read‑from‑replica)

## Dependencies for Redis HA (w/ Cluster Mode, Sharded 3+3) Hosting

- A cluster‑aware client library (e.g., ioredis Cluster, Jedis/Lettuce Cluster, go‑redis v9)
- One shared Redis password across all nodes (injected via variables referenced from Redis Node A)

### Deployment Dependencies

- Redis Cluster (OSS) docs: https://redis.io/docs/latest/operate/oss_and_stack/management/scaling/
- ioredis Cluster usage: https://github.com/luin/ioredis#cluster

### Implementation Details

Client (Node + ioredis inside Railway):
```js
import Redis from "ioredis";
import dns from "dns";

const seeds = [
  { host: process.env.REDIS_A_HOST, port: 6379 },
  { host: process.env.REDIS_B_HOST, port: 6379 },
  { host: process.env.REDIS_C_HOST, port: 6379 },
  // (Optional) include replicas too
  // { host: process.env.REDIS_D_HOST, port: 6379 },
  // { host: process.env.REDIS_E_HOST, port: 6379 },
  // { host: process.env.REDIS_F_HOST, port: 6379 },
];

const cluster = new Redis.Cluster(seeds, {
  // Resolve both IPv4/IPv6
  dnsLookup: (hostname, cb) =&gt; dns.lookup(hostname, { family: 0 }, cb),
  redisOptions: { password: process.env.REDIS_PASSWORD }, // This is the Redis Node A password
  // Optional: read from replicas ("master" | "replica" | "all")
  scaleReads: "master",
});

// Use it as normal
await cluster.set("foo", "bar");
const value = await cluster.get("foo");
console.log(value);

await cluster.quit();
```

Quick verify commands:
- `redis-cli -h masterhostnamehere -a passwordhere cluster info`
- `redis-cli -h masterhostnamehere -a passwordhere cluster nodes`

Notes:
- The template forms a 3‑shard cluster with one replica per shard. Failover promotes a replica if a master fails (requires a majority of masters).
- Multi‑key commands must target keys in the same hash slot; use hash tags like user:{123}:profile.

## Why Deploy Redis HA (w/ Cluster Mode, Sharded 3+3) on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Redis HA (w/ Cluster Mode, Sharded 3+3) on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

## Similar templates

- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.
- [Redis](https://railway.com/deploy/redis-1) — Self Host Latest Redis with Railway
- [EasyImg](https://railway.com/deploy/easyimg) — Simple self-hostable Nuxt.js personal image hosting system.

Open this page in a browser: https://railway.com/deploy/redis-ha-w-cluster-mode-sharded-33
