Skip to content

Radio

Two-way real-time messaging from DuckDB SQL.

47,305
extension loads · last 90 days
On this page

Technical Overview

Pub/sub channels as queryable tables

The model: buffers in, a delivery queue out

Supported transports

  • WebSocket: A standard RFC 6455 client. ws:// for plaintext or wss:// for TLS; the extension handles ping/pong and reconnect internally. Fits browser-style real-time feeds, event streams, and any custom server-sent API that speaks WebSocket.
  • Redis Pub/Sub: Point a subscription at a Redis URL plus channel name and Radio handles the Redis-specific SUBSCRIBE and PUBLISH under the same SQL surface. Fits application data flows that already use Redis as the bus.
  • Roadmap: Google Pub/Sub, Azure Service Bus, MQTT, and subprocess pipes are listed as planned on the extension's documentation page. Only WebSocket and Redis Pub/Sub exist today.

Production caveats

  • In-memory, process-scoped buffers: Subscriptions, the received-message buffer, and the transmit queue all live in DuckDB process memory. When DuckDB exits, subscriptions tear down and unread messages are lost. For at-least-once delivery across restarts, drain to a durable store before processing — a standalone consumer service can crash-restart from the bus, Radio cannot.
  • Fixed-capacity receive buffer: The inbound buffer is size-limited; older messages are evicted as new ones arrive. Drain at a cadence that keeps up with the inbound rate so you don't lose messages to eviction.
  • Best-effort outbound delivery: Transmit returns once the message is queued, not once it's delivered — the I/O thread updates each message's status asynchronously. Per-subscription transmit_successes / transmit_failures counters and the per-message status table expose progress so you can build retry logic in SQL.
  • Single connection per subscription: Subscription state is not shared across DuckDB connections in the same process. Open a subscription on the same connection that will drain it.
  • Experimental status: Function shapes may change as more transports land. Pin a known-good extension version in production.

Deep Dive

Technical Details

Install

INSTALL radio FROM community;
LOAD radio;

Quick Start

Subscribe to a WebSocket channel — the URL is the subscription key

CALL radio_subscribe('wss://stream.example.com/events');

Drain buffered messages as a normal table

SELECT receive_time, channel, message
FROM radio_subscription_received_messages('wss://stream.example.com/events')
ORDER BY receive_time DESC
LIMIT 50;

Send a message — args are (url, channel, payload, max_attempts, retry_delay)

CALL radio_transmit_message(
  'wss://stream.example.com/events',
  'main',
  '{"type":"hello"}'::BLOB,
  3,
  INTERVAL '500 milliseconds'
);

Reference

Extension Contents

Quick reference to all available functions and settings organized by category.

Name Description
Inbox
radio_received_messages() Table function exposing every received message (across subscriptions) as queryable rows.
radio_subscription_received_message_add() Inject a message into a subscription's received buffer.
radio_subscription_received_messages() Per-subscription view of received messages.
Listening
radio_listen() Open a listener on a channel — buffers incoming messages so subsequent SELECTs can drain them.
radio_subscribe() Subscribe to a remote endpoint (WebSocket / event bus) under a logical subscription name.
radio_subscriptions() Table function listing every active subscription with its endpoint and state.
radio_unsubscribe() Tear down a subscription opened with radio_subscribe.
Maintenance
radio_flush() Drain all currently-buffered messages so subsequent reads see only fresh data.
radio_sleep() Sleep the current connection — convenience for waiting between polling intervals when scripting.
radio_version() Return the loaded Radio extension version.
Outbox
radio_subscription_transmit_message_delete() Remove a queued outgoing message that hasn't yet been transmitted.
radio_subscription_transmit_messages() Table view of pending and sent outgoing messages with delivery status — what's been transmitted, what's queued, what failed.
radio_subscription_transmit_messages_delete_finished() Garbage-collect already-delivered outgoing messages from the transmit log.
radio_transmit_message() Queue an outgoing message on a subscription.

API Reference

Function Documentation

Practical Examples

Cookbook

Real-world recipes and patterns for common use cases.

Platform Support

Compatibility

Extension availability may vary by platform and DuckDB version. Check below to ensure this extension supports your environment before installation.

Quick Facts

Release status Experimental
Software License MIT
Pricing Free
Written In C++
Source Available Yes
View on GitHub
Usage
47,305
loads · last 90 days

Platforms

  • Linux x86_64 aarch64
  • Linux (musl) Not available
  • macOS Intel Apple Silicon
  • Windows Not available
  • WASM Not available
Compiled binary sizes
Platform Architecture Size
Linux x86_64 6.26 MB
Linux aarch64 6.16 MB
macOS Intel 3.60 MB
macOS Apple Silicon 3.73 MB

Compressed download size from the Haybarn extension repository.

DuckDB & Haybarn

Release calendar