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
Because each substate can be locked on its own, two transactions conflict only if they touch the same substates, even when they call the same component. That is the property Cerberus was designed to exploit, by running non-conflicting transactions on different shards at once. Mainnet does not shard yet: Babylon runs as a single shard group, so today the granularity decides what conflicts rather than where it runs.
Under Ethereum's account model the contract is the unit of state, so any two transactions touching the same contract are ordered against each other even when they read and write different data inside it, which bottlenecks popular contracts such as exchanges and 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.
