dify - 💡(How to fix) Fix Support Redis adapter in ext_socketio for multi-replica deployments

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix / Workaround

  • Affected file: api/extensions/ext_socketio.py
  • Redis usage: Pub/Sub only (PUBLISH / SUBSCRIBE). Messages are transient — no keys are written, no memory accumulates. The channel name socketio:collaboration does not conflict with existing Dify Redis keys (which use dify:* prefix or Celery broker DB).
  • Compatibility: python-socketio has built-in RedisManager support — no additional dependencies required (Redis is already a hard dependency for Dify).
  • Deployment scenarios this enables: Kubernetes with replicas > 1, Docker Swarm, any load-balanced multi-instance setup.
  • Workaround without this change: Sticky sessions (session affinity) at the load balancer level partially mitigates the issue, but doesn't solve the fundamental problem — events emitted by the server (e.g., lock state changes) still only reach clients on the same instance.

Code Example

def _create_client_manager():
      if not dify_config.ENABLE_COLLABORATION_MODE:
          return None
      return socketio.RedisManager(
          dify_config.normalized_pubsub_redis_url,
          channel="socketio:collaboration",
      )

  sio = socketio.Server(
      async_mode="gevent",
      client_manager=_create_client_manager(),
      cors_allowed_origins=dify_config.CONSOLE_CORS_ALLOW_ORIGINS,
  )
RAW_BUFFERClick to expand / collapse

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • Please do not modify this template :) and fill in all the required fields.

1. Is this request related to a challenge you're experiencing? Tell me about your story.

We deploy Dify API behind a load balancer with multiple replicas (pods) for high availability. When the Workflow Collaboration feature (ENABLE_COLLABORATION_MODE=true) is enabled, Socket.IO connections from different users may land on different replicas.

Since ext_socketio.py currently uses an in-memory transport (socketio.Server(async_mode="gevent", ...)), WebSocket events emitted on one replica are invisible to clients connected to other replicas. This means two users editing the same Workflow will not see each other's real-time updates if they happen to connect to different backend instances.

The fix is straightforward — pass a socketio.RedisManager as the client_manager argument when collaboration mode is enabled. This uses Redis Pub/Sub (no persistent keys, zero storage overhead) to broadcast events across all replicas:

  def _create_client_manager():
      if not dify_config.ENABLE_COLLABORATION_MODE:
          return None
      return socketio.RedisManager(
          dify_config.normalized_pubsub_redis_url,
          channel="socketio:collaboration",
      )

  sio = socketio.Server(
      async_mode="gevent",
      client_manager=_create_client_manager(),
      cors_allowed_origins=dify_config.CONSOLE_CORS_ALLOW_ORIGINS,
  )

When ENABLE_COLLABORATION_MODE=false (the default), behavior is identical to today — no Redis dependency, pure in-memory. This change only activates the adapter when collaboration is explicitly opted in, so single-instance deployments are unaffected.

2. Additional context or comments

  • Affected file: api/extensions/ext_socketio.py
  • Redis usage: Pub/Sub only (PUBLISH / SUBSCRIBE). Messages are transient — no keys are written, no memory accumulates. The channel name socketio:collaboration does not conflict with existing Dify Redis keys (which use dify:* prefix or Celery broker DB).
  • Compatibility: python-socketio has built-in RedisManager support — no additional dependencies required (Redis is already a hard dependency for Dify).
  • Deployment scenarios this enables: Kubernetes with replicas > 1, Docker Swarm, any load-balanced multi-instance setup.
  • Workaround without this change: Sticky sessions (session affinity) at the load balancer level partially mitigates the issue, but doesn't solve the fundamental problem — events emitted by the server (e.g., lock state changes) still only reach clients on the same instance.

3. Can you help us with this feature?

  • I am interested in contributing to this feature.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING