# Syncing big data

Synchronizing entities with `byte[]` or `string` bindings, or sending commands with `byte[]` or `string` arguments allows you to sync large amounts of custom data. However, if an entity update, or a single command, is too large to fit inside a single packet (where default MTU is 1280 bytes), then the entity update or the command will never be synchronized. To solve this problem, and be able to sync data of practically any size, you can use **fragmented channels** for synchronization of entities or commands.

{% hint style="warning" %}
Because of the implementation nature of **fragmented channels**, sending large units of data over a **fragmented channel** will delay subsequent updates and commands (even of different entities) sent over the same **fragmented channel** until the original data is fully transferred.

For this reason, it is recommended to **separate latency-sensitive bindings** (such as player position) and big-data bindings by dividing them into different **CoherenceSyncs**.
{% endhint %}

Data synchronized over the **fragmented channels** shares the bandwidth with other data synchronized over other channels, but data sent over the **non-fragmented channels** has priority over fragmented data. Because the **bandwidth is** **shared** (not multiplied), very large data sent over a fragmented channel might be more delayed if you're already syncing a lot of data over other channels.

Watch out for the amount of data you're sending over the fragmented channel, since the default bandwidth is not very high. For example, at the default MTU of 1280 bytes and default send rate of 20Hz, the maximum data bandwidth is around 24KB/s (this is after taking part of the bandwidth for coherence headers). If no other data is sent over other channels, 100KB of data sent over a fragmented channel would take **over 4 seconds** to transfer to the Replication Server, and **4 more seconds** to transfer to other Clients, which brings the total latency to over 8 seconds for 100KB of data. But 5KB of data would be synced to other clients in under 500ms.

{% hint style="success" %}
The default MTU of 1280 bytes and send rate of 20Hz are used because they will work on most internet connections and are thus optimal for most games.
{% endhint %}

{% hint style="info" %}
Note that there is currently no reporting of transfer progress in the SDK. Because of that, when sending considerable amounts of data, the synchronization might feel stuck, but it's probably just taking time to transfer the data to the replication server and then to other clients.
{% endhint %}

In case you want to synchronize a considerable amount of data, which would be too slow using the default bandwidth, we recommend exploring other options such as [Cloud Storage](https://docs.coherence.io/hosting/coherence-cloud/game-services/cloud-storage), rather than increasing the MTU or send rate.

### Syncing big data over entity bindings

In the *Advanced Settings* of the **CoherenceSync,** you can change the **Synchronization Channel** of an entity. Choosing the **Fragmented** channel will synchronize creation, deletion, and all binding updates of the entity over the **Fragmented** channel, allowing you to sync data of any size.

{% hint style="info" %}
Note that the commands targeting that entity will still be sent over any channel. See the [commands section](#syncing-big-data-over-commands) for more details.
{% endhint %}

{% hint style="warning" %}
Use **Fragmented** channels only for entities that you are sure will have large data to synchronize, because, as noted before, those entities could potentially experience increased latency.
{% endhint %}

<figure><img src="https://content.gitbook.com/content/CMCtKgV0bk1lwR4tWK3W/blobs/PTWWUIxsB6zYD4LAwhp4/01%20Syncing%20big%20data.png" alt=""><figcaption></figcaption></figure>

Since you don't want to send most bindings over the **fragmented channel**, the recommended way is to move bindings that contain big data to a separate **CoherenceSync,** and set only the new **CoherenceSync's Synchronization Channel** to **Fragmented**. One way of grouping those two entities together is by making the big data Prefab a child of the original Prefab using the [**PrefabSyncGroup**](https://docs.coherence.io/manual/parenting-network-entities/nesting-prefabs-at-edit-time).

Note that the big data child object might not be replicated to the remote Clients at the same time as the parent object, so you need to be sure your game logic can handle a scenario where the big data child object is delayed.

### Syncing big data over commands

You can send commands over the **fragmented channel** to any entity, no matter if the entity is synchronized over the **Fragmented** or **Default** channel. To send a command over the **fragmented channel,** use the `SendCommandOverChannel(...)` and `SendCommandToChildrenOverChannel(...)` overloads, passing either **Fragmented** or **FragmentedOrdered** channel (for [ordered](https://docs.coherence.io/manual/commands#ordering-of-commands) commands) as an argument.

{% hint style="warning" %}
Use **Fragmented** channels only for commands that you are sure will have large data to send, because, as noted before, those commands could potentially experience increased latency.
{% endhint %}

```csharp
var data = new byte[5 * 1024]; // 5KB of data
sync.SendCommandOverChannel<Player>(
    nameof(Player.SendData),
    MessageTarget.AuthorityOnly,
    Channel.Fragmented,
    data);
```
