---
id: "realtime-gateway"
type: "kind"
category: "edge"
url: "https://localhost:3000/catalogue/kinds/realtime-gateway"
---

# Real-time gateway

Holds long-lived client connections and pushes events.

| | |
|---|---|
| Category | Edge |
| Properties | 11 |
| Components | 20 |
| Rules | 3 |

## Properties

| property | type | values | required | default |
|---|---|---|---|---|
| `ackIntervalSeconds` (advanced) | integer | — | no | — |
| `autoscaling` | boolean | — | no | false |
| `channelAssignment` (advanced) | enum | `random`, `hash`, `sticky` | no | "random" |
| `drainOnScaleIn` (advanced) | boolean | — | no | false |
| `managed` | boolean | — | no | false |
| `protocol` | enum | `websocket`, `sse`, `long-poll`, `grpc-stream`, `udp-multicast` | no | "websocket" |
| `pushFallback` (advanced) | boolean | — | no | false |
| `sequenceNumbers` (advanced) | boolean | — | no | false |
| `stampedeGuard` (advanced) | boolean | — | no | false |
| `stateful` | boolean | — | no | true |
| `subscriptionsPerUser` (advanced) | integer | — | no | — |

## Rules for this kind · 3

### Reconnect stampede without guard `reconnect-stampede-without-guard` (error)

- Page: https://localhost:3000/catalogue/rules/reconnect-stampede-without-guard.md
- Why: When a gateway holding millions of sockets restarts, every client reconnects at once and the gateway asks the coordination service about each of them. Without a stampede guard that lookup storm takes the coordination service down too.
- Applies to: every node of kind realtime-gateway
- Message: Realtime gateway '{{node.id}}' calls a coordination service synchronously on connect but has no reconnect stampede guard.

It fires when:

- all of these hold:
  - the node has at least one synchronous outgoing edge to a coordination-service
  - the node's `stampedeGuard` is false

### Random channel placement under heavy-tail traffic `shared-host-per-channel-without-isolation` (error)

- Page: https://localhost:3000/catalogue/rules/shared-host-per-channel-without-isolation.md
- Why: With heavy-tail traffic a few channels carry most of the load. Assigning channels at random lands those hot channels on arbitrary hosts, and every tenant sharing a host suffers for it.
- Applies to: every node of kind realtime-gateway
- Message: Realtime gateway '{{node.id}}' assigns channels randomly while the design declares heavy-tail traffic. Hot channels will degrade unrelated tenants on the same host.

It fires when:

- all of these hold:
  - the node's `channelAssignment` is "random"
  - the design requirement `traffic.skew` is "heavy-tail"

### Stateful WebSocket scale-in without drain `stateful-websocket-scale-in-without-drain` (warning)

- Page: https://localhost:3000/catalogue/rules/stateful-websocket-scale-in-without-drain.md
- Why: Scaling a gateway down kills every live WebSocket on the removed instance at once. Without a drain step those clients all reconnect together.
- Applies to: every node of kind realtime-gateway
- Message: Realtime gateway '{{node.id}}' autoscales but does not drain connections on scale-in. Every scale-down becomes a reconnect storm.

It fires when:

- all of these hold:
  - the node's `autoscaling` is true
  - the node's `drainOnScaleIn` is false

## Components · 20

### vendor-neutral

- [Generic real-time gateway](https://localhost:3000/catalogue/components/realtime-gateway.md) `realtime-gateway` — the kind itself

### aws

- [API Gateway WebSocket API](https://localhost:3000/catalogue/components/aws-api-gateway-websocket.md) `aws-api-gateway-websocket` — 5 defaults
- [AWS AppSync Events API](https://localhost:3000/catalogue/components/aws-appsync-events.md) `aws-appsync-events` — 5 defaults
- [Amazon IVS Chat](https://localhost:3000/catalogue/components/aws-ivs-chat.md) `aws-ivs-chat` — 4 defaults

### azure

- [Azure Fluid Relay](https://localhost:3000/catalogue/components/azure-fluid-relay.md) `azure-fluid-relay` — 4 defaults
- [Azure SignalR Service](https://localhost:3000/catalogue/components/azure-signalr.md) `azure-signalr` — 5 defaults
- [Azure Web PubSub](https://localhost:3000/catalogue/components/azure-web-pubsub.md) `azure-web-pubsub` — 5 defaults

### default

- [Ably](https://localhost:3000/catalogue/components/ably.md) `ably` — 6 defaults
- [Centrifugo](https://localhost:3000/catalogue/components/centrifugo.md) `centrifugo` — 4 defaults
- [Liveblocks](https://localhost:3000/catalogue/components/liveblocks.md) `liveblocks` — 4 defaults
- [Mercure](https://localhost:3000/catalogue/components/mercure.md) `mercure` — 4 defaults
- [Multicast market-data feed](https://localhost:3000/catalogue/components/multicast-feed.md) `multicast-feed` — 3 defaults
- [PartyKit](https://localhost:3000/catalogue/components/partykit.md) `partykit` — 5 defaults
- [Phoenix Channels](https://localhost:3000/catalogue/components/phoenix-channels.md) `phoenix-channels` — 2 defaults
- [Pusher Channels](https://localhost:3000/catalogue/components/pusher.md) `pusher` — 5 defaults
- [Pushpin](https://localhost:3000/catalogue/components/pushpin.md) `pushpin` — 4 defaults
- [ASP.NET Core SignalR](https://localhost:3000/catalogue/components/signalr.md) `signalr` — 5 defaults
- [Socket.IO server](https://localhost:3000/catalogue/components/socket-io-server.md) `socket-io-server` — 2 defaults
- [Soketi](https://localhost:3000/catalogue/components/soketi.md) `soketi` — 4 defaults
- [WebSocket gateway](https://localhost:3000/catalogue/components/websocket-gateway.md) `websocket-gateway` — 2 defaults

## Source (`kind` YAML, verbatim)

```yaml
# yaml-language-server: $schema=../schema/kind.schema.json
# Holds long-lived client connections and pushes events (WebSocket gateways, chat servers, long-poll and multicast feeds).
# stampedeGuard and drainOnScaleIn default false so reconnect and scale-in rules can fire.
schemaVersion: "1"
type: "kind"
id: "realtime-gateway"
category: "edge"
properties:
  protocol:
    type: "enum"
    values: ["websocket", "sse", "long-poll", "grpc-stream", "udp-multicast"]
    default: "websocket"
  stateful:
    type: "boolean"
    default: true
  autoscaling:
    type: "boolean"
    default: false
  channelAssignment:
    type: "enum"
    values: ["random", "hash", "sticky"]
    default: "random"
    advanced: true
  drainOnScaleIn:
    type: "boolean"
    default: false
    advanced: true
  stampedeGuard:
    type: "boolean"
    default: false
    advanced: true
  sequenceNumbers:
    type: "boolean"
    default: false
    advanced: true
  ackIntervalSeconds:
    type: "integer"
    advanced: true
  subscriptionsPerUser:
    type: "integer"
    advanced: true
  pushFallback:
    type: "boolean"
    default: false
    advanced: true
  managed:
    type: "boolean"
    default: false
```

Human page: https://localhost:3000/catalogue/kinds/realtime-gateway
