← Back to list

Understanding Server-Sent Events (SSE) in ASP.NET Core

There comes a point in almost every application where the server needs to notify the client that something has changed.

Obed Danso · 2026-07-26 13:57 · 0 claps · 3.8 min read
#dotnet #web #realtime #web-architecture #javascript
Open on Medium ↗
Wiki topics: 🌐 · Web Development 🏛️ · Architecture

Understanding Server-Sent Events (SSE) in ASP.NET Core

An image from Vincent Delsuc Pexels

An image from Vincent Delsuc Pexels

There comes a point in almost every application where the server needs to notify the client that something has changed.

Maybe you’re building a financial platform that streams stock prices every minute. Maybe you’re monitoring a background job that processes uploaded files. Maybe you’re building a dashboard showing live system metrics.

Most developers immediately think of WebSockets.

But what if your application doesn’t need two-way communication?

What if the client only needs to receive updates from the server?

That’s exactly where Server-Sent Events (SSE) shines.

SSE is a standardized HTTP technology that allows a server to continuously push updates to a client over a single long-lived HTTP connection. Unlike traditional HTTP requests that end after sending a response, an SSE connection stays open, allowing the server to stream new events whenever data becomes available.

The best part is that it works over plain HTTP and is supported natively by modern browsers through the EventSource API.

When Should You Use Server-Sent Events?

SSE isn’t meant to replace WebSockets. It’s designed for a different kind of problem.

Whenever information only flows from the server to the client, SSE is usually simpler.

If your application needs clients to also send live messages back to the server — such as multiplayer games or chat applications — then WebSockets are usually the better choice.

How Does SSE Work?

The concept is surprisingly simple.

  1. The client sends an HTTP GET request.
  2. The server accepts the request.
  3. Instead of closing the response, the server leaves it open.
  4. Whenever new information becomes available, the server writes another event into the response stream.

The response uses a special content type:

Content-Type: text/event-stream

Every event follows a very small text-based format.


event: message
data: {"time":"12:00:01","status":"active"}

event: priceUpdate
data: {"symbol":"MSFT","price":420.50}

Each event ends with an empty line.

That’s all there is to the protocol.

A Simple View of the Connection

+------------+                               +-------------+
|            |                               |             |
|   Client   |                               |   Server    |
|  Browser   |                               | ASP.NET API |
+-----+------+                               +------+------+
      |                                             |
      | GET /events                                 |
      |-------------------------------------------->|
      |                                             |
      | HTTP 200 OK                                 |
      | Content-Type: text/event-stream             |
      |<--------------------------------------------|
      |                                             |
      | data: Server Started                        |
      |<--------------------------------------------|
      |                                             |
      | data: Processing...                         |
      |<--------------------------------------------|
      |                                             |
      | data: Finished                              |
      |<--------------------------------------------|

Notice that the HTTP connection never closes until either the client disconnects or the server ends the stream.

The Simplest ASP.NET Core Implementation

Creating an SSE endpoint is surprisingly straightforward.

The endpoint simply writes data to the response stream and flushes it immediately so the client receives each event as soon as it’s available.

app.MapGet("/events", async (HttpContext context) =>
{
    context.Response.Headers.Append("Content-Type", "text/event-stream");
    context.Response.Headers.Append("Cache-Control", "no-cache");
// Configure CORS appropriately for your application.
    context.Response.Headers.Append("Access-Control-Allow-Origin", "*");
    for (int i = 0; i < 10000; i++)
    {
        var data = $"data: Server time is {DateTime.Now:HH:mm:ss}\n\n";
        await context.Response.WriteAsync(data);
        // Immediately send buffered data to the client.
        await context.Response.Body.FlushAsync();
        await Task.Delay(1000);
    }
});

The response will continuously stream data instead of returning a single payload.

Listening from the Browser

Modern browsers include native support through the EventSource class.

Creating a connection requires only a single line.

<script>
const evtSource = new EventSource("http://localhost:5000/events");evtSource.onmessage = (e) => {
    console.log("Received:", e.data);
};
</script>

Every time the server writes another data: event, the browser immediately invokes the callback.

Looking a Little Deeper

The previous example sends plain messages.

In production you’ll often want to categorize events.

Instead of relying only on onmessage, you can define custom event types.

Server

event: priceUpdate
data: {"symbol":"MSFT","price":420.50}

event: orderCompleted
data: {"orderId":1234}

Client

const source = new EventSource("/events");

source.addEventListener("priceUpdate", (event) => {
    const price = JSON.parse(event.data);
    console.log(price);
});
source.addEventListener("orderCompleted", (event) => {
    const order = JSON.parse(event.data);
    console.log(order);
});

This allows multiple kinds of updates to share a single HTTP connection while remaining easy to organize.

Server Libraries

If you’re building clients outside the browser, there are libraries available for most popular languages.

LanguageLibraryEquivalentJavaScriptNativeEventSourceNode.jseventsourceEventSourcePythonsseclient, httpx-sseSSEClientJavaJAX-RSSseEventSourceC#LaunchDarkly.EventSourceEventSourceGor3labs/sseClientRusteventsource-clientEventSourceClientPHPCommunity implementationsVaries

Production Considerations

Although SSE is simple, there are a few things worth remembering before deploying it to production.

CORS

If your frontend and backend run on different domains, configure CORS appropriately.

Connection Timeouts

Reverse proxies such as NGINX, load balancers, and cloud providers may terminate idle connections.

Configure them to allow long-running HTTP streams.

Buffering

Some proxies buffer HTTP responses before forwarding them.

Disable response buffering for SSE endpoints so events are delivered immediately.

Automatic Re-connection

One of the nicest features of EventSource is that browsers automatically reconnect if the connection drops.

In many cases you don’t have to write re-connection logic yourself.

HTTP Version

Although SSE works over HTTP/2 in many modern environments, deployments commonly use HTTP/1.1 for long-lived streaming connections because proxy and infrastructure support is generally more predictable. Verify the behavior of your hosting platform and reverse proxy.

ASP.NET Core 10

At the time of writing, .NET 10 introduces first-class support for Server-Sent Events through TypedResults.ServerSentEvents().

If you’re targeting .NET 10 or later, it’s worth looking at the new API because it removes much of the manual response-writing shown in this article.

Final Thoughts

Server-Sent Events are one of those technologies that are often overlooked because WebSockets receive most of the attention.

But for applications where data only needs to travel from the server to the client, SSE is often the simpler, lighter, and more maintainable solution.

If you’re building dashboards, monitoring tools, financial systems, deployment logs, notifications, or any application that streams updates in one direction, SSE is well worth considering.


메타데이터
post_id
181be46280f8
slug
understanding-server-sent-events-sse-in-asp-net-core-181be46280f8
url
https://medium.com/@obeddanso/understanding-server-sent-events-sse-in-asp-net-core-181be46280f8
canonical_url
https://medium.com/@obeddanso/understanding-server-sent-events-sse-in-asp-net-core-181be46280f8
author_url
https://medium.com/@obeddanso
status
ok
fetched_at
2026-08-12 12:03:22