Introduction
Before you can build real-time features, you need to configure Action Cable's adapter, allowed origins, and mount point. Rails 8.1 introduces Solid Cable as a first-party adapter option alongside Redis and PostgreSQL, giving you a database-backed alternative that requires no additional infrastructure.
Key Concepts
- Cable Adapter: The pub/sub backend that Action Cable uses to broadcast messages between server processes. Options include
async(single process, development only),redis,postgresql, andsolid_cable. - Solid Cable: A database-backed Action Cable adapter introduced in Rails 8. It stores messages in a dedicated database table, supporting MySQL, SQLite, and PostgreSQL without requiring a separate Redis instance.
- Allowed Request Origins: A security setting that restricts which domains can establish WebSocket connections, preventing cross-site WebSocket hijacking.
- Worker Pool Size: The number of threads Action Cable uses to process incoming messages. Each thread handles callbacks from subscriptions.
Real World Context
In production, your Rails app typically runs multiple server processes (via Puma workers or multiple containers). The async adapter only works within a single process, so you need a shared pub/sub backend. Historically, Redis was the default choice. With Rails 8.1, Solid Cable lets you use your existing database as the pub/sub backend, eliminating an infrastructure dependency. This is especially useful for smaller applications or teams that want to minimize operational complexity.
Deep Dive
Action Cable configuration lives in config/cable.yml. Here is a typical setup covering all environments:
yaml# config/cable.yml development: adapter: async test: adapter: test production: adapter: solid_cable
The async adapter is perfect for development — it keeps messages in memory within the current process. For production, you have three main options:
Solid Cable (recommended for Rails 8.1):
Install Solid Cable with the built-in generator:
bashbin/rails solid_cable:install
This command sets up config/cable.yml with the solid_cable adapter and creates db/cable_schema.rb containing the table definition for message storage. Solid Cable supports MySQL, SQLite, and PostgreSQL. Messages are automatically trimmed after they expire, keeping the table small.
Redis adapter:
yamlproduction: adapter: redis url: <%= ENV.fetch("REDIS_URL", "redis://localhost:6379/1") %> channel_prefix: myapp_production
Redis is a high-performance option ideal for applications with very high message throughput. The channel_prefix prevents collisions if multiple apps share the same Redis instance.
PostgreSQL adapter:
yamlproduction: adapter: postgresql
The PostgreSQL adapter uses NOTIFY/LISTEN for pub/sub, leveraging your existing database without additional infrastructure. However, it has lower throughput than Redis for very high-volume scenarios.
Next, configure allowed origins to prevent unauthorized WebSocket connections:
ruby# config/environments/production.rb Rails.application.configure do config.action_cable.allowed_request_origins = [ "https://myapp.com", "https://www.myapp.com" ] # Or use a regex for flexibility # config.action_cable.allowed_request_origins = [/https:\/\/.*\.myapp\.com/] config.action_cable.worker_pool_size = 4 end
Finally, ensure the Action Cable JavaScript is loaded in your application. In Rails 8.1 with import maps:
ruby# config/importmap.rb pin "@rails/actioncable", to: "actioncable.esm.js"
Common Pitfalls
- Using the async adapter in production — The
asyncadapter only works within a single process. If you run multiple Puma workers or containers, messages will not reach subscribers on other processes. Always useredis,postgresql, orsolid_cablein production. - Forgetting allowed_request_origins — In production, Action Cable rejects connections from origins not in the allowed list. If your WebSocket connections silently fail in production but work in development, check this setting first.
- Over-sizing the worker pool — Each Action Cable worker is a thread. Setting the pool too high on a memory-constrained server can starve your main request threads. Start with 4 and increase based on monitoring.
Best Practices
- Start with Solid Cable in Rails 8.1 — It requires no additional infrastructure and handles moderate message volumes well. Migrate to Redis only if monitoring reveals a bottleneck.
- Set
channel_prefixwhen using Redis — This prevents message collisions when multiple applications or environments share a Redis instance. - Use environment-specific configuration — Keep
asyncfor development,testfor tests, and your production adapter separate. Never hardcode production credentials.
Summary
- Action Cable supports four adapters:
async(dev only),redis,postgresql, andsolid_cable(new in Rails 8). - Solid Cable is installed via
bin/rails solid_cable:installand uses your database for pub/sub, supporting MySQL, SQLite, and PostgreSQL. - Always configure
allowed_request_originsin production to prevent cross-site WebSocket hijacking. - The worker pool size controls how many threads process incoming WebSocket messages — start with 4.
- Use the
asyncadapter for development and a shared backend (Solid Cable, Redis, or PostgreSQL) for production.
Code Examples
# config/cable.yml
development:
adapter: async
test:
adapter: test
production:
adapter: solid_cablebin/rails solid_cable:install