> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ditto.live/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuring Collection Sync

<Info>
  This feature is available in v4.10 and above.
</Info>

## Introduction

User Collection Sync Scopes let you control how data from each user collection is shared with other connected Peers.
This is useful when you want to fine-tune which collections do not sync, which collections sync with only Ditto Server (a "Big Peer") and which collections sync only with connected Small Peer devices.

Sync scopes can be used to control how documents sync, reduce unnecessary data transfer, and improve performance.

## Usage

Sync scopes work on a per-collection basis. A collection's scope is checked when syncing data to other peers and can
prevent data from being sent, even if it matches the other peer's subscription.

### Sync Scopes

A collection can use one of the following sync scopes:

| Sync Scope             | Purpose                                                                                              |
| ---------------------- | ---------------------------------------------------------------------------------------------------- |
| `"AllPeers"` (default) | Sync with both Ditto Server and other Small Peers. This is the default behavior for all collections. |
| `"BigPeerOnly"`        | Sync only with Ditto Server. Do not sync with other Small Peers.                                     |
| `"SmallPeersOnly"`     | Sync only with other Small Peers. Do not sync with Ditto Server.                                     |
| `"LocalPeerOnly"`      | Do not sync this collection to Ditto Server or other Small Peers.                                    |

### Setting Sync Scopes

To configure sync scopes, use the DQL `ALTER SYSTEM` operation to set the `USER_COLLECTION_SYNC_SCOPES` system
property. This property takes a map where each key is a collection name and the value is the desired sync
scope.

<Note> `ALTER SYSTEM` configurations reset with each Ditto initialization. To maintain your settings, apply them after every
new Ditto instance initialization. For more details, see [`Advanced>Customizing System Settings`](/sdk/latest/sync/using-alter-system).</Note>

```sql DQL theme={null}
ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = {
    [collection_name]: [sync_option],
    ...
}
```

```sql DQL theme={null}
ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = {
    collection_1: "BigPeerOnly",
    collection_2: "SmallPeersOnly",
    collection_3: "LocalPeerOnly"
}
```

**Code Example**

In the example below we'll set the collection `local_mesh_orders` to only sync with other small peers in the mesh and not with Ditto Server
using the `SmallPeersOnly` sync scope.

<Warning> `ALTER SYSTEM USER_COLLECTION_SYNC_SCOPES` must be called before `startSync()` to ensure data is not unintentionally synced.</Warning>

<CodeGroup>
  ```swift Swift theme={null}
  var syncScopes = [
    "local_mesh_orders": "SmallPeersOnly"
  ];
  await ditto.store.execute(
      query: "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
      arguments: ["syncScopes": syncScopes]);

  try! ditto.sync.start()

  ```

  ```kotlin Kotlin theme={null}
  ditto.store.execute(
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    mapOf("syncScopes" to mapOf(
      "local_mesh_orders" to "SmallPeersOnly"
    )))

  try {
      ditto.sync.start()
  } catch (e: DittoError) {
      // handle error
  }
  ```

  ```javascript JS theme={null}
  const syncScopes = {
    local_mesh_orders: "SmallPeersOnly"
  };
  await ditto.store.execute(
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    { syncScopes }
  );

  try {
    ditto.startSync()
  } catch (err) {
    // handle error
  }
  ```

  ```typescript TS theme={null}
  import { Ditto, QueryResult } from '@dittolive/ditto'

  type SyncScope = "AllPeers" | "BigPeerOnly" | "SmallPeersOnly" | "LocalPeerOnly"

  interface SyncScopesConfig {
    [collectionName: string]: SyncScope
  }

  const syncScopes: SyncScopesConfig = {
    local_mesh_orders: "SmallPeersOnly"
  }

  const result: QueryResult = await ditto.store.execute(
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    { syncScopes }
  )

  try {
    ditto.startSync()
  } catch (err: unknown) {
    // handle error
  }
  ```

  ```java Java theme={null}
  Map<String, String> syncScopes = new HashMap<>();
  newCar.put("local_mesh_orders", "SmallPeersOnly");

  ditto.getStore().execute(
      "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
      Collections.singletonMap("syncScopes", syncScopes));

  try {
      ditto.getSync().start();
  } catch(DittoError e) {
      // handle error
  }
  ```

  ```csharp C# theme={null}
  var args = new Dictionary<string, object> {
    "syncScopes", new { local_mesh_orders = "SmallPeersOnly" }
  };

  await ditto.Store.ExecuteAsync(
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    args);

  try
  {
      ditto.Sync.Start();
  }
  catch (DittoException ex)
  {
      // handle exception
  }
  ```

  ```cpp C++ theme={null}
  std::map<std::string, std::map<std::string, std::string>> args;
  args["syncScopes"] = {{"local_mesh_orders", "SmallPeersOnly"}};

  ditto.get_store().execute(
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    args);

  try {
    ditto.get_sync().start();
  } catch (const DittoError &err) {
    std::cerr << err.what();
  }
  ```

  ```rust Rust theme={null}
  #[derive(serde::Serialize)]
  struct Args {
    #[serde(rename = "syncScopes")]
    sync_scopes: SyncScopes,
  }
  #[derive(serde::Serialize)]
  struct SyncScopes {
    local_mesh_orders: String,
  }

  // ...

  let args = Args {
    sync_scopes: SyncScopes {
      local_mesh_orders: "SmallPeersOnly".to_string()
    },
  };

  ditto.store().execute((
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    args,
  )).await?;

  ditto.sync().start()?;
  ```

  ```dart Dart theme={null}
  final syncScopes = {
    "local_mesh_orders": "SmallPeersOnly"
  };

  await ditto.store.execute(
    "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
    arguments: {"syncScopes": syncScopes},
  );

  try {
    ditto.startSync();
  } catch (e) {
    // handle exception
  }
  ```

  ```go Go theme={null}
  syncScopes := ditto.Document{"local_mesh_orders": "SmallPeersOnly"}
  result, err := dit.Store().Execute(
      "ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = :syncScopes",
      ditto.QueryArguments{"syncScopes" : syncScopes},
  )
  if err != nil {
      return err
  }
  defer result.Close()  // cleanup

  if err = dit.Sync().Start(); err != nil {
      // handle error
  }
  ```
</CodeGroup>

### Reading Sync Scopes

To see the currently set sync scopes use the DQL `SHOW` command with the `USER_COLLECTION_SYNC_SCOPES` system property.

```sql DQL theme={null}
SHOW USER_COLLECTION_SYNC_SCOPES
```

### Updating Sync Scopes

To change sync scopes after they are set, use the `ALTER SYSTEM` command to update the `USER_COLLECTION_SYNC_SCOPES` parameter.

<Note>System parameters can now be updated while sync is active, though it may take some time for changes to take effect depending on cached state.</Note>

```sql DQL theme={null}
ALTER SYSTEM SET USER_COLLECTION_SYNC_SCOPES = {
    collection_1: "BigPeerOnly",
    collection_2: "LocalPeerOnly"
}
```

### Usage Considerations

* `USER_COLLECTION_SYNC_SCOPES` is reset when the Ditto instance is closed.
* Be sure to always set `USER_COLLECTION_SYNC_SCOPES` after creating a new Ditto instance.
* For best results, set `USER_COLLECTION_SYNC_SCOPES` before calling `startSync()` to ensure data is not unintentionally synced.
* Sync scopes are defined on a per-device basis and not shared with other peers in the mesh.
* Sync scopes are designed to allow users to control how document on a device flow out on a per collection basis.
* Sync scopes will be enforced locally over sync subscriptions from other peers. Meaning if a collection has a sync scope
  that doesn't allow for sharing with that peer documents will not be share even if that peer has permissions to that
  collection.
* To have a collection that is only synced with other Small Peers and never synced with Ditto Server all peers
  need to individually set the collection to have the `SmallPeersOnly` sync scope. If any peer in the mesh does not set this
  that peer will send data to Ditto Server.

### Limitations

* Sync scopes cannot be applied to system collections. These are collections prefixed with double underscore `__`. Updating
  `USER_COLLECTION_SYNC_SCOPES` with a system collection will fail.
* Sync scopes are not enforced for remote query requests.

## Use Case Scenarios

### Local-Device Only Collections

A Local-Device Only Collection keeps data stored only on the device where it was created. This is useful when the data is temporary,
sensitive, or tied to the specific device. Common examples include caches of recently viewed items, unsaved drafts, or device-specific
settings like user preferences.

In these cases, syncing the data to other peers — or to Ditto Server — is unnecessary and could introduce privacy or performance concerns.
By setting the collection to `LocalPeerOnly`, you ensure the data never leaves the device.

### Small Peers Only Collections

A Small Peers Only Collection allows data to sync only with nearby Small Peers, without ever syncing to Ditto Server. This is useful for
temporary collaboration data or ephemeral sessions where nearby devices work together locally.

This approach helps reduce unnecessary cloud storage and limits data visibility to just the local mesh. To configure this, set the
collection’s sync scope to SmallPeersOnly.

A common pattern is to use a Small Peers Only collection for active or in-progress data being shared between devices. Once the data reaches
a final state — such as after a process is completed — you can copy or move the finalized data into a separate collection that syncs with
Ditto Serverfor long-term storage or reporting.

### Big Peer Only Collections

A Big Peer Only Collection syncs data exclusively with a Big Peer (Ditto Server), ensuring it is not shared with connected Small Peers. This is particularly
useful when data needs to be stored in the cloud without being distributed across other devices. Ideal use cases include audit logs, user
preferences, or any information meant for centralized storage and retrieval rather than real-time peer-to-peer collaboration.
