CLOUD CONCEPT

Server-Sent Events

Server-Sent Events is an HTTP-based mechanism for delivering a continuous stream of text events from a server to a client over a long-lived response.

Cloud Concepts Hub →

What is Server-Sent Events

Server-Sent Events (SSE) lets applications push incremental updates without repeated client polling, using the text/event-stream media type. It is useful for foundation model responses, progress notifications, and live status feeds when updates primarily flow from server to client. Streaming improves perceived responsiveness by displaying available output before the complete operation finishes.

Server-Sent Events (SSE) defines a text event format delivered through a long-lived HTTP response. The client initiates a request, and the server responds with the text/event-stream media type, keeping the response open while sending events. In browsers, the EventSource API parses this format, dispatches events, and normally reconnects after an interrupted connection. SSE is unidirectional within that response: sending another prompt, canceling a job, or submitting user feedback requires a separate request or another communication mechanism.

Events use UTF-8 text with fields such as data, event, id, and retry. A blank line terminates an event, and multiple data lines within one event are joined with newline characters. For example, an application can send an event field of token and a data field containing a JSON object with a generated text fragment. The client must parse complete event boundaries rather than assume that each network read contains exactly one event. Transport chunks can split an event or contain several events.

For real-time AI interactions, an application backend invokes a foundation model through a streaming API and translates the resulting model events into browser-facing SSE events. With Amazon Bedrock, ConverseStream or InvokeModelWithResponseStream can provide incremental output where supported by the selected model and API. Bedrock's event stream is not itself a browser-compatible SSE response; the backend must decode the SDK events, extract relevant text or metadata, and encode SSE messages. A practical assistant can emit text updates, usage metadata, an application-defined completion event, and structured errors.

The entire delivery path must support streaming. A backend that flushes each fragment still appears buffered if a gateway, reverse proxy, compression layer, or application framework waits for the complete response. Configure supported response-streaming integrations explicitly, disable inappropriate caching and buffering, and test the public endpoint rather than only the application process. For API Gateway, use a REST API integration that supports response streaming and configure its response transfer mode accordingly; do not assume every API type or integration streams responses.

SSE and HTTP chunked transfer encoding are different concepts. SSE defines application-level event framing, whereas chunked transfer encoding frames an HTTP/1.1 message body. An SSE response can use HTTP/1.1 chunked transfer encoding, but HTTP/2 carries streaming data in its own frames without that encoding. Merely enabling chunked transfer does not create SSE events or guarantee immediate delivery. WebSockets, by contrast, provide bidirectional messaging and are often preferable for continuous two-way interaction, such as interactive audio.

Operationally, use periodic comment lines as heartbeats to help prevent idle connections from being closed, while respecting the shortest timeout anywhere in the path. Apply connection limits, bounded buffering, and slow-client handling. Propagate cancellation upstream when possible so disconnected users do not leave unnecessary model generation running. Measure time to first useful event separately from total generation latency: streaming can improve perceived responsiveness without reducing model execution time.

Automatic reconnection does not guarantee reliable replay. Event IDs and the Last-Event-ID request header support resumption only when the server retains events and implements replay logic; clients may also need deduplication. Native browser EventSource uses GET and does not expose arbitrary request-header configuration. Applications needing POST bodies or bearer authorization headers can use fetch with a streaming response and an SSE parser, but must implement reconnection themselves. Authenticate connections, enforce authorization for each stream, configure CORS appropriately, and avoid sensitive credentials in URLs. Once response headers have been sent, communicate later failures through application-defined events or connection termination rather than attempting to change the HTTP status.

Key aspects of Server-Sent Events

SSE combines HTTP-based one-way updates, structured text events, and reconnect support, while requiring explicit attention to streaming infrastructure, replay, security, and connection management.

One-way delivery over HTTP

A client opens an HTTP request and receives ongoing server updates through the response. Use separate requests for client commands, or choose WebSockets when persistent bidirectional messaging is required.

Explicit text event framing

SSE uses text/event-stream with UTF-8 fields and blank-line event delimiters. Parse the stream incrementally because HTTP reads and transport chunks do not necessarily align with event boundaries.

Incremental AI response delivery

A backend can translate foundation model stream events into text fragments, metadata, and completion events for a user interface. This reduces the wait before users see useful output, but does not inherently shorten generation time.

Reconnect and optional replay

Browser EventSource normally reconnects after interruption and can send Last-Event-ID when event IDs are supplied. Reliable recovery still requires server-side retention, replay rules, and appropriate client deduplication.

End-to-end streaming support

Application servers, gateways, proxies, and clients must all forward data incrementally. Configure supported streaming integrations, flush output appropriately, and account for idle timeouts and buffering.

Connection lifecycle and security

Long-lived connections require resource limits, heartbeat policies, authorization, and cancellation handling. Native EventSource authentication constraints may make a fetch-based SSE client more suitable for APIs requiring custom headers or POST requests.

Cloud services for Server-Sent Events

Amazon Bedrock supplies incremental model output, while an application running in AWS Lambda or Amazon ECS translates model events into the SSE wire format. A supported API Gateway REST API response-streaming integration can expose a Lambda or HTTP backend; an ECS deployment can instead serve traffic through an Application Load Balancer. These are alternative delivery paths rather than mandatory components of one stack. The browser consumes events through EventSource or a fetch-based streaming parser. Across either path, engineers must verify incremental delivery, authenticate access, configure timeouts, prevent unintended buffering, and stop upstream work when clients disconnect.

Amazon Bedrock

ConverseStream and InvokeModelWithResponseStream expose incremental foundation model output for supported models. An application backend converts the returned SDK event stream into SSE messages; the Bedrock stream is not directly interchangeable with browser EventSource.

Open Amazon Bedrock →
Amazon API Gateway image Amazon API Gateway

Supported REST API proxy integrations can deliver streaming responses when configured for response streaming. This allows an SSE-producing backend to deliver incremental output through an API endpoint; support must be checked for the specific API type and integration rather than inferred from HTTP chunking.

Open Amazon API Gateway →
AWS Lambda image AWS Lambda

Lambda response streaming can incrementally write an SSE-formatted response through supported invocation paths, including streaming-enabled function URLs and supported API Gateway integrations. Configure the content type and streaming handler correctly instead of returning a fully buffered response.

Open AWS Lambda →