QUESTPIE
Concepts

Realtime

Understand live queries, channels, the durable outbox, cross-instance delivery, presence, and the consistency model behind QUESTPIE realtime applications.

Realtime keeps connected clients synchronized after committed application changes. QUESTPIE separates the application contract from delivery, so the same live-query and channel APIs work across local SSE and managed transports.

Two realtime primitives

Use the primitive that matches the data:

PrimitiveCarriesBest for
Live queryA fresh collection or global snapshotLists, detail views, counters, dashboards
ChannelA typed application eventProgress, typing, notifications, presence

Live queries re-run a normal read after invalidation. Channels deliver schema-validated events and keep transient state separate from persisted records.

Change flow

A collection or global write follows this live-query path:

  1. QUESTPIE writes the data change and its realtime outbox row in one transaction.
  2. The transaction commits both records together.
  3. The broker wakes every application instance that serves subscribers.
  4. Each instance refreshes affected live queries under each subscriber's access rules.
  5. The client updates the matching subscription.

The durable outbox closes the gap between database commit and delivery. Broker messages act as wake-ups; application rows remain in the database.

Live queries

The client subscribes with the same query shape used for a normal read:

const unsubscribe = client.collections.posts.live(
	{ where: { status: "published" }, orderBy: { createdAt: "desc" } },
	(snapshot) => render(snapshot.docs),
);

The first callback receives the current snapshot. Later invalidations refresh only subscriptions affected by the changed collection, global, locale, stage, and query scope.

See Client realtime for live(), liveIter(), lifecycle options, and TanStack Query integration.

Channels

Channels define typed event streams in channels/. Codegen adds publish and subscribe methods to server context and the generated client.

channels/progress.ts
import { channel } from "questpie/channels";
import { z } from "zod";

export default channel("progress-[jobId]").events({
	updated: z.object({ percent: z.number().min(0).max(100) }),
});

Publishing a channel event validates it, authorizes the caller, and appends it to the bounded delivery ledger before transport fan-out. Use persisted collections for history that users must retrieve later. Use channels for transient events.

See Channels for authorization, publishing, subscriptions, presence, and replay behavior.

Connections and scaling

Clients multiplex subscriptions over a shared connection. A broker distributes invalidations across app instances; a transport carries updates to browsers.

Single-instance development can use the built-in path. Multi-instance deployments choose a shared broker or managed transport that matches their topology.

Consistency and delivery

Realtime is a synchronization layer over committed state. Clients reconnect, resume from the supported cursor, and reconcile from the database when delivery is interrupted.

Design handlers to tolerate duplicate wake-ups. Persist business facts before publishing events, and derive durable UI state from collections or globals.

Choose a transport

The realtime configuration selects polling, Postgres notifications, Redis Streams, Pusher/Soketi, or Cloudflare delivery without changing application subscriptions.

See Realtime adapters for topology, admission, outbox settings, transport configuration, and custom contracts.

On this page