# A Beginner's Guide to Server-Sent Events (SSE)

Server-Sent Events (SSE) is a web standard that lets a server push data to a browser in real-time over a single, long-lived HTTP connection. Think of it as a one-way communication channel where the server can continuously send updates to the client without the client having to repeatedly ask for them.

How ChatGPT uses Server-Sent Events to give answer of one prompt.

* You **write one prompt.**
    
* Server keeps pushing updates to you as they happen from model.
    

Here i’ve asked one simple question.

![Simple ChatGPT Prompt.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750498386168/46f230b7-547d-4d10-a6de-10bb5d30b58d.png align="center")

Inspect the request that we’ve sent.

![ChatGPT Request.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750498447856/9c5027ea-864b-417c-8d93-a5a1e8ce4731.png align="center")

![ChatGPT Request Header.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750498507994/7b95e881-676d-4234-bcb4-7990ff542bca.png align="center")

![ChatGPT Request Header where our prompt is being passed..](https://cdn.hashnode.com/res/hashnode/image/upload/v1750498549135/a704dc9e-79d2-43be-916e-36554331bf20.png align="center")

Now, we can see the EventStream result. It keeps pushing data to the connection as it receives it. Look at the time, many metadata-related responses and the actual response are being sent.

![ChatGPT Response of EventStream where answer is given with other metadata.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750498632478/7ca812bb-7098-4f2d-a5b6-0e07bb286096.png align="center")

![ChatGPT Response of EventStream where answer is given with other metadata.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750498730440/af463a56-17c0-4f74-a0d3-d6b418ee5dda.png align="center")

## What's the difference between Polling, WebSocket and Server-Sent Events?

Polling is about client sending requests to the server at regular intervals to check if there are any new updates. sometimes there is no new data at server side, resulting in unnecessary request.

WebSocket is generally suitable for bidirectional communication on single active connection, for example: collaboration tools, real time polling app.

Server-Sent Event is lightweight, one directional communication from server to client over HTTP, it’s unidirectional only.

## Example:

Here is simple SSE Example, the API endpoint gives the current Date & Time in response at every second.

```csharp
app.MapGet("/stream-time", async (HttpContext context) =>
{
    var response = context.Response;
    response.Headers.Append("Content-Type", "text/event-stream");
    response.Headers.Append("Cache-Control", "no-cache");
    response.Headers.Append("Connection", "keep-alive");

    while (!context.RequestAborted.IsCancellationRequested)
    {
        var message = $"The time on the server is: {DateTime.Now:T}";
        await response.WriteAsync($"data: {message}\n\n");
        await response.Body.FlushAsync();
        await Task.Delay(1000);
    }
});
```

```xml
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Minimal SSE Demo</title>
</head>
<body>

    <h1>Server-Sent Events Demo</h1>

    <p>
        <strong>Connection Status:</strong>
        <span id="status">Connecting...</span>
    </p>

    <p>
        <strong>Latest Server Message:</strong>
    </p>
    <div id="live-data">
        Waiting for data...
    </div>

    <script>
        const statusElement = document.getElementById('status');
        const dataElement = document.getElementById('live-data');

        const SSE_ENDPOINT = 'http://localhost:5139/stream-time';

        // This is the key line. Browser provides EventSource API to implement SSE.
        const eventSource = new EventSource(SSE_ENDPOINT);

        eventSource.onopen = function () {
            console.log("Connection to server opened.");
            statusElement.textContent = 'Connected';
        };

        eventSource.onmessage = function (event) {
            console.log("Received data:", event.data);
            dataElement.textContent = event.data;
        };

        eventSource.onerror = function (error) {
            console.error("EventSource failed:", error);
            statusElement.textContent = 'Error / Disconnected';
        };

    </script>

</body>
</html>
```

So when we load the page, API get’s hit and Single HTTP Connection gets established which gives date and time and on UI we get date and time.

![SSE Request EventSteam.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750509591802/7cf88dd2-bc35-42dd-80f5-c8a2d633ffea.png align="left")

![Response of SSE API.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750509607336/68f69707-d7a1-4081-b0ce-7abc9960e4de.png align="left")

![Log of Response of SSE API.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750510334778/0a2ac868-29ae-46bc-9c4f-acec9963b8de.png align="center")

![Front End showing data that we received from API.](https://cdn.hashnode.com/res/hashnode/image/upload/v1750509742916/a80c91c5-4a9e-41cf-8aee-7d654d54bc6f.gif align="left")

Now you might realize how ChatGPT and other AI applications use the same concept of Server-Sent Events to take advantage of this browser feature for their needs, instead of choosing WebSocket, which might be too complex for the same purpose.

For more understanding and real-world use cases, you can refer to the list of blogs below.

[https://developer.mozilla.org/en-US/docs/Web/API/Server-sent\_events/Using\_server-sent\_events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)  
[https://shopify.engineering/server-sent-events-data-streaming](https://shopify.engineering/server-sent-events-data-streaming)  
[https://germano.dev/sse-websockets](https://germano.dev/sse-websockets)
