Overview
The Substate Model is Radix's approach to storing and managing on-ledger state. Rather than using a global account-based model (Ethereum) or UTXOs (Bitcoin), Radix breaks state into fine-grained pieces called substates.
Each substate is an independently addressable, independently lockable piece of data. A component's state might consist of dozens of substates β each vault, each metadata field, each access rule is its own substate.
Why It Matters
This granularity is what enables Cerberus to achieve unlimited parallelism. Two transactions that touch different substates can execute on different shards simultaneously, even if they interact with the same component. Only transactions that touch overlapping substates need coordination.
Compare this to Ethereum's account model: any two transactions interacting with the same contract must be serialized, even if they access completely different data within that contract. This creates bottlenecks around popular contracts (DEXes, stablecoins).
How a Substate Is Addressed
Substates are not a storage detail bolted onto the ledger β they are one of the three abstractions the kernel layer of the Radix Engine is built around. The layered architecture reference lists the kernel’s responsibilities as defining the "Node, Partition, Substate abstractions", defining the call frame abstraction, maintaining ownership and reference invariants, and "managing transaction state updates, which are to be subsequently committed to the database at the end of the transaction" (Radix Engine Docs).
That gives every piece of on-ledger state a three-level address:
NodeIdβ the entity the state belongs to: a component, a resource manager, an account, a vault.- Partition Number β a numbered region of that node’s state, grouping related data together.
SubstateKeyβ the individual substate within the partition.
Below the kernel, the database layer flattens this into partition-key and sort-key abstractions "implemented on top of a key-value database". The kernel is explicitly "implemented on top of the database layer’s Partition Key and Sort Key abstractions", so the addressing scheme the engine reasons about and the keys the store actually writes are the same structure at two levels of detail. For the layer that executes code against these substates, see Kernel Layer and VM Layer.
Where a Component’s Substates Come From
A blueprint author never writes substates by hand. They declare fields β the individual pieces of a component’s state β and collections, the keyed structures (key-value stores, indexes, sorted indexes) a component uses for data that grows. "The mapping from the Fields and Collection indices to Partition Number is managed by the System Layer and done at a per blueprint basis" (Radix Engine Docs), so the layout is derived from the blueprint rather than chosen by the developer.
Object modules contribute partitions of their own on top of the blueprint’s: a component’s metadata, its royalty configuration, and its access rules are each their own state, addressed separately from the fields the blueprint declares. This is why the count adds up the way it does: a single Scrypto component is not one state blob but dozens of independently addressable substates β every vault it holds, every metadata entry, every access rule, and every entry in every collection.
What the Granularity Buys
Because a substate is the unit that gets read and written, it is also the unit that gets contended. Two transactions that touch disjoint substates have nothing to coordinate, even when they call into the same component β a swap against one vault and a metadata read on the same DEX are, as far as state is concerned, unrelated work.
The comparison in the Overview holds in the other direction too. Under an account model the contract is the unit of state, so any two transactions touching a popular contract must be ordered against each other whether or not they share any data. Under a UTXO model the granularity is there, but state is consumed and recreated rather than updated in place, which makes long-lived shared state awkward to express.
The practical consequence shows up in how Radix's sharded designs schedule work. hyperscale-rs distinguishes per-substate locking β where a transaction's manifest and blueprint metadata are analysed ahead of execution to determine exactly which substates it will touch β from hot-state flagging for indivisible state such as a pool price, where one shard batches many transactions under a single amortized lock. Neither technique is available to a runtime whose smallest lockable unit is an entire contract.
