C# Academy · Lesson

Scaling with Redis Backplane

Scale SignalR across multiple servers using a Redis backplane to synchronize messages between instances.

Lesson 4 of 413 steps

Scaling with Redis Backplane is a free C# Academy lesson on CoddyKit. This is lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 4 lessons in total.

The Multi-Server Problem

When SignalR runs on a single server, clients and the server share memory for connections and groups. Scale to two or more servers and each server only knows about its own connections — a message sent on Server A never reaches clients connected to Server B.

What Is a Backplane?

A backplane is a shared message bus between SignalR server instances. When one server wants to send a message, it publishes to the backplane; all servers receive it and forward it to their local connections.

Adding the Redis Backplane

Install the Microsoft.AspNetCore.SignalR.StackExchangeRedis package and call AddStackExchangeRedis() after AddSignalR().

// dotnet add package Microsoft.AspNetCore.SignalR.StackExchangeRedis

builder.Services.AddSignalR()
    .AddStackExchangeRedis("localhost:6379", options =>
    {
        options.Configuration.ChannelPrefix =
            RedisChannel.Literal("myapp"); // namespace your channels
    });

// Or from config:
// .AddStackExchangeRedis(builder.Configuration.GetConnectionString("Redis")!);

How Redis Pub/Sub Works for SignalR

Each SignalR server subscribes to Redis channels. When server A publishes a message for a group or user, Redis delivers it to all subscribers (servers B, C…), which then forward it to their local connections.

// Server A: client sends message
// Hub on Server A calls:
await Clients.Group("room-42").ReceiveMessage(user, msg);

// Internally SignalR publishes to Redis:
// PUBLISH signalr/myapp/group/room-42 <serialized message>

// Redis delivers to Server B and C
// Both servers find connections in "room-42" and push to them

Configuration Options

Fine-tune the Redis connection for production: TLS, password, connection resilience, and pub/sub channel prefix.

builder.Services.AddSignalR()
    .AddStackExchangeRedis(opts =>
    {
        opts.Configuration = ConfigurationOptions.Parse(
            builder.Configuration["Redis:ConnectionString"]!);
        opts.Configuration.Password      = builder.Configuration["Redis:Password"];
        opts.Configuration.Ssl           = true;
        opts.Configuration.AbortOnConnectFail = false;
        opts.Configuration.ConnectRetry  = 3;
    });

Azure SignalR Service

For fully managed scaling, use Azure SignalR Service. It acts as the backplane and connection manager — your app servers become stateless and don't hold WebSocket connections themselves.

// dotnet add package Microsoft.Azure.SignalR

builder.Services.AddSignalR()
    .AddAzureSignalR(builder.Configuration["Azure:SignalR:ConnectionString"]!);

// That's it — Azure manages all connections and backplane
// Your server scales to zero when not needed

Sticky Sessions (Fallback for Non-WebSocket Transport)

When using Server-Sent Events or Long Polling (not WebSockets), the same client must always hit the same server — called sticky sessions. Configure this in your load balancer or reverse proxy.

# Nginx: sticky session config (IP hash)
upstream signalr_servers {
    ip_hash; # ensures same client hits same server
    server server1:5000;
    server server2:5000;
    server server3:5000;
}

# Or use cookie-based sticky sessions:
# sticky cookie srv_id expires=1h;

# WebSockets don't need sticky sessions —
# the connection is long-lived on one server

Groups Across Multiple Servers

Group membership is maintained by the backplane. Adding a connection to a group on Server A means Server B knows about it via Redis — transparent to application code.

// This works correctly across servers:
public async Task JoinRoom(string room)
{
    // Adds to Redis-backed group
    await Groups.AddToGroupAsync(Context.ConnectionId, room);

    // Clients.Group sends via Redis to all servers
    await Clients.Group(room).UserJoined(Context.User!.Identity!.Name!);
}
// No code changes needed — the Redis backplane handles distribution

Monitoring Redis Pub/Sub

Monitor Redis channels to verify SignalR traffic and diagnose issues. Use redis-cli SUBSCRIBE or Redis Insights to observe the message flow.

# redis-cli: monitor all SignalR channels
redis-cli PSUBSCRIBE "myapp*"

# Check active channel subscribers
redis-cli PUBSUB CHANNELS "myapp*"

# Check number of subscribers per channel
redis-cli PUBSUB NUMSUB "myapp/all"

Handling Redis Failures

If Redis becomes unavailable, SignalR falls back to local-only mode — messages won't cross servers. Configure retry policies and alerting for Redis connectivity.

builder.Services.AddSignalR()
    .AddStackExchangeRedis(opts =>
    {
        opts.Configuration = ConfigurationOptions.Parse(redisConn);
        opts.Configuration.AbortOnConnectFail = false; // don't crash app
        opts.Configuration.ConnectRetry       = 5;
        opts.Configuration.ReconnectRetryPolicy =
            new ExponentialRetry(5000, maxDeltaBackoffMilliseconds: 60000);
    });

Real-World: Scaled Chat Architecture

In production, run 3+ SignalR server instances behind a load balancer, with Redis (or Azure SignalR Service) as the backplane. All state lives in Redis; servers are stateless and disposable.

// Architecture:
// [Browser] -> [Load Balancer (any server, WebSocket)] ->
//   [SignalR Server 1] -+
//   [SignalR Server 2] -+-> [Redis Pub/Sub] -> all servers
//   [SignalR Server 3] -+

// Server code is identical on all instances:
builder.Services.AddSignalR().AddStackExchangeRedis(redisConn);
app.MapHub<ChatHub>("/hubs/chat");
// Scale replicas: kubectl scale deployment chat --replicas=3

Quick Check

What problem does a SignalR backplane solve?

Recap: Scaling with Redis Backplane

Key takeaways:

  • Without a backplane, messages from one server don't reach clients on other servers
  • AddStackExchangeRedis() adds a Redis pub/sub backplane transparently
  • Azure SignalR Service provides a fully managed, serverless backplane alternative
  • Sticky sessions are required for non-WebSocket transports (SSE, Long Polling)
  • Group membership is synchronized across servers via the backplane
  • Configure AbortOnConnectFail=false and retry policies for Redis resilience
Free to start

Learn C# with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
93
Lessons
346

Frequently Asked Questions

Is the “Scaling with Redis Backplane” lesson free?

Yes — the full text of “Scaling with Redis Backplane” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 4 lessons in total.

What will I learn in “Scaling with Redis Backplane”?

Scale SignalR across multiple servers using a Redis backplane to synchronize messages between instances. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Scaling with Redis Backplane” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. SignalR Hubs & Connections
  2. Groups, Users & Connection Management
  3. Strongly Typed Hubs
  4. Scaling with Redis Backplane
← Back to C# Academy