DATE:
AUTHOR:
PowerSync Product Team
PowerSync Service

Sync Streams are now Generally Available

DATE:
AUTHOR: PowerSync Product Team

We are excited to announce that Sync Streams have advanced from beta to GA - APIs are stable, and they've proven themselves in production.

They are a core component of the PowerSync architecture, controlling what data syncs to each client (they achieve partial sync). Each stream is a SQL query you define on the server; clients subscribe to the streams they need, when they need them.

Our original Sync Rules system synced all relevant data to clients upfront on connect. That works well for offline-first apps, but creates friction for web apps and view-driven UIs where you only want data for the current view.

Sync Streams address this: clients subscribe to streams on demand, with their own parameters, independently per view or tab. Built-in TTL keeps data cached after unsubscribing, so returning to a view loads instantly. For offline-first apps, set auto_subscribe: true and streams sync on connect instead, giving you the same behavior as Sync Rules.

If your project uses Sync Rules, they remain fully supported but are now considered legacy. Sync Rules will be deprecated eventually. We will communicate an LTS plan well in advance.

Key improvements over Sync Rules

Sync Streams cover the same use cases as Sync Rules, including offline-first apps, and add:

  • On-demand syncing: Define streams once on the server, then subscribe from your app with different parameters as needed. Each subscription is independent — no more managing arrays of IDs to control what's synced. Set auto_subscribe: true to sync on connect instead, keeping the same behavior as Sync Rules.

  • Multi-tab support: Each subscription manages its own lifecycle. Open the same list in two tabs and each subscribes independently; close one and the other keeps working.

  • Per-subscription TTL: Each subscription has a configurable TTL that keeps data cached after unsubscribing. When users return to a view, data is often already there and the view loads instantly.

  • Simpler, more powerful syntax: Stream queries support JOINs, CTEs, subqueries, and multiple queries per stream. No separate parameter queries — the syntax is closer to plain SQL.

  • Framework integrations: React, Vue/Nuxt, and Kotlin Compose bindings let UI components manage subscriptions automatically based on what's rendered. TanStack React Query is also supported via useQuery/ useQueries.

What's new since beta

Since the beta shipped in March 2026, many of you have been building with Sync Streams in production, reporting bugs and suggesting improvements. We shipped compiler bug fixes, syntax features, better error messages and diagnostics, and operational fixes. Most of these came from your feedback - thank you!

Upgrade to the latest PowerSync Service and SDK versions to pick up all these improvements. PowerSync Cloud instances are updated automatically. The public APIs and syntax have no breaking changes since beta, so your existing definitions will keep working.

Added

  • Global CTEs reusable across all streams (#567). If you have a subquery that multiple streams share, define it once as a global CTE instead of duplicating it in every stream.

  • instr SQLite function in stream queries (#564). Enables substring-based filtering patterns that weren't possible before.

  • Schema generators emit type-safe wrappers for stream subscriptions (#538). Instead of calling db.syncStream('my_stream', { param: value }) with untyped strings, generated client code now includes typed methods that match your stream definitions.

  • Explicit limit and clear error when a stream compiles to more than 100 equivalent bucket_definitions (#579). Catches over-broad stream definitions early, before they cause performance issues in production.

  • Configurable limit on parameter query results, with offending stream definitions identified in the error (#621, #630). When a stream generates too many parameter combinations, the error now tells you which stream definition is responsible.

Improved

  • Compiler diagnostics now include source offsets pointing to the exact location in your YAML (#568, #578)

  • Clearer error messages for invalid YAML nodes (#612) and Postgres query failures (#620)

  • Better error message when a query attempts to partition a table-valued function on request data (#555)

  • Parameter query logs include a top-10 breakdown by stream definition when limits are exceeded (#593)

Fixed

  • Crash when the same CTE is referenced from multiple sites (#604)

  • Crash when subqueries are nested inside other subqueries (#552)

  • Crash in queries joining multiple tables where more than one WHERE condition references columns from both tables (#608)

  • Unsound merge of EXISTS subqueries inside OR clauses (#556)

  • Compiler error when table-valued function outputs are used multiple times (#548)

  • Edge cases in expanding request filter expressions (#547)

  • Inferred column names for quoted identifiers (#551)

  • Unsupported SQL functions now produce a compile-time warning instead of a runtime crash (#595)

  • Replication of parameter rows that produce multiple outputs (#625)

  • Premature partial_checkpoint_complete for subscriptions with custom priorities, which caused checksum errors (#586)

Getting started

To use Sync Streams, add config: edition: 3 at the top of your sync config:

config:
  edition: 3

streams:
  my_todos:
    query: SELECT * FROM todos WHERE owner_id = auth.user_id()

See the Sync Streams quickstart for the full stream definition reference, parameters syntax, client-side subscription API, and examples.

Migrating from Sync Rules

Migrating takes a few clicks. Click Migrate to Sync Streams in the PowerSync Dashboard, or run powersync migrate sync-rules in the CLI to generate a draft from your current config. The output uses auto_subscribe: true by default, so client code keeps working as-is on first deploy.

From there, switch individual streams to on-demand subscriptions at your own pace.

See the migration guide for syntax mapping, before/after examples, and client-side instructions.

Feedback and help

If you come across a bug or want to see something else added to Sync Streams, open an issue on GitHub or reach out on Discord. Sync Streams were designed based on what we learned from Sync Rules, and we're going to keep improving them.

Thank you to everyone who used Sync Streams during the beta and reported what they found. This milestone is a direct result of your feedback.

Powered by LaunchNotes