---
title: "Build Real-Time Dashboards in Blazor with gRPC Streaming for High-Performance Apps"
published_at: "2025-10-24T06:29:36+00:00"
modified_at: "2025-12-02T06:22:32+00:00"
url: "https://www.syncfusion.com/blogs/post/blazor-with-grpc-streaming"
excerpt: "Learn how to implement real-time dashboards in Blazor with gRPC streaming. Explore server-streaming, performance optimization, and best practices for scalable .NET applications."
taxonomy_category:
  - ".NET development"
  - "Blazor"
  - "gRPC Streaming"
  - "Performance Optimization"
  - "Real-Time Dashboards"
taxonomy_post_tag:
  - ".NET Core"
  - "Blazor"
  - "Blazor gRPC Streaming"
  - "Blazor real-time data updates"
  - "Dashboard UI"
  - "gRPC"
  - "gRPC server streaming in .NET"
  - "Real-Time Data"
---

# Build Real-Time Dashboards in Blazor with gRPC Streaming for High-Performance Apps

[Chameera Dulanga](https://www.syncfusion.com/blogs/author/chameera-dulanga)

![Image](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/Blazor-gRPC-Streaming-Explained-Build-Scalable-Real-Time-Apps.jpg)


**TL;DR:** Struggling with laggy dashboards and delayed updates? Traditional REST APIs can’t handle real-time data efficiently. This guide shows how Blazor with gRPC streaming delivers lightning-fast, server-driven updates for responsive dashboards. Learn implementation steps, performance tuning, and best practices for scalable .NET apps.

Real-time dashboards aren’t optional, they’re critical for applications where every second counts. Think **stock trading**, ** health monitoring**, or ** delivery tracking**. A single missed update can cost money, jeopardize safety, or delay shipments.

Traditional REST APIs struggle with continuous updates because they rely on polling, which adds latency and overhead. **gRPC server-streaming** solves this by pushing low-latency updates directly to the browser over an always-open connection.

In this guide, you’ll combine **Blazor’s component model** with ** gRPC server-streaming** to build dashboards that stay in sync with live data. We’ll cover

- Setting up a secure HTTP/2 streaming environment
- Implementing server-streaming in gRPC
- Connecting Blazor UI to the stream
- Optimizing performance and reliability

## Step 1: Setting up the development environment

Real-time streaming requires two parts working together:

- Blazor UI to display data
- gRPC service to send updates

You’ll create both projects, add references, and configure Kestrel for HTTP/2 with TL.

### Creating the projects

Open a new terminal in an empty directory and run these commands to scaffold your solution: a Blazor Server front-end for the UI and a gRPC back-end for real-time data streaming:

```
dotnet new sln -n RealTimeDashboard
dotnet new blazorserver -n DashboardApp
dotnet new grpc -n DashboardGrpc

dotnet sln add DashboardApp/DashboardApp.csproj
dotnet sln add DashboardGrpc/DashboardGrpc.csproj
```

Your folder structure will look like this:

```
RealTimeDashboard/
├─ DashboardApp/ # Blazor UI
│  └─ Program.cs
├─ DashboardGrpc/ # gRPC back end
│  └─ Program.cs
└─ RealTimeDashboard.sln
```

You can find the complete codebase of this application in this [GitHub](https://github.com/ChameeraD/RealTimeDashboard/tree/main)
 repository.

### Reference the gRPC project

Blazor needs access to gRPC message types. Add a reference in [DashboardGrpc.csproj](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardGrpc/DashboardGrpc.csproj)
 file:  
 ![DashboardGrpc.csproj file](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image017-1.png)

### Configure protobuf generation

In the [DashboardApp.csproj](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardApp/DashboardApp.csproj)
 file, we need to configure **Protobuf generation** so the client and server code are auto-generated from your **.proto file**:

![.proto file](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image019.png)

In `DashboardGrpc.csproj` file, add this code:

![proto code](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image021.png)

These settings instruct the build process to:

- Generate client-side code in DashboardApp (GrpcServices=”Client”)
- Generate server-side code in DashboardGrpc (GrpcServices=”Server”)
- Share the .proto file from the gRPC project to prevent duplication

### Enable HTTP/2 and TLS on the gRPC host

gRPC requires HTTP/2, and browsers demand TLS for it. Update [Program.cs](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardGrpc/Program.cs)
 in the gRPC project to enable HTTPS and HTTP/2. Then run:

![HTTP/2and TLS](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image023.jpg)

**Note:** Run **dotnet run** inside DashboardGrpc to confirm the server starts with no errors.

## Step 2: Add gRPC Client to Blazor

To enable the Blazor UI to communicate with the gRPC service, you need a **typed client**. Follow these steps:

### 1. Install the gRPC client package

From the solution root, run:

```
cd DashboardApp
dotnet add package Grpc.Net.Client
cd ..
```

### 2. Register the gRPC client in Blazor

Open [DashboardApp/Program.cs](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardApp/Program.cs)
 and add the following client configuration:

```
// DashboardApp/Program.cs
builder.Services.AddGrpcClient<DashboardService.DashboardServiceClient>(options =>
{
    // The same HTTPS address you opened in Program.cs of the gRPC host
    options.Address = new Uri("https://localhost:5001");
});
```

### 3. Run both projects

When you press F5 (or dotnet run in the solution root), both projects start:

- **DashboardGrpc** launches on https://localhost:5001 with HTTP/2.
- **DashboardApp** launches on its default port (usually https://localhost:5002) and connects to the gRPC endpoint you just registered.

At this point, your environment supports a secure, always‑on stream from the gRPC server to any Blazor component. Next, you’ll add the **.proto file**, implement the service logic, and bind the UI to live data.

## Step 3: Implement gRPC server-streaming

Real-time dashboards need a communication pattern that supports continuous updates without constant polling. gRPC offers four call patterns:

- **Unary**: client sends one request; server returns one reply.
- **Server‑streaming**: client sends one request; server keeps sending multiple responses.
- **Client‑streaming**: client streams multiple requests, server returns one response.
- **Bidirectional**: both sides send multiple messages at the same time.

Here, we focus on server‑streaming because dashboards mostly consume continuous data but rarely need to push large amounts back.

### Define the proto contract

Create a new file at [DashboardGrpc/Protos/dashboard.proto](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardGrpc/Protos/dashboard.proto)
 and add the following:

![DashboardGrpc/Protos/dashboard.proto file](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image028.jpg)

- Use a **while loop** to keep sending updates until the client disconnects.
- Handle cancellation with **`context.CancellationToken`** for clean shutdown.
- Use `Task.Delay(..., context.CancellationToken)` to control update intervals and break out on cancellation.

### Keep-alive and connection health

- gRPC over HTTP/2 uses built-in keep-alive pings to prevent idle timeouts.
- You can adjust Kestrel’s keep-alive settings in `program.cs` if your network drops idle connections.
- For most development scenarios, the defaults work fine.

## Step 4: Building an interactive dashboard UI

Now it’s time to connect your **Blazor UI** to the ** gRPC stream**, consume each incoming DataPoint, and update the page in real time. You’ll start by rendering raw values, then upgrade to a chart without changing the underlying data flow.

### Register and inject the gRPC client

Make sure you’ve already registered the client in `Program.cs`. In any Razor component, inject it like this:

```
@using DashboardGrpc
@inject DashboardService.DashboardServiceClient Grpc
```

### Create a basic razor page

Add a new component at [DashboardApp/Components/Pages/LiveData.razor](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardApp/Components/Pages/LiveData.razor)
:

![DashboardApp/Components/Pages/LiveData.razor file](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image029.jpg)

- **StartStream** opens the gRPC call and loops through incoming messages.
- Each DataPoint is added to a list, trimmed to the last 100 items.
- StateHasChanged() refreshes the UI.
- **StopStream** cancels the token for a clean disconnect.

### Upgrade to Charts

You can plug in any Blazor chart library. For example, install [Syncfusion Blazor Charts](https://www.syncfusion.com/blazor-components/blazor-charts)
.

```
dotnet add package Syncfusion.Blazor.Charts
```

Update the Razor page to render charts instead of raw lists. You can find the updated Razor component [here](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardApp/Components/Pages/LiveData.razor)
.

![DashboardApp/Components/Pages/LiveData.razor](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image031.jpg)

In **StartStream**, replace `StateHasChanged()` with await `RenderChart()` to redraw the chart for each new batch of points. By separating data collection from rendering, you can switch between raw lists, tables, or charts without changing the streaming logic.

## Optimizing performance

Enable `gzip compression` in the Program.cs:

```
builder.Services.AddGrpc(options =>
{
    options.ResponseCompressionAlgorithm = "gzip";
    options.ResponseCompressionLevel = CompressionLevel.Fastest;
});
```

### Automatic reconnect with exponential back‑Off

Wrap your streaming call in a helper that retries on failures:

![Exponential back-off](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image033.jpg)

Use it in place of StartStream:

```
await RunWithRetry(ct => StartStream(ct), cts.Token);
```

This ensures short network blips do not break your dashboard. I have already implemented this in the [LiveData.razor](https://github.com/ChameeraD/RealTimeDashboard/blob/main/DashboardApp/Components/Pages/LiveData.razor)
 page.

### Scaling and profiling

- Deploy multiple gRPC servers behind a layer‑4 load balancer. If each UI instance must remain sticky, enable source‑IP or cookie affinity.
- Monitor with **dotnet-counters monitor grpc** to track call counts, latencies, and thread usage in real time.
- **Load-test** with k6-grpc or ** ghz** to simulate thousands of parallel clients:

```
brew install k6 # macOS
choco install k6 # Windows
k6 install xk6-grpc
```

Create a load test file [load-test.js](https://github.com/ChameeraD/RealTimeDashboard/blob/main/load-test.js)
:

![Load test js](https://www.syncfusion.com/blogs/wp-content/uploads/2025/10/image035.png)

Run the load test:

```
k6 run load-test.js --vus 100 --duration 30s
```

This simulates 100 virtual users connecting to your gRPC service for 30 seconds.


## Conclusion

Thanks for reading! In this guide, you’ve built an end-to-end solution:

- **Environment**: Blazor UI and gRPC host configured for HTTP/2 + TLS.
- **Streaming**: proto definitions and server‑streaming implementation.
- **UI binding**: consuming IAsyncEnumerable and rendering as lists or charts.
- **Optimization**: compression, batching, reconnect logic, scaling, and profiling.

To take this further:

- **Secure the stream** with JWT tokens or mutual TLS so only authorized clients can subscribe.
- **Compare with SignalR** if you need bidirectional messaging or legacy browser support without a proxy.
- **Extend your proto** to support multiple data sources, alerts, or user commands for richer interactivity.

Apply these patterns in your next project to deliver responsive dashboards that keep pace with real‑world data.

If you’re a Syncfusion user, you can download the setup from the [license and downloads](https://www.syncfusion.com/account/downloads)
 page. Otherwise, you can download a free [30-day trial](https://www.syncfusion.com/downloads/)
.

You can also contact us through our [support forum](https://www.syncfusion.com/forums)
, [support portal](https://support.syncfusion.com/)
, or [feedback portal](https://www.syncfusion.com/feedback)
 for queries. We are always happy to assist you!

## Related Blogs



[10 Steps to Replace REST Services with gRPC-Web in Blazor WebAssembly](https://www.syncfusion.com/blogs/post/10-steps-to-replace-rest-services-with-grpc-web-in-blazor-webassembly)



[Fix Broken Charts Instantly: Handle Missing Data Like a Pro in Blazor!](https://www.syncfusion.com/blogs/post/handle-missing-data-blazor-charts)



[Visualize Financial Insights Instantly with Blazor Waterfall Charts](https://www.syncfusion.com/blogs/post/blazor-waterfall-charts-financial-insights)



[How to Add Error Bars to Blazor Charts: A Complete Guide with Examples](https://www.syncfusion.com/blogs/post/add-error-bars-blazor-charts-examples)
