This feature is available in SDK version 4.12.0 and later.
Every data modification in Ditto returns a commit ID that you can use to track when that specific commit reaches other peers in your mesh network.

What Are Commit IDs?

Commit IDs are unique, monotonically increasing identifiers assigned to each data modification on your device:
let result = try await ditto.store.execute(
  query: "UPDATE products SET price = 99.99 WHERE _id = 'product-123'"
)
print("Commit ID: \(result.commitID ?? -1)") // e.g., 1547

Key Properties

  • Monotonic - Always increasing (1547, 1548, 1549…)
  • Device-specific - Each device has its own sequence
  • Per-operation - Every INSERT, UPDATE, DELETE gets a new ID
  • Trackable - Use with system:data_sync_info to monitor sync progress

Tracking Sync Progress

Compare your commit ID with synced_up_to_local_commit_id to see if peers have received your commit:
// Step 1: Execute statement and get commit ID
let result = try await ditto.store.execute(
  query: "UPDATE orders SET status = 'shipped' WHERE _id = :id",
  arguments: ["id": "order-456"]
)
let commitId = result.commitID!

// Step 2: Check if it synced to cloud
let syncResult = try await ditto.store.execute(
  query: "SELECT * FROM system:data_sync_info WHERE is_ditto_server = true"
)

if let item = syncResult.items.first,
   let documents = item.value["documents"] as? [String: Any],
   let syncedUpTo = documents["synced_up_to_local_commit_id"] as? Int64 {
  
  if syncedUpTo >= commitId {
    print("Commit synced to cloud")
  } else {
    print("Syncing...")
  }
}

Monitoring Multiple Commits

Observers on system:data_sync_info result in the callback triggering every 500ms even when the result remains the same. This frequency can be configured using the live_query_system_collection_refresh_interval system parameter.
Track several commits and watch them sync in order:
var pendingCommits: [Int64] = []

// Make several commits
let result1 = try await ditto.store.execute(
  query: "UPDATE inventory SET quantity = quantity - 1 WHERE _id = 'item-1'"
)
if let commitId1 = result1.commitID {
  pendingCommits.append(commitId1)
}

let result2 = try await ditto.store.execute(
  query: "INSERT INTO orders DOCUMENTS (:order)",
  arguments: ["order": ["_id": "order-789", "status": "pending"]]
)
if let commitId2 = result2.commitID {
  pendingCommits.append(commitId2)
}

// Watch them sync
let observer = ditto.store.registerObserver(
  query: "SELECT * FROM system:data_sync_info WHERE is_ditto_server = true"
) { result in
  guard let item = result.items.first,
        let documents = item.value["documents"] as? [String: Any],
        let syncedUpTo = documents["synced_up_to_local_commit_id"] as? Int64 else { return }
  
  // Check which commits have synced
  var syncedCount = 0
  for commitId in pendingCommits {
    if syncedUpTo >= commitId {
      print("Commit \(commitId) synced")
      syncedCount += 1
    } else {
      break
    }
  }
  
  // Remove synced commits
  if syncedCount > 0 {
    pendingCommits.removeFirst(syncedCount)
    print("\(pendingCommits.count) commits remaining")
  }
}

Transaction Behavior

Commit IDs are only assigned after transactions complete:
var queryResult: DittoQueryResult?

try await ditto.store.transaction { transaction in
  queryResult = try await transaction.execute(
    query: "INSERT INTO orders DOCUMENTS ({ _id: 'order-123', total: 99.99 })"
  )
  
  print(queryResult?.commitID ?? "nil") // nil - not committed yet
  
  return try await transaction.commit()
}

print(queryResult?.commitID ?? "nil") // 1548 - now has commit ID

Checking Specific Peers

Track sync progress to any peer (not just cloud servers):
// Check sync to a specific peer device
let syncResult = try await ditto.store.execute(
  query: "SELECT * FROM system:data_sync_info WHERE _id = 'peer-device-456'"
)

if let item = syncResult.items.first,
   let documents = item.value["documents"] as? [String: Any],
   let peerSyncedUpTo = documents["synced_up_to_local_commit_id"] as? Int64 {
  print("Peer has synced up to commit \(peerSyncedUpTo)")
}

Best Practices

Remember that Ditto is offline-first. Use commit ID tracking to enhance user experience, not to block operations.
  • Don’t block operations - Let users continue working while tracking sync in background
  • Show progress indicators - Use commit tracking to display sync status in your UI
  • Handle concurrency gracefully - Tracking should enhance the experience, not block it
  • Monitor critical data - Focus tracking on important operations like payments or submissions
  • Clean up tracking - Remove old commit IDs from your tracking lists to avoid memory issues