Semantics & guarantees
This page describes what Relay commits to today for the core publish and subscribe path. It is aligned with enforcement in app/Services/PlanEnforcementService.php and the Go relay under packages/relay-server/.
Delivery model (default realtime path)
- At-most-once over the wire: after a successful HTTP response from the trigger event API, the relay attempts to deliver to current subscribers. There is no durable end-to-end acknowledgement from every browser back to your server for each message.
- Reconnects: clients should use the Pusher-compatible client lifecycle (disconnect/reconnect). Missed messages while offline are not replayed automatically unless you use history / rewind features (bounded; see relay channel history) or your own Event Replay / Event Store flows in the dashboard.
- Ordering: delivery is best-effort FIFO per channel on a single relay process. Under load, across multiple relay instances, or during reconnects, do not rely on strict global ordering without your own sequencing in the payload or a dedicated ordered stream design.
Plan limits (examples)
Limits vary by plan; the dashboard and API enforce them at publish time.
| Concern | Enforcement |
|---|---|
| Payload size | Rejected with 413 when over plan max (see PlanEnforcementService::checkPayloadSize). |
| Daily message volume | 429 when over messages_per_day for the org plan. |
| Channel cardinality | 429 when new channels would exceed the plan’s channel limit (rolling logic uses today’s event_logs). |
| API rate | Token / app throttles (see ThrottleByAppToken and plan config). |
Default free-tier payload cap is on the order of 10 KB unless overridden in config/relay-cloud.php.
Idempotency
If you send idempotency_key and the app has deduplication enabled, repeated publishes with the same key within the dedup window return success without double-delivering (see EventController).
Observability
Each successful trigger records a server trace id and optional correlation id (see REST API docs). Use headers X-Relay-Trace-Id and X-Relay-Correlation-Id and the in-app Event trace screen to connect publishes to spans and logs.
Not guaranteed by default
- Exactly-once delivery to every subscriber.
- Unbounded retention of messages in the hot path (history is bounded; long-term retention is plan- and feature-specific).
- Cross-region active/active unless you operate that topology yourself.
For product direction and what we ship next, see Roadmap.