Consistency model
Clustron Zaris gives you a consistent and predictable view of your data across nodes. This article explains what that means in practice, so you can predict how reads and writes behave — and know when you need to add coordination on top.
What consistency means here
Consistency is about how data behaves when more than one thing is happening at once: multiple nodes hold the data, multiple clients read and write the same key, and updates arrive concurrently. The model is designed to balance three goals — correctness, availability, and performance — so it does not chase absolute guarantees at the cost of being usable.
One logical store
Even in distributed mode, a store presents itself as a single logical store. You address the store, not individual nodes, and you do not manage replication or route requests to specific nodes yourself. Many nodes back the store, but you reason about one consistent view:
Multiple nodes → one consistent view
This is the foundation everything else rests on: your application code treats a distributed store the same way it treats an in-process one.
How reads and writes behave
Writes are applied through the cluster, which keeps the store in a consistent state as changes land. You do not coordinate replication between nodes — that is the system's responsibility.
Reads return the latest known value. Crucially, once a write succeeds, subsequent reads reflect that write. This read-after-write behavior is what lets you write a value and then rely on reading it back, rather than second-guessing whether the update has propagated.
Read-after-write holds because reads go to the primary by default, and the primary is where writes land. If you enable replica reads (AllowReplicaReads) under the default Async replication, a read served by a lagging replica can return stale data — so read-after-write is no longer guaranteed. See Partitioning and replication for the routing and replication-mode details.
For most applications the result is that you interact with the store as if it were a single instance: predictable reads and writes, no manual replication, and no consistency bookkeeping across nodes.
Configuring consistency
The knobs that shape these guarantees live in the store configuration. The defaults (Async replication, primary-only reads) give you read-after-write out of the box; change them when a workload needs different trade-offs:
- Replication mode —
replication.mode:Async(default; lowest latency, a failover may lose the most recent writes) orSync(waits for replicas, stronger durability). WithSync,replication.quorum(All,Majority, orBestEffort) decides how many replicas must acknowledge. - Replica reads —
reads.allowReplicaReads(defaultfalse). Enable it only for read-heavy workloads that tolerate slightly stale reads; it trades read-after-write for read throughput.
{
"replication": { "factor": 2, "mode": "Sync", "quorum": "Majority" },
"reads": { "allowReplicaReads": false }
}
The replication factor is set when you create the store (New-ZrStore -ReplicationFactor). For every field and default, see the configuration reference.
Concurrent updates to the same key
When multiple clients update the same key at the same time, the store handles the operations safely and settles on a consistent outcome — you will not end up with a corrupt or half-written value. What a plain write does not do is check whether someone else changed the key first.
A plain PutAsync is a blind write: it overwrites whatever is there, so two clients updating the same key concurrently can produce a lost update — the second write silently replaces the first. If the correctness of an update depends on the value you read, do not rely on ordinary writes. Use a transaction, which detects a conflicting change and fails instead of overwriting, or a lock or lease to ensure only one client updates the key at a time.
The same model in both modes
The consistency model is identical in in-process and distributed modes. Your application does not need different logic depending on where the store runs, which is what makes it safe to develop against an in-process store and deploy against a distributed one.
When you need stronger guarantees
The default behavior is enough for straightforward reads and writes. When an operation needs ordering, exclusivity, or all-or-nothing semantics, reach for the coordination primitives:
- Locks to give one client exclusive access and prevent conflicting updates.
- Transactions to group multiple operations so they apply together, with conflict detection through optimistic concurrency.
- Leases to manage ownership of a resource and release it automatically on failure.
These let you opt into stronger coordination exactly where you need it, without paying for it on every operation.