Redis Configuration for Production

+15 Mana ✨

Redis is essential for Action Cable in production, enabling multiple Rails processes to share WebSocket messages.

Why Redis?

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Rails 1    │     │   Rails 2    │     │   Rails 3    │
│  (Puma)      │     │  (Puma)      │     │  (Puma)      │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │                    │                    │
       └────────────────────┼────────────────────┘
                            │
                     ┌──────┴───────┐
                     │    Redis     │
                     │  (pub/sub)   │
                     └──────────────┘

Without Redis, messages only reach users connected to the same process.

Configuration

yaml
# config/cable.yml
production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: myapp_production

Redis URL Formats

ruby
# Basic
redis://localhost:6379/1

# With password
redis://:password@localhost:6379/1

# With username and password (Redis 6+)
redis://username:password@localhost:6379/1

# SSL/TLS
rediss://localhost:6379/1

# Full example with all options
redis://:password@redis.example.com:6380/2

Connection Pooling

ruby
# config/initializers/action_cable.rb
ActionCable.server.config.cable = {
  adapter: 'redis',
  url: ENV['REDIS_URL'],
  channel_prefix: 'myapp_production'
}

# For high traffic, configure Redis connection pool
Rails.application.config.action_cable.worker_pool_size = 10

Separate Redis Instance

For high-traffic apps, use a dedicated Redis for Action Cable:

yaml
# config/cable.yml
production:
  adapter: redis
  url: <%= ENV.fetch("ACTION_CABLE_REDIS_URL") %>
  channel_prefix: myapp_cable

Health Checks

ruby
# config/routes.rb
get '/health/cable', to: proc {
  begin
    ActionCable.server.pubsub.redis_connection_for_subscriptions.ping
    [200, {}, ['OK']]
  rescue => e
    [503, {}, ["Redis connection failed: #{e.message}"]]
  end
}

Monitoring Redis

ruby
# Custom metrics
class CableMetrics
  def self.connection_count
    ActionCable.server.connections.count
  end

  def self.subscription_count
    ActionCable.server.connections.sum { |c| c.subscriptions.count }
  end
end

PostgreSQL Alternative

For simpler setups without Redis:

yaml
# config/cable.yml
production:
  adapter: postgresql

Uses PostgreSQL's NOTIFY/LISTEN feature. Good for:

  • Smaller deployments
  • Avoiding additional infrastructure
  • Lower message volume
✓ Completed