Real-Time WebSockets Without Redis: Using Cloudflare Durable Objects in Nuxt 4

Nuxfire TeamSeptember 15th, 2026
Real-Time WebSockets Without Redis: Using Cloudflare Durable Objects in Nuxt 4

Building real-time features (such as instant notifications, collaborative cursors or live dashboards) has always been one of the biggest nightmares in serverless architectures.

Traditionally, the recipe for supporting WebSockets required:

  1. A cluster of always-on dedicated Node.js servers.
  2. A Redis cluster with Pub/Sub to sync messages between instances.
  3. A load balancer configured for persistent connections (Sticky Sessions).

The monthly cost of this minimal infrastructure rarely fell below hundreds of dollars. Nuxfire solves this challenge using Cloudflare Durable Objects.


What Are Cloudflare Durable Objects?

Durable Objects provide serverless compute with coordinated state. Each object runs as a single instance on Cloudflare's global network, guaranteeing that all connections to the same "channel" or "room" reach the same memory process.

In addition, each Durable Object has its own embedded SQLite database, allowing message history to be persisted with sub-millisecond latency.

[User A (Browser)] ──WebSockets───────> ┌────────────────────────────────┐
                                        │ Cloudflare Durable Object      │
[User B (Browser)] ──WebSockets───────> │ - Connection state in RAM      │
                                        │ - Embedded SQLite database     │
[Webhook / Backend Worker] ──Fetch────> └────────────────────────────────┘

Robust Security: Handshake with HMAC-Signed Tickets

WebSocket connections do not carry normal HTTP headers after the initial handshake. To guarantee maximum security against forged connections, Nuxfire uses cryptographically signed tickets:

  1. The client makes an authenticated HTTP request asking for a connection ticket.
  2. The server generates an HMAC-signed token using the application's secret key, valid for 60 seconds.
  3. The client opens the WebSocket connection passing the ticket in the query string.
  4. The Durable Object validates the signature before accepting the handshake.
// Generating the signed ticket in the authentication endpoint
export function generateWebSocketTicket(userId: string, workspaceId: string) {
  const expiresAt = Date.now() + 60 * 1000;
  const payload = `${userId}:${workspaceId}:${expiresAt}`;
  const signature = createHmac("sha256", env.WS_SECRET).update(payload).digest("hex");
  return `${payload}:${signature}`;
}

Consuming It in the Frontend with Nuxt Composables

On the Nuxt 4 client side, connecting to the team channel is as simple as using a native composable:

<script setup lang="ts">
const { messages, status, send } = useTeamWebSockets();

function handleNotify() {
  send({ type: "TEAM_PING", content: "New task created on the board!" });
}
</script>

<template>
  <div>
    <UBadge :color="status === 'OPEN' ? 'success' : 'neutral'">
      {{ status === 'OPEN' ? 'Real Time Active' : 'Reconnecting...' }}
    </UBadge>
    <div v-for="msg in messages" :key="msg.id">
      {{ msg.content }}
    </div>
  </div>
</template>

Conclusion: Enterprise-Grade Real Time Within Your Reach

With Durable Objects, you completely eliminate the costs of Redis and Socket.io servers, taking advantage of Cloudflare's global network to deliver an ultra-fast experience to your users.

This whole flow — from the backend workers to Nuxt's reactive composables — already comes 100% implemented and tested in Nuxfire.

Get your lifetime license and download the code right now →