Skip to main content


Ditto documents support all primitive JSON compatible types like string, boolean, number, etc.

All primitive types in Ditto are internally represented as so called Registers with "Last Writer Wins" semantics.

When a device updates a document, the last write to the document will win. A timestamp is attached to each update, and updates with later timestamps always win. To learn more about how this works, read about Ditto's Hybrid Logical Clock.

Data TypeAllowed Values
BooleanEither true or false.
StringA utf-8 encodable string value.
Unsigned integerAn unsigned 64-bit integer value.
Signed integerA signed 64-bit integer value.
FloatA 64-bit floating point value.
ArrayArrays are an ordered list of values. Arrays can contain all primitive values as well as nested collection types like other Arrays or Maps.
MapSometimes referred to as a dictionary, a Map represents a nested object within the overall document. Comparing values at the map level for equality first checks that each key and each value match.
nullThis represents an absence of a value.
// Insert JSON-compatible data into Dittoawait'people').upsert({  boolean: true,  string: 'Hello World',  number: 10,  map: { key: 'value' },  array: [],  null: null,})

How it works

Ditto uses a temporal timestamp called an HLC (hybrid logical clock) to associate each register value with a time. When two registers are merged the value with the highest timestamp wins.

For example, one attendant updates a customer's seat number to '6', and another to seat '9'. When the two conflicting versions merge, the edit with the highest timestamp wins.

In that case that two updates occur at exactly the same time, we use the unique ID of the Ditto SDK to tie-break, preferring the highest ID.

In the case of a number, like a seat number, a last-write-wins register is a good choice. Some numbers represent quantities over time, and that is when a Counter is useful.

Read more about how Ditto's CRDT works.