In this lesson, you will learn how to quantify round-trip latency in SignalR applications to pinpoint whether performance bottlenecks originate from network transit, server-side processing, or client-side dispatching.
The Anatomy of SignalR Latency
When measuring latency in distributed systems, we must distinguish between the "wire time" (network transit) and the "processing time." In SignalR, a round-trip measurement involves sending a timestamped message from the client to the Hub and receiving an echoed response.
To analyze this accurately, avoid relying on simple system clocks if your clients are globally distributed, as clock drift can skew results. Instead, calculate the Round-Trip Time (RTT) using a consistent reference point.
Implementing a Latency Probe
The most effective way to identify bottlenecks is to implement a "heartbeat" probe within your Hub. By sending a high-resolution timestamp from the client, the server can record the arrival time, process the logic, and return the original timestamp alongside the server’s arrival time.
// Client-side C# (Blazor/Console)
var startTime = Stopwatch.GetTimestamp();
await hubConnection.InvokeAsync("Ping", startTime);
// Server-side Hub
public void Ping(long clientStartTime)
{
var serverArrivalTime = Stopwatch.GetTimestamp();
// Calculate server processing overhead
var processingDuration = Stopwatch.GetTimestamp() - serverArrivalTime;
Clients.Caller.SendAsync("Pong", clientStartTime, serverArrivalTime);
}
Identifying Bottlenecks
Once you have your RTT data, categorize your findings:
- High Network Latency: If the duration between the client sending and the client receiving is consistently high, but the
processingDurationis negligible, the bottleneck is the physical network path or the WebSocket negotiation overhead. - Server-Side Saturation: If the
processingDurationspikes, check your Hub's execution context. This often happens if you are blocking the thread pool with synchronous calls or if the Hub's dependency injection scope is struggling with high-latency operations (e.g., slow database queries). - Serialization Overhead: If the latency increases specifically with large payloads, the bottleneck is likely the JSON (or MessagePack) serialization process, which consumes CPU cycles before the data even touches the network stack.
By sampling these probes under varying load levels, you can determine if your SignalR infrastructure scales linearly or if you are hitting architectural limits.
Key Takeaway: Precise latency analysis requires measuring the delta between timestamps captured at the source, arrival, and completion points to isolate network transit from server-side execution delays.