Skip to main content

pubsub

DEPRECATED (will be removed in an upcoming release; migration guide https://github.com/iii-hq/iii/blob/6901a589dd39d9c34f9d5b6bd8bc82170ee21548/docs/next/upgrading/migrate-from-streams.mdx). Fire-and-forget topic pub/sub: broadcast an event with `publish` and every observer of `publish` filtered on that topic receives it. Use for real-time notifications where missed events are acceptable.

Source facts

Repository
iii-hq/workers
Last source activity
November 9, 2026 at 22:38
Detected SKILL.md language
English
Stars
114
Forks
30

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
pubsub
tags
pubsub, publish, observe, events, redis
description
DEPRECATED (will be removed in an upcoming release; migration guide https://github.com/iii-hq/iii/blob/6901a589dd39d9c34f9d5b6bd8bc82170ee21548/docs/next/upgrading/migrate-from-streams.mdx). Fire-and-forget topic pub/sub: broadcast an event with `publish` and every observer of `publish` filtered on that topic receives it. Use for real-time notifications where missed events are acceptable.
# pubsub > **Deprecated:** pubsub is deprecated (pubsub) and will be removed in an upcoming release. Behavior is unchanged for now. Migration guide: https://github.com/iii-hq/iii/blob/6901a589dd39d9c34f9d5b6bd8bc82170ee21548/docs/next/upgrading/migrate-from-streams.mdx > > Applies to `publish` and the `pubsub` configuration entry. Do not start new work on it: observe a worker-owned event function for fire-and-forget fan-out, or use the `queue` worker (`iii::durable::publish` observed through `queue::on-message`) when every event must be processed. The worker logs rate-limited deprecation warnings (target `iii::deprecation`); topic `stream.events`, used by the engine's iii-stream bridge, is exempt. The `pubsub` worker is topic-based publish/subscribe messaging. Publish an event to a named topic with the `publish` function, and every observer of `publish` whose filter selects that topic receives `{ topic, data }` — no persistence, no retries. It is fire-and-forget broadcast: observers receive each event as it arrives, and a target that is offline simply misses it. Install it with `iii call compose::add worker=pubsub`. It replaces the former in-engine pub/sub service: the function id (`publish`) is unchanged, so existing publishers keep working — only the owner moved from an in-process builtin to this standalone worker. The worker exposes one function, `publish`, registered with the bare function id `"publish"` (no namespace prefix). Any worker may call it, and subscribers observe it. Two adapters: `local` (default; events stay on this engine; no external dependency) and `redis` (`redis_url: ${REDIS_URL:redis://localhost:6379}`; uses Redis Pub/Sub so events also reach the observers on other engines). The adapter is set in the `pubsub` configuration entry and hot-swaps at runtime. ## When to Use - Real-time notifications consumers may miss without consequence — UI live updates, ephemeral signals, telemetry mirroring. - Loose coupling where an event source should not know about its consumers. - Cross-engine fan-out of ephemeral events (configure the `redis` adapter). ## Boundaries - No persistence, ordering, or retries — a target that is down misses events permanently. Use the `queue` worker (`queue::on-message`) when every consumer must process every event. - Topics are plain strings; select them with filter operators (`$eq`, `$in`, …) on `input.topic`. There are no hierarchical topic patterns. - An empty topic is rejected: `publish` returns `topic_not_set` and the call reaches no observer. - For key/value or stream change reactivity, observe `state::on-changed` or the `stream::on-*` functions instead — `pubsub` carries discrete events, not state. ## Functions - `publish` — broadcast `{ topic, data }`; every observer of `publish` whose filters match the call receives it. Empty topic returns `topic_not_set`. Returns `null`. ## Observing a topic Observe `publish` when a function should run every time something publishes to a topic. It takes no args: select the topic with a filter on `input.topic`, and use `capture: ['input']` so the target receives `{ topic, data }` at `payload.input`. Several observers of the same topic each get an independent copy (true fan-out). Reach for it when: - A domain event from one part of the system should kick off side effects elsewhere without the publisher knowing the consumers. - You want cross-engine fan-out via the `redis` adapter. If targets must reliably process every event with retries and dead-letter handling, observe the `queue` worker's `queue::on-message` instead — `publish` is fire-and-forget. ### How to observe 1. Register a handler: `iii.registerFunction('notifications::on-order-shipped', handler)`. 2. Observe `publish` with it: ```typescript iii.observe( { function_id: 'publish', filters: { 'input.topic': { $eq: 'orders.shipped' } }, // exact topic; $in for several capture: ['input'], }, 'notifications::on-order-shipped', ) ``` The handler receives the `Observed` envelope with `{ topic, data }` at `input`, so one handler can serve several topics. Its return value is ignored and there is no retry. Pass `{ metadata }` as the third argument of `iii.observe` to hand the handler a sidecar with every event. For the published payload shape, call `iii get function info` on `publish` or the handler function id.
View on GitHub