Data Structures and Types
Ditto provides a flexible and efficient way to store and manage data so you can efficiently sync data for a wide range of applications and use cases.
Each data structure in Ditto has unique behaviors and characteristics that you'll need to be familiar with to achieve your specific goals.
This article provides a quick overview of Ditto's schema-flexible document model and advanced data types.
For more comprehensive information, see the Platform Manual.
Ditto stores data in JSON-like document objects. Each document consists of sets of human‑readable fields that identify and represent the information for storage in Ditto.
Each document is nested with a hash-stable tree structure that self-describes the data to be stored, as well as provides the predetermined rules that ensure data consistency and accuracy.
In Ditto’s document model, the supported data types depend on the CRDTs associated with the document. For more information about CRDTs, see the Platform Manual > Data Types and Document Model.
Syncing large documents can significantly impact network performance:
Caution is advised when handling large binary data, such as a high‑resolution image or video exceeding 50 megapixels; a deeply‑embedded document; or a very large document.
Instead of storing files exceeding 250kb directly within a document object, carefully consider using attachments . (See Attachment Objects)
The following snippet provides an example of a basic JSON‑like document object:
A document consists of sets of fields that self‑describe the data it encodes. Each set signifies a single pair of two associated elements:
Required and randomly generated and assigned by default upon creation, the first set of fields identify the document. (See Document Identifiers)
The first set of fields within each document uniquely identifies the data that its document object encodes. When grouped in a collection, this _id serves as the primary key identifying the document in the collection.
Ditto automatically generates and assigns each new document a unique identifier, or _id.
However, if desired, you can pass your own custom _id as a parameter in the upsert function you use to create a new document. (See CRUD Fundamentals)
In addition to having the option to supply your own _id, in complex scenarios where you want to create a more intricate and unique identifier for your documents, you can combine two or more distinct elements to form a composite key.
For more comprehensive information and how-to instructions, see the Platform Manual > CRUD Operations > Upserting and Updating.
If there is a set of documents that contain the same commonly-queried field, such as a string reference to cars, you can optimize query speed and reduce peer storage usage by grouping them in an index, or a collection.
The following snippet and corresponding table provide an example of a string reference to the collection cars.
To help better understand, think of a collection like a SQL database table and the documents it holds like table rows:

To improve performance, instead of storing a file that encodes large amounts of binary data as a document, you can opt to store it as a separate, explicitly-fetched object known as an attachment.
With the attachment CRDT, you can sync between peers without querying and merging.
For a real-world usage scenario, see either the demo chat app for iOS or Android in the getditto > demoapp-chat GitHub repository. The Chat demo employs the attachment type to optionally retrieve full-resolution avatar image from a collection named User.
For more comprehensive information and how-to instructions, see the Platform Manual > Data Types > Attachment.
You can model relationships between your data using foreign‑key relationships, key-value pair relationships by way of embedded CRDTmaps , as well as CRDT arrays.
Ditto does not support nesting documents within documents.
The following table provides a complete overview of the relationships you can establish in Ditto:
Relationship | Description | Approaches |
One-to-many | Associates a parent element with children elements to establish a hierarchy. |
|
Many-to-many | Associates multiple entities in one collection with multiple entities in another collection. |
|
Many-to-one | Associates two or more collections, where one collection refers to the primary key of another collection to create a meaningful relationship between the datasets. |
|
For more information, see Ditto Basics > CRUD Fundamentals and Platform Manual > CRUD Operations.
As a semi-structured distributed database, Ditto leverages conflict‑free replicated data types (CRDT) technology to enable advanced data exchange capabilities.
To get the most out of Ditto, you'll need to work with one or more CRDTs. Theregister type is the most common and simple type to use.
For more information, see Platform Manual > Register.
The following table provides a quick overview of the advanced data types you can use in Ditto, along with their guiding principles for conflict resolution, or merge semantics, a brief description, and a common usage scenario:
In Ditto’s document model, the supported primitive data types depend on the CRDTs associated with the document. For an overview of the data types that each CRDT allows, see Platform Manual > Data Types.
Type | Merge Semantics | Description | Use Case |
register | Last‑Write‑Wins Register, Delta-state replication | Stores a single value and allows for concurrent updates. | Updates associated with later temporal timestamps always win. |
map | Add-Wins Map, Delta-state replication | Working in conjunction with the Register, stores the mapping of temporal timestamps to the values written in the Register to help resolve concurrency conflicts. | Make a list of items in a document and update those items over time. |
counter | Positive or Negative Counter, The sum of all Site_ID Counters, Delta-state replication | Converts a number value for a given key into a Counter. Unlike a primitive number, value increments and decrements merge without conflict. | Manage inventory and handle votes, such as stock details and survey results. |
attachment | Last-Write‑Wins Register, Merges only when explicitly fetched | Stores very large amounts of binary data, such as an image file, and allows for concurrent updates. | Reduce Small Peer resource usage by storing data outside of memory. |
array | Last‑Write‑Wins Register, Delta-state replication | An extension of the register type, | |