AI Agent Chat: Choosing Between WebSockets and Server-Sent Events

Discover how to power your AI agent chat by choosing the right real-time communication protocol. In this article, we dive into the pros and cons of WebSockets and Server-Sent Events

AI Agent Chat: Choosing Between WebSockets and Server-Sent Events
Photo by Diana Parkhouse / Unsplash


TL;DR 🚀

  • AI Agent Progress – Continuing with LangChain (TypeScript) + NestJS for automation.
  • Streaming Challenge – Needed a way to stream responses efficiently.
  • WebSockets vs. SSE – WebSockets are low-latency but resource-intensive; SSE is simpler, scalable, and secure.
  • Chose SSE – Works well with NestJS and natively supported, easier to implement, auto-reconnects, and scales with HTTP.
  • Limitations? – SSE is one-way only (server → client) but not a problem for this use case.
  • What’s next? – Retrieval-Augmented Generation (RAG), Observability & Further AI-driven automation for Marketing. 🚀

Introduction

As firstly I mentioned my one of previous articles I mentioned that I started working on an AI Agent.

How AI is Transforming SEO and Content Marketing
AI is reshaping digital marketing by automating content creation, optimizing keywords, and improving search rankings. This article explores how businesses—especially smaller ones—leverage AI to compete more effectively, streamline SEO, and enhance marketing ROI.

In this article I want to follow up on progress. Expand on that tech stack has been chosen.

Tech Stack

I've decided to build the agent's intelligence on LangChain and with NestJS

gray TV remote
Photo by Immo Wegmann / Unsplash

What is LangChain?

  • LangChain is a framework for building applications powered by large language models (LLMs).
  • It simplifies tasks like prompt chaining, memory management, data integration, and workflow orchestration.
  • Ideal for building AI agents, chatbots, and retrieval-augmented generation (RAG) applications.
  • Has a TypeScript implementation. Which I am big fan of.
  • Also it makes easy to integrate with NestJS and leverage its DI container to inject services, instead of leveraging micro services. If you'd like to learn more about when to or not to use it you can read more: The Real Benefits of Micro Services in NestJS (And When They Aren't Worth It)

By leveraging LangChain on Typescript I've implemented the ai agent chat functionality.

One of the main challenges and considerations was Chat UX. ChatGPT has already set a bar high with chat experience, but leveraging streaming. One might assume that streaming is achieved through WebSockets. WebSockets has many benefits and quite a few drawbacks.

programming language illustration
Photo by Christopher Robin Ebbinghaus / Unsplash

✅ WebSockets: Pros

  • Low latency. This makes them ideal for quick back and forth message sending.
  • Supports simultaneous sending and receiving, unlike traditional HTTP requests.
  • Persistent Connection – Reduces overhead by maintaining a single connection instead of opening new ones for each message.

However,

❌ WebSockets: Cons

  • High Resource Consumption – Maintaining persistent connections increases memory and CPU usage. Unlike stateless HTTP requests, WebSockets require dedicated server resources for each connection, making large-scale deployments more challenging. (Ensuring there will be enough servers to handle connections and managing budget).
  • Security Considerations – WebSockets do not include built-in authentication or authorization mechanisms. Common approaches, like sending JWT tokens with each message, require additional validation logic, and none are as straightforward as traditional API authentication.

👉 Key Takeaway: While WebSockets offer low-latency, full-duplex communication, their resource demands and security concerns make them less suited for real-time applications.

🧐 What are the options ?

  • Server-Sent Events (SSE) – Simpler than WebSockets, ideal for one-way streaming.
  • Polling/Long Polling – Works with older architectures but adds latency and wastes resources.

I went with Server-Sent Events (SSE). NestJs already supports it out of the box. One thing is to make sure to return the RxJS observable from the controller method and decorate method with @Sse decorator. Let's go quickly over SSE Pros & Cons.

✅ Server-Sent Event: Pros

  • Simplicity – Uses standard HTTP connections, making it easier to implement compared to WebSockets. Especially with NestJS.
  • Lightweight & Efficient – SSE operates over a single HTTP connection.
  • Automatic Reconnection – Built-in support for auto-reconnect, meaning clients can automatically re-establish the connection if interrupted. Handled by the browser.
  • Secure by Default – SSE leverages existing HTTP/HTTPS security mechanisms. No need for extra implementation for authentication and authorization.
  • Scalability-Friendly – Easier to scale with HTTP load balancers, since it uses standard HTTP connections rather than a stateful protocol like WebSockets.

Before I close off I would like to mention that there are some cons to the Server-Sent events, though in my use case they are irrelevant.

❌ Server-Sent Event: Cons

  • One-Way Streaming – Ideal for applications that require server-to-client updates. To update backend you must to send another POST/PUT request to backend to make an update to your state to alter SSE and if required trigger reconnection.
  • While SSE scales better than WebSockets in some contexts, it still faces limitations with very high-frequency updates or large numbers of clients, particularly in cloud environments where maintaining long-lived HTTP connections can be costly and hit limits, but generally this is a good problem to have. It means that your project amounted to something 🤭

So to conclude, when it came to streaming responses, I initially evaluated WebSockets but ultimately opted for Server-Sent Events (SSE) due to its simplicity, built-in security, and scalability. While SSE has some limitations, such as one-way streaming, these were not critical for my use case.