Skip to main content

Dynamic sync controls

In active-active replication we've seen how to sync data between Postgres and SQLite. Normally though, when you're building an app, you don't want to sync all of the data onto the local-device. You want to limit it to just the data the user needs and is allowed to access.

With ElectricSQL, you control this using DDLX rules and Shapebased sync.

DDLX rules

DDLX rules are the core, row-level primitive for database administrators to control what data is allowed to sync where.

First, tables need to be electrified to sync at all:

ALTER TABLE projects

Then users are assigned roles based on their authentication state (usually by matching the user_id in their authentication token with foreign keys to your users table):

ELECTRIC ASSIGN 'projects:owner'
TO projects.owner_id;

Roles are then granted permissions to access the data:

ON projects
TO 'projects:owner';

Data only replicates onto a user's device if that user has permission to read it and only replicates off from their device if they have permission to write it.

Shape-based sync

Shapes are the core primitive for app developers to control what data actually syncs where. They are incredibly powerful and flexible: allowing you to reach into a central cloud database, take a subset of related data and sync just that set of data onto the local device.

For example, you can sync:

  • a workspace and all its documents and their data
  • a region and all its locations and their data
  • a time period and all its events

Shapes are live, so if new data arrives that matches the shape, that data also syncs onto the local device. And they're dynamic, so they can change at runtime, using the sync function, e.g.:

const shape = await db.projects.sync({
where: {
id: {
in: selectedProjectIds
include: {
issues: {
include: {
comments: true

Within a shape, data is filtered based on permissions. So if you sync all projects:

const shape = await db.projects.sync({
where: true

The user will only actually get the projects that they're authorised to access.

That's a taster of how you control what data syncs where. Let's wrap up by looking at the real-world apps you can build with this model »