Realtime
Channels, tickets, presence and live logs.
View as MarkdownCreate a channel
A channel belongs to exactly one project. A channel with the same name in another project is a different channel.
veltic realtime channels create PROJECT_ID orders "Order status"Test in two terminals
Start the listener first, then publish from a second terminal.
veltic realtime listen PROJECT_ID orders
veltic realtime publish PROJECT_ID orders created '{"id":1}'Connect a browser client
Request a short-lived ticket from the dashboard and connect directly to the realtime endpoint with it. The dashboard cannot terminate the WebSocket itself, because serverless functions cannot hold a persistent connection. Grant only the publish or subscribe permissions the client needs.
const ticket = await fetch('/api/realtime/ticket', {
method: 'POST',
body: JSON.stringify({ channels: ['orders'], mode: 'subscribe' })
}).then(response => response.json());
const socket = new WebSocket(`${ticket.endpoint}?ticket=${ticket.token}`);Live logs
logs:app:<name> and logs:function:<name> are a reserved namespace. Nobody creates them: the ticket grants them through a prefix after checking app.read or function.read and that the resource exists, and it grants subscribe only, so no client can forge a log line. Payloads are raw excerpts batched every 250 milliseconds; anything over 32 KB is dropped and flagged as truncated.
Realtime is not an archive
Messages reach whoever is connected at the time. Store anything that matters in PostgreSQL and resynchronize state after a reconnect.