Delta is always eventually consistent, however changes may exist elsewhere in the network that have not yet reached the device.

When two devices have made changes to the same document, Delta needs to merge these changes together. This process is called merging.

Eventual consistency

Delta is always eventually consistent. This means that changes made on one device will eventually be reflected on all other devices in the network. However, changes may exist elsewhere in the network that have not yet reached the device. This is because Delta is designed to work offline and does not require a constant internet connection.

We’ve also engineered additional protections into Delta. We rely on causal consistency to ensure that changes are applied in the correct order. This means that changes are applied in the order they were made. This ensures that any changes on a single device that caused another change are applied in the correct order.

Merging

When two devices have made changes to the same record, Delta needs to merge these changes together. This process is called merging.

Delta uses a CRDT (Conflict-free Replicated Data Type) to ensure that changes can be replicated across multiple devices and merged without conflicts. We keep a logical clock (Lamport clock) to ensure that changes are applied in the correct order.

The default merge strategy is “Last-write-wins”. This means that the last change made to a record will be the one that is kept. However, you can also define custom merge strategies to handle conflicts in a more complex way. We do not rely on system time for last-write-wins, as this can be manipulated by a malicious actor. Instead, we use a logical clock, so the most updated record will be the change applied to the database.

Merge strategies

Merge level

There are four levels of merging in Delta:

  1. Cell level: Merging at the cell level is the most granular level of merging. This means that changes are merged at the level of individual cells in a record. This is the default merge level in Delta.
  2. Record level: Merging at the record level means that changes are merged at the level of individual records. This is useful when you want to keep the entire record consistent.
  3. Table level: Merging at the table level means that changes are merged at the level of entire tables. This is useful when you want to keep the entire table consistent.
  4. Database level: Merging at the database level means that changes are merged at the level of the entire database. This is useful when you want to keep the entire database consistent.

Each of these has tradeoffs. Merging at the cell level is the most granular, but is not suitable if there are many dependencies between cells. Merging at the database level is the most coarse, but is the most consistent.

Custom merge strategies

After selecting a merge level, you can define custom merge strategies to handle conflicts in a more complex way. For example, you could define a custom merge strategy that always keeps the oldest change, or that always keeps the change with the highest priority.

Merge strategies will only be employed when there is a conflict at your selected merge level.