4.11.0 Version Release
Release Date: June 10, 2025

4.11 - DQL & Legacy Compatibility

With 4.11 we are excited to introduce legacy compatibility for DQL, which allows developers to use the new DQL APIs while maintaining compatibility with existing code and data. This capability, called STRICT MODE, is designed to ease the transition to the new APIs and ensure that existing applications continue to function as expected.

DQL Strict Mode

DQL Strict Mode provides control over how DQL statements are evaluated and how data types are inferred. When disabled, it offers more flexibility in working with documents without requiring explicit collection definitions.

For more information see DQL Strict Mode

With strict mode disabled (DQL_STRICT_MODE=false), Ditto is more flexible and will infer the CRDT type based on the document’s shape:

  • Objects are treated as CRDT maps
  • Scalars and arrays are treated as Registers
  • Counters and attachments are inferred from operations
  • Collection definitions are no longer required

Setting DQL Strict Mode

DQL
ALTER SYSTEM SET DQL_STRICT_MODE = false

DQL Differ

DQL 4.11 introduces a new Differ API for calculating diffs between query results. This API can be used with a store observer to understand how its results change over successive callbacks. The Differ API provides a way to track changes in the data and can be used to optimize data synchronization and conflict resolution.

Differ API documentation.

DQL Transactions

DQL 4.11 introduces support for transactions. Transactions can be used to group multiple DQL statements together, ensuring that either all of the statements are executed successfully or none of them are. This is particularly useful in scenarios where multiple updates or inserts need to be made to the database, and you want to ensure that either all of them are applied or none of them are.

Transactions API documentation.

Advanced DQL Features

DQL 4.11 introduces numerous advanced querying and manipulation features:

FeatureDescriptionExample
UNSET clauseRemove fields from documentsUPDATE orders UNSET items.abc WHERE _id = 'my-id'
CAST functionExplicitly convert between data typesSELECT * FROM products WHERE CAST(price AS INT) > 10
USE IDS clauseDirect document retrieval by IDSELECT * FROM products USE IDS ['123', '456']
SIMILAR TOPattern matching expressionsSELECT * FROM products WHERE name SIMILAR TO '%phone%'
Runtime expressionsUse expressions in object/array constructionUPDATE products SET metadata = { 'updated_at': current_timestamp() }
CountersSupport for legacy compatible counter typeUPDATE products APPLY in_stock PN_INCREMENT BY 1.0

In 4.11, functional operations are denoted with an arrow (->) are deprecated.

Tombstone Reaper

The tombstone reaper is now enabled by default for all SDKs. This feature helps clean up deleted document markers (tombstones) to improve database performance and reduce storage requirements.

The reaper:

  • Automatically removes tombstones after a configurable time-to-live (TTL)
  • Uses read transactions for efficiency
  • Includes random scheduling variations to prevent performance problems
  • Tracks the number of tombstones evicted for monitoring
  • Remembers previous reap times across restarts

This improves overall system performance by reducing the long-term accumulation of tombstones when calling DELETE to remove documents.

4.11.0 Common Changelog

4.11.0 JavaScript & React Native Specific Changes

Fixed: Creating multiple Ditto instances with the same persistenceDirectory parameter now throws a DittoError with code store/persistence-directory-locked instead of only logging an error. This change prevents constructing a non-functional instance as Ditto does require separate configurations for this parameter when multiple instances are instantiated. (#12336)

Added: Error code store/persistence-directory-locked to the DittoError class. (#12336)

Added: property SmallPeerInfo.syncScope to replace the now deprecated methods SmallPeerInfo.getSyncScope() and Ditto.smallPeerInfo.setSyncScope(). (#15579)

Deprecated: Methods SmallPeerInfo.getSyncScope() and SmallPeerInfo.setSyncScope(), use the SmallPeerInfo.syncScope property instead. (#15579)

Added: Method transaction() on Store allowing a DQL transaction to be performed. (#15800)

Added: Transaction representing an active DQL transaction. (#15800)

Added: TransactionInfo encapsulating information about a transaction. (#15800)

Added: TransactionCompletionAction representing an action to be taken upon completing a transaction: Commit or Rollback. (#15800)

Added: An opt-in Android foreground service which allows Ditto to sync in the background. (#16097)

Added: ditto.observeTransportConditions() API for React Native that will allow developers to be aware transports conditions changes, like shutting down bluetooth. (#16518)

Added: class Diff to represent diffs produced by the Differ. (#16723)

Added: class Differ, which calculates diffs between query results. This can be used with a store observer to understand how its results change over successive callbacks. (#16723)

Added: More detailed messages about network problems are logged when authentication fails (#SEC-124)

Changed: Unify dedicated TCP servers across different transports (Multicast, mDNS, and WiFi Aware) by utilizing a single static TCP server implementation (#TRANS-131)