1. Topics
  2. /
  3. Realtime technologies
  4. /
  5. SignalR deep dive: Key concepts, use cases, and limitations
13 min readPublished Mar 23, 2023

SignalR deep dive: Key concepts, use cases, and limitations

This article is a deep dive into SignalR - a technology developers can use to engineer realtime functionality for use cases like live chat and multiplayer collaboration. We’ll cover the following:

Copy link to clipboard

Introduction to SignalR

SignalR is an event-driven technology that helps developers add realtime functionality to web and mobile applications. SignalR allows server side code to push updates to connected clients (primarily over WebSockets) as soon as new content/information is available, without any need for clients to constantly poll the server for updates. Similarly, clients can send messages to the server.

SignalR comes in several different flavors:

  • ASP. NET SignalR - a library for ASP.NET developers. This version is largely outdated (only critical bugs are being fixed, but no new features are being added).

  • ASP. NET Core SignalR - an open-source library; unlike ASP.NET SignalR, this version is actively maintained. 

  • Azure SignalR Service -  the managed cloud version.

Note: This article focuses on ASP.NET Core SignalR and Azure SignalR Service. We’re not covering ASP.NET SignalR, which is unlikely to be a good tech choice for building production-ready systems (since it’s not actively maintained and won’t benefit from any new features or enhancements).    

Copy link to clipboard

Azure SignalR Service vs ASP. NET Core SignalR: Major differences

ASP.NET Core SignalR and Azure SignalR Service offer the same core features (more about this in the following section of this article). There are, however, some differences between the two.

ASP.NET Core SignalR can be self-hosted or hosted in any server that supports ASP.NET Core. Developers are responsible for managing the SignalR infrastructure themselves. This means that developers need to handle things like scalability, security, and maintenance. 

In contrast, Azure SignalR Service is built on top of ASP.NET Core SignalR. Azure SignalR Service is a fully managed product with built-in scalability, security, and maintenance. With Azure SignalR Service, developers don't have to worry about managing SignalR infrastructure or scaling the application as traffic increases. 

The two SignalR solutions have different architectures. When using ASP.NET Core SignalR, the client connects directly to the server. Meanwhile, with Azure SignalR Service, a negotiate endpoint is exposed by the SignalR Service SDK. Once a successful negotiation takes place, the client connects to Azure SignalR Service. 

Unlike ASP.NET Core SignalR, Azure SignalR Service supports not only server-based configurations, but serverless architectures too. For more details, see the SignalR service mode section in this article. 

Finally, in terms of pricing, ASP.NET Core SignalR is open-source and free to use. In comparison, Azure SignalR Service is a paid solution, with a usage-based pricing model. 

Copy link to clipboard

Key SignalR features and concepts

We’ll now cover SignalR’s main concepts and features.

A SignalR hub is a high-level pipeline that enables connected servers and clients to define and invoke methods on each other, thus facilitating client-server communication. 

You can write SignalR hubs in C# and add them to any ASP.NET Core application. To create a hub, you have to declare a class that inherits from the Hub Class:

public class ChatHub : Hub

Here’s how you send messages to clients from a SignalR hub:

public async Task SendMessage(string user, string message)
    => await Clients.All.SendAsync("ReceiveMessage", user, message);

public async Task SendMessageToCaller(string user, string message)
    => await Clients.Caller.SendAsync("ReceiveMessage", user, message);

public async Task SendMessageToGroup(string user, string message)
    => await Clients.Group("Chat Users").SendAsync("ReceiveMessage", user, message);

The code snippet above demonstrates how to use three different hub methods:

  • SendMessage sends a message to all connected clients.

  • SendMessageToCaller sends a message back to the caller.

  • SendMessageToGroup sends a message to all clients in a group (Chat Users).

In addition to pushing messages from server code to clients, hubs allow the server to request updates from the client side:

public class ChatHub : Hub
{
    public async Task<string> WaitForMessage(string connectionId)
    {
       var message = await Clients.Client(connectionId).InvokeAsync<string>(
            "GetMessage");
        return message;
    }
}

Clients send updates through .On(...) handlers:

hubConnection.On("GetMessage", async () =>
{
    Console.WriteLine("Enter message:");
    var message = await Console.In.ReadLineAsync();
    return message;
});

SignalR hubs support two data formats: a JSON-based protocol, and a binary protocol inspired by MessagePack. The JSON protocol is used by default. If you wish to enable MessagePack on the server side, first you have to install the Microsoft.AspNetCore.SignalR.Protocols.MessagePack package in your app. Then, you have to specify MessagePack in the Startup.ConfigureServices method:

services.AddSignalR()
    .AddMessagePackProtocol();

The process for enabling MessagePack on the client side differs depending on what client SDK is used. Refer to the docs for more information. 

Copy link to clipboard

SignalR client support

SignalR supports different types of clients:

  • Browsers

  • Desktop apps and mobile apps

  • IoT devices

  • Game consoles

Note that SignalR offers client SDKs targeting .NET, Java, and JavaScript.

Copy link to clipboard

Multi-protocol capabilities

SignalR supports several transport protocols for realtime communication between client and server: WebSockets, Server-Sent Events (SSE), and HTTP long polling. SignalR automatically chooses the best transport method that is supported by both the client and the server. Whenever possible, SignalR will use a WebSocket connection. However, some environments, such as some corporate networks, may not support WebSockets. When that happens, SignalR will gracefully fall back to one of the two alternative transport options (note that SSE is the preferred fallback, while long polling is the last resort).

Learn how SignalR compares to raw WebSockets

Copy link to clipboard

Automatic reconnections

It’s common for client devices to experience brief disconnections. For example, a user might go through a tunnel, or they might switch from a mobile network to their home Wi-Fi. To address these scenarios, you can configure automatic reconnections using the WithAutomaticReconnect method on HubConnectionBuilder, as demonstrated in this example:

HubConnection connection= new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect()
    .Build();

If no parameters are specified for WithAutomaticReconnect, the client attempts to reconnect four times (with a 0, 2, 10, and 30 seconds delay between each reconnection attempt). After four failed reconnection attempts, the client will stop trying to reconnect.

You can also configure a custom number of reconnection attempts. To do so, you can pass an array of numbers, representing the delay between each reconnection attempt. For example, the code snippet below implements two reconnection attempts: the first one takes place immediately after the connection is lost, with no delays, while the second reconnection attempt takes place 10 seconds after the first one fails. 

HubConnection connection= new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(10) })
    .Build();

SignalR supports several different messaging patterns. You can send messages to a particular SignalR connection, as well as broadcast messages to all connections, or a subset of connections that have been placed in a group (the latter is useful for use cases such as chat rooms). In addition, SignalR supports streaming. Note that both the server and the client can stream data to the other side.

Copy link to clipboard

SignalR service mode

You can configure SignalR to support different service modes: Default, Serverless, and Classic. Note that the service mode is a concept that’s specific to Azure SignalR Service; there are no service modes involved when using ASP.NET Core SignalR. 

With Default mode, you have a web server app that hosts a hub (hub server). Both the client and the server connect to SignalR, which acts as a proxy. 

The Default mode is recommended if you’re already familiar with ASP.NET Core SignalR, and wish to migrate from self-hosted SignalR to Azure SignalR Service.

When using Serverless mode, there’s no need for a hub server. Azure SignalR Service bindings for Azure Functions are used instead. You can push messages to clients over WebSocket connections or via Azure SignalR Service data plane REST APIs. Clients can also send messages to the server application, with Azure SignalR Service acting as an intermediary. Messages sent by clients are delivered from Azure SignalR Service to the server app through webhooks. 

Serverless mode is the recommended option if you’re creating a new SignalR project, and don’t want to deal with a hub server and server connections. 

The Classic mode is a mixture of Default and Serverless modes. If there's a hub server, the client connection will be routed to a hub server. If there’s no hub server, a limited Serverless mode will be used instead, with no support for client-to-server messaging. Classic mode is primarily used to ensure backward compatibility for apps created before the Default and Serverless modes were introduced; it’s not recommended to use Classic mode for new SignalR projects.

Copy link to clipboard

SignalR use cases

SignalR can be used to power realtime communication for several different types of use cases:

  • Live chat. 1-to-1 chat, chat rooms, chat bots, support chat, in-game chat.

  • Data broadcast. High-frequency updates sent in a 1-to-many fashion, such as live scores and traffic updates, live captions, voting, polling, and auction apps. 

  • Multiplayer collaboration. Whiteboards and co-authoring apps (such as Google Docs).

  • Notifications across social media and chat apps, online marketplaces, gaming, travel and transportation, etc.

  • GPS location tracking for logistics, fleet management, urban mobility, and food delivery apps. 

Copy link to clipboard

Scaling SignalR

When using ASP.NET Core SignalR, vertical scaling seems like an attractive proposition; it’s relatively easy to set up and maintain, as a single server is involved. However, if you’re building a large-scale system, horizontal scaling - although significantly more complex than vertical scaling - is a more dependable model in the long run. Read more about horizontal vs vertical scaling

Scaling to multiple ASP.NET Core SignalR servers means adding a few new components to your system architecture. First of all, a load balancer layer. Secondly, you need to use the Redis backplane so you can pass SignalR messages between your servers, and keep them in sync. Redis is needed because SignalR servers don’t communicate between themselves, and are unaware of each other’s connections. 

Learn about the challenges of scaling ASP.NET Core SignalR

If you want to avoid hosting, managing, and scaling SignalR infrastructure yourself, then Azure SignalR Service is a better option than ASP.NET Core SignalR. As a fully managed solution, Azure SignalR Service automatically handles scalability and load balancing. 

Learn about the limitations of using Azure SignalR Service at scale

Copy link to clipboard

SignalR limitations

Copy link to clipboard

Poor data integrity guarantees

Data integrity (guaranteed message ordering and guaranteed delivery) is desirable, if not critical for many use cases. Imagine how frustrating it must be for chat users to receive messages out of order. Or think of the impact an undelivered fraud alert can have.   

If the order in which messages are delivered is important to your use case, then SignalR might not be a great fit, because it does not guarantee ordering out of the box. You could make SignalR more reliable by adding sequencing information to messages, but that’s something you’d have to implement yourself. 

Going beyond ordering, SignalR doesn’t guarantee message delivery - there’s no message acknowledgment mechanism built-in. 

Copy link to clipboard

Single-region design

Azure SignalR Service is a regional service - your SignalR instance is always running in a single region. This single-region design can lead to issues and complications such as:

  • Increased latency & poor UX. Since all realtime traffic is routed through a single region, some end-users may deal with significantly increased latencies compared to others. For example, let’s assume you’re building a collaborative whiteboard app with SignalR. Let’s also assume that your SignalR instance is hosted in West US. If you have a user connecting from the US, and another user connecting from India, the latter will experience increased latency compared to the former. This latency difference might seriously impact the UX of the whiteboard app, making it difficult for end-users in different regions to collaborate efficiently.  

  • It’s hard to ensure resiliency. Azure SignalR Service allows you to automatically switch to other instances when some of them are not available. This makes it possible to ensure resiliency and recover when a disaster occurs - you can even have instances deployed in different regions, and when the primary one fails, you can fail over to the secondary one in a different region. However, you will need to set up the right system topology yourself, and your costs will increase, since you’ll be paying for idle backup instances. 

Copy link to clipboard

Service uptime

Azure SignalR Service provides a maximum 99.95% uptime guarantee - for premium accounts - which amounts to almost 4.5 hours of allowed downtime / unavailability per year. The situation is worse for non-premium accounts, where the SLA provided is 99.9% (almost 9 hours of annual downtime).  

These SLAs might not be reliable enough for certain use cases, where extended downtime simply isn’t acceptable. For example, healthcare apps connecting doctors and patients in realtime, or financial services apps that must be available 24/7. 

Copy link to clipboard

Self-hosting SignalR is complex and expensive

Self-hosting SignalR (or any other WebSocket solution) is a complicated affair. You have to think about how you’re going to scale it, ponder how to ensure it’s highly available and fault-tolerant, and manage a lot of moving parts (persistent connections, messages, load balancers, Redis, etc.).

Successfully dealing with all of the above is far from trivial. It’s safe to expect high financial costs to build the system, and additional ones to maintain and improve it. Significant engineering effort is required, shifting away focus from core product development.   

Here are some key stats to give you a taste of how challenging and expensive it is to build and maintain realtime infrastructure in-house:

  • 65% of self-built realtime (WebSocket) solutions had an outage or significant downtime in the last 12-18 months.

  • 10.2 person-months is the average time to build basic realtime infrastructure, with limited scalability, in-house.

  • Half of all self-built realtime solutions require $100K-$200K a year in upkeep.

Read more about the costs and challenges of building realtime infrastructure in-house

Copy link to clipboard

Only 3 client SDKs

SignalR offers only 3 client SDKs, for .NET, Java, and JavaScript. If you were planning to implement SignalR in other languages on the client side, you won’t be able to; unfortunately, there are no SignalR client libraries available for platforms and languages like PHP, Python, Go, Swift, iOS, Ruby, or Flutter.

Copy link to clipboard

SignalR alternatives

We hope this article helps you understand how SignalR works, and allows you to assess if SignalR is the right choice for your realtime project. As we have seen, SignalR offers capabilities like multi-protocol support, automatic reconnections, and flexible messaging (1:1, broadcast, streaming).  

However, SignalR has its drawbacks, such as poor data integrity guarantees and a limited number of client SDKs. Self-hosting SignalR is difficult and expensive, especially if you’re building a large-scale system. While Azure SignalR Service removes the burden of having to manage SignalR infrastructure yourself, it has limitations: it’s a single-region service with an uptime guarantee that might not be reliable enough for some use cases (99.95% for enterprise accounts, 99.9% for the rest).

If you’re planning to build and deliver real time web functionality at scale, it is ultimately up to you to decide if SignalR is the best choice for your use case, or if a SignalR alternative is a better fit. 


Ably, the most reliable SignalR alternative that’s guaranteed to deliver at scale

Ably is a realtime experience infrastructure provider. Our APIs, SDKs, and managed integrations help developers build and deliver realtime experiences without having to worry about maintaining and scaling messy realtime infrastructure. 

Ably offers:

  • A globally-distributed network of datacenters and edge acceleration points of presence. 

  • Client SDKs for every major programming language and development platform. 

  • Pub/sub APIs with rich features, such as message delta compression, multi-protocol support (WebSockets, MQTT, Server-Sent Events), automatic reconnections with continuity, presence, and message history. 

  • Guaranteed message ordering and delivery. 

  • Global fault tolerance and a 99.999% uptime SLA.

  • < 65ms round-trip latency for 99th percentile.

  • Elastic scalability to handle millions of concurrent clients.

Find out more about Ably and how we can help with your realtime use case:

Join the Ably newsletter today

1000s of industry pioneers trust Ably for monthly insights on the realtime data economy.
Enter your email