Skip to main content

Realtime limits & billing

Realtime runs on shared, multi-tenant infrastructure, so every resource is bounded per organisation. Limits resolve through the entitlement ladder — GREATEST(floor, plan tier, per-org override) — and are cached on the hot path. Self-hosted uses the environment defaults shown below.

Enablement & product limits

EntitlementDefaultWhat it controls
max_ws_connections1Concurrent WebSocket connections per org. This is the WS on/off switch0 disables WS
max_mqtt_connections1Concurrent MQTT connections per org (independent of WS) — 0 disables MQTT
max_ws_history0Per-channel history-rewind depth. 0 = off; paid tiers scale it. Self-hosted: AIRPIPE__WS_HISTORY_MAX

Higher plans raise the connection ladders (e.g. 1 → 5 → 25 → 100 → 250).

Safety floors (abuse protection)

These are protective floors, not pricing levers — every org gets at least the floor, and a higher plan can only raise it. They stop any single org from exhausting a node. Self-hosted sets them via env.

EntitlementDefaultBoundsSelf-hosted env
max_subscriptions_per_conn1000Subscriptions one connection may holdAIRPIPE__RT_MAX_SUBS_PER_CONN
max_presence_per_conn100Presence memberships one connection may holdAIRPIPE__RT_MAX_PRESENCE_PER_CONN
max_retained1000Retained messages an org pins across all channelsAIRPIPE__RT_MAX_RETAINED
max_publish_rate1000Publishes per second per connection (token bucket)AIRPIPE__RT_MAX_PUBLISH_RATE
max_topics100000Distinct topics/channels an org may createAIRPIPE__RT_MAX_TOPICS

Enforcement is fail-loud: over a cap, the offending operation is rejected (ap_error / dropped subscribe) or the retain bit is stripped — never a silent degrade of other tenants. On MQTT, an over-rate publish is still delivered to subscribers (so a QoS1 publisher isn't left hanging) but skips the pipeline + cross-node fan-out.

Billing (managed)

Realtime bills on top of config_run:

  • Connection-time and throughput (bytes) are metered per org while a socket is open.
  • Each message that triggers a pipeline counts as one request (config_run), exactly like an HTTP call. Plain pub/sub delivery between clients is not a pipeline run.
  • A connection is refused when the org is out of balance, and open connections are dropped if the balance is exhausted.

Public interfaces are still fully accounted. An anonymous/public connection is attributed to the owning organisation (WS via the URL, MQTT via the username), so its connection-time, throughput and pipeline runs bill to — and are capped by — that org. Opening a public: true interface means you accept and pay for its public traffic, bounded by the safety floors above.