Hi! In this post, I’ll share how we used SignalR in .NET Core to build a real-time API Health Check Dashboard, something we actually deployed, not just a side project. This article is not a generic tutorial, I’ll speak to you like I would to a teammate or fellow dev friend. You’ll get the context, the logic, the gotchas, and some actual code and diagrams.
So, grab coffee. This one’s a bit long, around 30-minute read but I promise, it’s going to be worth it especially if you’re planning to implement real-time updates.
What is SignalR (In Plain Words)
SignalR is like a bridge between your server and browser, allowing them to talk to each other instantly like messaging apps do.
Normally, HTTP is “pull-based”. Your client (browser) keeps asking, “Any update?” But with SignalR, it becomes “push-based”. The server notifies the client when something happens almost like magic.
Technically, SignalR abstracts WebSockets, Long Polling, and Server-Sent Events. So you don’t need to worry which protocol is supported by the browser or the server. SignalR negotiates it for you.
Why We Used SignalR (Real Story)
We built an internal dashboard to monitor the health of various APIs. Before SignalR, the dashboard had to be refreshed manually every few minutes or use JavaScript intervals calling REST endpoints. Not only was it inefficient, it was also slow, sometimes the API was already down, but the UI still showed “OK”.
With SignalR, we flipped that around. When a service became unhealthy, our backend would instantly push the status update to all connected clients. The dashboard turned red within milliseconds. Everyone loved it.
Use Case: Real-Time API Health Dashboard
Let’s zoom in on a real-world scenario where SignalR made a huge difference for us.
We had a setup with more than 20 internal APIs running across different environments some in Azure, some on-prem, and some in staging environments that often got missed. These APIs were being hit by different services and clients. Sometimes, one API would go down without anyone knowing until users started reporting errors.
We used to rely on polling, the frontend JavaScript would call a health-check API every 60 seconds to check status. But that approach wasn’t reliable. What if an API failed after 2 seconds from the last poll? The dashboard wouldn’t show it until the next minute.
So we asked ourselves:
What if the server could push the update the moment it detects an issue?
That’s where SignalR came in.
Here’s How It Works
We built a backend service, a simple HealthMonitor class that checks each API’s health every 30 seconds. When it detects something unusual (like an API responding slowly, or failing entirely), it sends a real-time message via SignalR to all connected dashboard clients.
Sample SignalR Hub
public class HealthHub : Hub
{
public async Task BroadcastHealthStatus(string apiName, string status, int responseTime)
{
await Clients.All.SendAsync("ApiHealthUpdated", apiName, status, responseTime);
}
}
The BroadcastHealthStatus method is called whenever a monitored API’s status changes. This instantly tells all connected clients what happened.
JavaScript: Receiving the Update
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.0/signalr.min.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/healthhub")
.build();
connection.on("ApiHealthUpdated", (api, status, time) => {
updateHealthUI(api, status, time); // Change status indicator (e.g., red, green)
});
connection.start().catch(console.error);
</script>
The browser listens for any ApiHealthUpdated messages. When it receives one, the UI updates immediately no reloads, no waiting.
For example: If our /payments API suddenly times out, the dashboard turns red instantly and everyone sees the change in real-time.
Backend Check Trigger
public class HealthMonitor
{
private readonly IHubContext<HealthHub> _hub;
public HealthMonitor(IHubContext<HealthHub> hub)
{
_hub = hub;
}
public async Task RunHealthChecksAsync()
{
foreach (var api in _monitoredApis)
{
var result = await CheckApiAsync(api); // Ping the API, get status
await _hub.Clients.All.SendAsync("ApiHealthUpdated", api.Name, result.Status, result.Time);
}
}
}
This task is scheduled using a background worker or a hosted service in .NET, and it keeps running in the background.
Why This Setup Was Powerful
- We saw service disruptions in real time, without waiting for error reports.
- Our support team was notified before users even noticed issues.
- We added audio alerts and email integration later but SignalR was the foundation.
And the best part? No more writing client-side loops to poll APIs every few seconds. The server owned the timing, and the dashboard simply reacted.
It made our monitoring tool feel alive, not passive.
SignalR Under the Hood: How It Works
- Client connects to the SignalR Hub.
- SignalR negotiates the best protocol (WebSocket, Long Polling, etc.)
- Server sends messages using Clients.All.SendAsync(…)
- Client receives messages via .on(…) handler.
You don’t manage connections manually. SignalR handles connection IDs, reconnection attempts, and fallback logic automatically.
When to Use SignalR
Use SignalR when your app needs to respond immediately to server-side events:
- Live dashboards (health, analytics, stock, payments)
- Real-time chat or messaging
- Multiplayer games
- Collaborative document editing
- Background job progress notifications
- Alert systems (e.g., fraud detection, downtime warnings)
When NOT to Use SignalR
SignalR is awesome but it’s not always the best tool. Avoid using it when:
Scenario | Better Alternative |
---|---|
Simple periodic updates | Use REST with polling |
Massive client base (100K+) | Consider Message Queues (e.g., Kafka, MQTT) |
Mobile push notifications | Use FCM/APNS |
Highly scalable pub-sub | Use Azure SignalR, Redis Backplane, or external brokers. |
If your update doesn’t need to happen instantly, or your audience is too large, rethink SignalR.
Pros of SignalR
- Real-time without polling
- Cross-browser and fallback support
- Integrates easily with .NET Core
- Supports groups, users, and connections
- Handles reconnect logic for you
Cons / Gotchas
- Scaling is tricky (you’ll need Redis or Azure SignalR for multi-server)
- Not great for broadcasting to 100k+ clients
- Doesn’t work well on low-bandwidth networks
- Needs WebSocket support (most modern browsers have this, but proxies/firewalls can be a blocker)
Scaling SignalR in Production
If you plan to scale your app to multiple instances, you need a backplane:
- Redis: Syncs messages across multiple app instances
- Azure SignalR Service: Cloud-based, auto-scaled
dotnet add package Microsoft.AspNetCore.SignalR.StackExchangeRedis
Diagram: SignalR Real-Time Flow (API Health Monitoring)
This diagram illustrates the flow of real-time communication in a health monitoring system using SignalR:

1. Server Checks API Health
The process begins with a server-side health monitoring service. This service regularly performs health checks on a list of APIs by sending HTTP requests and analyzing the response such as checking:
- Status code (e.g., 200, 500)
- Response time (e.g., latency thresholds)
- Timeout or unreachable endpoints
If something goes wrong like the response time spikes or the API fails the server detects it immediately.
2. Triggers SignalR
Once the server detects an issue (or a recovery), it sends a message through SignalR, which acts as the middleman that takes care of the connection to all clients.
SignalR decides the best communication channel (WebSocket, SSE, or Long Polling) and handles the connection reliability for you.
3. Sends Update to All Clients
SignalR then broadcasts this update to all connected clients — typically browser-based dashboards that multiple users are viewing in real time.
You can also target specific clients, groups (e.g., per department), or user roles (e.g., engineers only), but in this case we used Clients.All for simplicity.
4. Dashboard Turns Red/Green
On the client side (web dashboard):
- If an API is healthy, the UI element turns green
- If it becomes unhealthy, it turns red
Each dashboard updates immediately no refresh required keeping your team informed with up-to-the-second data.
This is especially useful for:
- NOC (Network Operations Center) displays
- Developer portals
- On-call engineers who need fast alerting
Testing Tips
- Test multiple browsers and devices.
- Simulate network disconnections (see if reconnect works).
- If hosting on IIS or Nginx, ensure WebSockets are enabled.
- Use browser dev tools to inspect WebSocket frames.
References & Docs
I highly recommend reading through these:
- SignalR Introduction – Microsoft Docs
- SignalR JavaScript Client
- GitHub: ASP.NET Core SignalR
- Scaling SignalR with Redis
Final Thoughts
SignalR changed how we think about responsiveness in web apps. No more dirty polling hacks. No more delayed UIs. Just instant updates and that “wow” moment when you show your team a dashboard that reacts in real time.
If you’re building a system where users are waiting for updates, give SignalR a try. Just like in our health dashboard, your users will feel the difference.
Visit marai.dev where I document my learnings from real-world .NET projects.