Skip to main content

Object Versioning

Sui references every object stored onchain by an ID and version. When a transaction modifies an object, it writes the new contents to an onchain reference with the same ID but a new version. Despite appearing multiple times in the store, only the latest version of an object is available to transactions. Only one transaction can modify an object at a given version, guaranteeing a linear history.

(I, v0) => ...
(I, v1) => ... # v0 < v1
(I, v2) => ... # v1 < v2

Versions strictly increase and Sui never re-uses (ID, version) pairs. This allows node operators to prune old object versions from their stores, though they might also retain them to serve historical requests or help other nodes catch up.

Object versioning paths​

Sui versions objects either through the fastpath or through consensus. The choice affects object ownership options and has performance trade-offs.

Sui uses Lamport timestamps in its versioning algorithm. This guarantees that Sui never re-uses versions: a transaction sets the new version for all objects it touches to 1 + max(version of all input objects). For example, a transaction transferring object O at version 5 using gas object G at version 3 updates both to version 1 + max(5, 3) = 6.

The following table summarizes the two paths. The Fastpath objects and Consensus objects sections describe each path in detail.

PropertyFastpathConsensus
Ownership typesAddress-owned, immutableAddress-owned, party, shared
Who sets the versionThe sender names the exact versionConsensus assigns the version during scheduling
Transaction input referenceID and versionShared objects: ID, the version the object was shared at, and a flag indicating mutable access
LatencySuited to latency-sensitive applicationsCan increase when multiple transactions contend for an object
Multiple sendersRequires offchain coordinationNo offchain coordination needed
Good fit forLatency- or gas-sensitive applications, no complex multi-party transactions, existing offchain coordinationApplications that require coordination between multiple parties

Fastpath objects​

tip

Use party objects rather than fastpath objects. Sui versions party objects through consensus, not the fastpath.

Fastpath objects can only be address-owned or immutable. The sender names the exact version to use, so these objects need no consensus-assigned version and do not contend with other transactions for one.

Every fastpath transaction must use the object's current version as input and use the output version as the reference for the next transaction. If multiple senders frequently use a fastpath object, coordinate offchain access or use a consensus object instead.

You must reference fastpath transaction inputs at a specific ID and version. Validators reject conflicting transactions that require the same mutable owned object version. You also reference immutable objects at a specific version, but validators do not need to lock them because their contents never change. Their version identifies the point at which they became immutable.

Fastpath is a good fit for applications that are extremely sensitive to latency or gas costs, do not need complex multi-party transactions, or already rely on an offchain coordination service.

Consensus objects​

Consensus objects can be address-owned, owned by a party, or shared. Consensus sequences reads and writes on these objects and assigns their versions, which can raise latency when multiple transactions contend for an object, but you manage versions more easily, especially for frequently accessed or multi-party objects.

Transactions accessing multiple consensus objects or particularly popular objects might see increased latency due to contention. The trade-off is flexibility: multiple addresses can access the same object in a coordinated way without offchain coordination.

You reference shared transaction inputs by ID, the version the object was shared at, and a flag indicating whether the transaction accesses it mutably. You don't specify the precise access version because consensus determines that during scheduling, the step where consensus sequences the transactions that access the object and assigns their versions: one transaction's output version becomes the next transaction's input version. Immutably referenced shared objects participate in scheduling but don't increment the object's version.

Consensus is a good fit for applications that require coordination between multiple parties.

Wrapped and dynamic field objects​

Wrapped objects are not accessible by their ID in the object store. You must access them through the object that wraps them. You do not need to supply a wrapped object's ID or version as transaction input. Validators refuse to sign transactions that specify wrapped objects directly as inputs.

A transaction can unwrap a wrapped object, after which the object is accessible by its ID again. An object retains its ID across all wrap and unwrap events. Lamport timestamp versioning ensures the version at unwrap is always greater than the version at wrap.

Dynamic fields behave similarly: they are only accessible through their parent object and you do not need to supply them as transaction inputs. However, unlike wrapped objects, if a transaction modifies a dynamic object field, that transaction increments its version. Lamport versioning also ensures that when you remove a field and re-add it with the same name, the new Field object's version is strictly greater than the deleted one's, so Sui never reuses (ID, version) pairs.

Why does object versioning matter?​

Understanding object versioning helps you design applications correctly and avoid common mistakes:

  • Avoid stale version references. If your client code caches an object version and another transaction modifies that object before yours executes, validators reject your transaction. Always fetch the latest version before submitting.
  • Choose the right versioning path. Fastpath reduces latency for single-owner workflows. Consensus handles multi-party coordination without requiring offchain locking.
  • Prune safely. Because Sui never reuses (ID, version) pairs, node operators can safely prune old versions without risking collision with future writes.
  • Reason about history. The strictly increasing version sequence gives every object a linear, auditable history. Archival nodes can serve any historical version to clients that need it.