Beta
Realtime is in beta. Share your feedback on Discord or via the Neon Console.
Realtime makes any SQL query live. Subscribe in realtime to your Lakebase Postgres database. Develop with end-to-end, type-safe reactivity using live queries and optimistic mutations.
Get started
Get started with Realtime and learn about how it works.
npx neon@latest bootstrap my-app --template realtime-reactSee examples of how to build full-stack, reactive apps with Next.js and TanStack and how to keep users and agents in sync with Mastra.
Realtime live SQL
Realtime offers arbitrary live SQL with full reactivity on Lakebase Postgres. It allows you to build realtime, reactive apps and agents:
- without using a second or bespoke realtime system
- without changing your schema, queries, ORM or reactivity system
- without contorting your application around the limitations of your sync engine
There is no need to use a different database for realtime sync. You can reuse your existing query code and data loading patterns. This is full reactivity, on standard Postgres, with live SQL that just works.
Integrated reactive DX
Define and subscribe to queries directly. Or use the batteries included: end-to-end, type-safe reactivity and mutation primitives that integrate into your framework of choice.
In your backend, define live queries using raw SQL or your ORM of choice (in this case Drizzle):
your-api-server.tsimport { createRealtime } from "@neon/realtime/server" import { drizzleAdapter } from "@neon/realtime-drizzle" const realtime = createRealtime({ secret: process.env.NEON_REALTIME_SECRET!, db: "neondb", adapter: drizzleAdapter() }) // This can be any SQL query, including joins, aggregates, ordering, etc. const query = db.select().from(messages)Seal the live queries to safely expose them to your frontend:
your-api-server.tsconst sealedQuery = await realtime.seal({ query })Subscribe directly using a low‑level client:
client-or-server.tsimport { createRealtimeClient } from "@neon/realtime/client" const client = createRealtimeClient({ url: process.env.NEON_REALTIME_URL! }) const subscription = client.subscribe(sealedQuery) subscription.onChange(console.log)Or, in your app, use the higher-level reactivity primitives to bind live queries to your component state:
App.tsximport { useLiveQuery } from "@neon/realtime-react" import { type SealedLiveQuery } from "@neon/realtime/client" type Props = { sealedQuery: SealedLiveQuery<Message> initialData?: Message[] } export function Messages({ sealedQuery, initialData }: Props) { const { data } = useLiveQuery(sealedQuery, { initialData }) return ( <ul> {(data ?? []).map((message) => ( <li key={message.id}>{ ... }</li> ))} </ul> ) }Optionally passing in the
initialDatafrom SSR (e.g.: with TanStack Start):routes/messages.tsximport { createFileRoute } from "@tanstack/react-router" import { createServerFn } from "@tanstack/react-start" const loadMessages = createServerFn({ method: "GET" }).handler(async () => { const [initialData, sealedQuery] = await Promise.all([query, realtime.seal({ query })]) return { initialData, sealedQuery } }) export const Route = createFileRoute("/messages")({ loader: () => loadMessages(), component: () => <Messages {...Route.useLoaderData()} />, })Or for more advanced use, sync the live query into a TanStack DB collection:
db/collections.tsimport { createCollection } from "@tanstack/db" import { realtimeCollectionOptions } from "@neon/realtime-tanstack" export const messagesCollection = createCollection( realtimeCollectionOptions({ id: "messages", client, query: sealedQuery, ..., onUpdate: async ({ transaction, collection }) => { const updates = transaction.mutations.map(({ original, changes }) => ({ id: original.id, changes })) const { txid } = await api.messages.update(updates) await collection.utils.awaitTxId(txid) } }) )Bind that to your components and benefit from instant local writes using optimistic mutations:
App.tsximport { useLiveQuery } from "@tanstack/react-db" export function Messages() { const { data } = useLiveQuery({ query: (q) => q.from({ messagesCollection }) }) function star(message) { messagesCollection.update(message.id, (draft) => { draft.starred = true }) } return ( <ul> {(data ?? []).map((message) => ( <li key={message.id} onClick={() => star(message)}>{ ... }</li> ))} </ul> ) }That's it. You get live SQL and end-to-end reactivity on standard Postgres. With full type-safety and support for SSR, instant local writes, multi-user, multi-device sync and local offline persistence.
Agent skills and MCP
Install the Neon MCP server. Or use the CLI to install the Realtime skill:
neon skills -s neon-realtimeFrequently asked questions
Answers to frequently asked questions about Realtime:
What's in the beta and what's not?
Functionally, Realtime already supports:
- arbitrary live SQL (any read-only, deterministic
SELECT) - end-to-end, type-safe reactivity
- SSR and Managed Better Auth support
- initial ORM, query builder and framework integrations
- support for branching and scale-to-zero
Realtime does not yet support:
- billing (Realtime is free to use during the beta)
- RLS (we aim to support it by GA, if priorities allow)
- Lakebase Postgres on Databricks (Realtime is available only on Neon for now)
The transport protocol is not yet stable and we aim to add wider client and framework integrations for GA.
The beta also makes no performance guarantees. We have very ambitious performance goals but there's lots of optimization work still to do.
How much does it cost? Is billing enabled?
Realtime is free to use during the beta. Neon does not charge for the live query engine compute or the Live SQL API service.
Using Realtime can still cause usage on your database:
- database compute: starting a live query may wake the database compute endpoint, which is billed according to your plan
- data transfer: outbound data transfer is measured as egress and is subject to your plan's data-transfer allowance and applicable overage charges
The beta waiver applies to the Realtime service itself. It does not waive database compute or network-transfer charges generated by your workload.
What's the performance impact on my database?
Realtime switches the cost of queries from "query-execution on read" to "incremental cost on write". However that cost is incurred on a replica, which means Realtime has zero impact on the write-latency, write-throughput or write-compute of your primary database.
Realtime does require logical replication to be enabled. Technically, this adds a small metadata overhead to the Postgres WAL. For more information, see Table requirements.
Can I use my ORM / query-builder?
Yes. Realtime works with SQL, so any library that generates SQL can work with it. There are built-in adapters for Drizzle and Kysely, and you can write your own for other libraries.
See Using a query builder or ORM for how to set one up, and the RealtimeAdapter reference for the interface.
What SQL features are supported? Are there limitations?
Realtime supports any read-only, deterministic SQL query that Postgres supports, including joins, aggregates, window functions and sub-queries.
Queries can't have side effects, and any functions they use must be deterministic, so you can't use now() or gen_random_uuid(). Complex queries add write-processing latency, especially on larger datasets.
See Defining live queries for the details.
Is Realtime enabled by default?
No. You enable it per project and branch. Child branches created from a Realtime-enabled branch have it enabled automatically.
Enable it on a branch with neon realtime enable. Or, if you manage your project with neon.ts, declare it with neon config add realtime and apply it with neon deploy. You can also enable it in the Neon Console. See the Quickstart for more details.
Realtime isn't available on Claimable projects until they're claimed.
Which regions is it enabled in?
During the beta, Realtime is available in:
aws-ap-southeast-1
aws-eu-central-1
aws-us-east-1
aws-us-east-2See product availability for every region.
Does Realtime support RLS?
Not yet. Realtime has been architected to support RLS and we aim to add it by GA if priorities allow. However, it's not yet been implemented and isn't the recommended approach to auth.
See Why not row-level security for more details.
Does Realtime support branching?
Yes, Realtime supports branching. Realtime is enabled at the branch level.
Branches support live queries and Realtime-enabled branches can be branched. Child branches of a Realtime-enabled branch automatically have Realtime enabled.
Does Realtime support scale-to-zero?
Yes, using Realtime does not prevent your database from scaling to zero. Initiating live queries will wake your database. Holding subscriptions open does not.
Do live queries use up database connections?
No. Realtime query connections from clients are terminated at the Live SQL API, which then speaks to the live query engine over a single TCP connection.
Is there a risk of write-lag / WAL build-up?
No. There's no impact on write-throughput and no risk of WAL build-up.
What about thundering herds?
Realtime has built-in protection from thundering herds in the client and the Live SQL API. There's no risk of a large spike of client-reconnections taking your database down.
How does Neon Realtime compare with alternatives?
We don't speak for other systems. However, we have tried to articulate the key differences with some alternative realtime systems below.
Supabase
Supabase Realtime is a pubsub system with replay. It pushes messages and database changes to connected clients. Subscriptions can filter on column values but can't join, aggregate, order, limit or run arbitrary queries.
Neon Realtime is a sync engine that supports arbitrary live SQL queries, including joins, aggregates, ordering and limits. The system keeps live query results consistently in sync with the database and provides type-safe primitives for end-to-end reactivity and instant local writes.
Convex
Compared with Convex, Neon Realtime supports similar end-to-end reactivity but on standard Postgres and with standard web frameworks and build tooling. Realtime also uses delta-sync rather than query-invalidation, which is more efficient over the wire.
Materialize
Compared with Materialize, Neon Realtime is a similarly expressive incremental view engine with live SQL support. However, Realtime is designed and optimized for serving live data to apps and agents, with efficient data matching and support for large numbers of concurrent clients.
Zero
Zero is an open-source sync engine with expressive sync and reactivity using a custom query language. Zero also provides advanced client-side data management. Realtime is built into Lakebase Postgres and the Neon platform and provides similar sync and reactivity on standard SQL. Both systems are composable with your existing schema and auth.
Is Realtime compatible with, or based on, Electric?
Realtime isn't based on Electric, but it is a drop-in replacement for Electric's role in your stack. We recommend that teams using Electric migrate to Realtime.
Live SQL queries replace shapes. For TanStack DB users, realtimeCollectionOptions() replaces electricCollectionOptions().
Next steps
Get started with Realtime and learn more about how it works.
Need help?
Join our Discord Server to ask questions or see what others are doing with Neon. For paid plan support options, see Support.









