Storage types
Smart contracts can persist data in the Stellar ledger using the storage interface (env.storage() in Soroban SDK). There are three types of storage available on the Stellar network:
Every storage type can be thought of as a map from arbitrary keys to arbitrary values. The data is physically stored in the Stellar ledger.
Every storage ‘map’ is completely independent from every other storage ‘map’. It is possible to store different data for the same key in every storage. For example, in temporary storage, key
123_u32 may have a value of 100_u32, while in persistent storage the same 123_u32 key may have a value of abcd.
All the storage types have almost exactly the same functionality, besides the differences highlighted in the table above, specifically cost, behavior when TTL expires, and limit for the number of keys stored per contract.
A note on TTL
If you’re wondering what ‘TTL’ means, here is a quick intro on TTLs and state archival in Stellar. State archival is a special mechanism defined by the Stellar protocol that ensures that the active ledger state size doesn’t grow indefinitely. In simple terms, every stored contract data entry, as well as contract code (Wasm) entry, has a certain ‘time-to-live’ (TTL) assigned. TTL is just a number of ledgers for which the entry is considered to be ‘active’, and after that number of ledgers, the entry is considered to have TTL expired and thus no longer active. Different storage types handle TTL expiration differently: data will either be moved to the archive (‘cold’, off-chain storage), or automatically removed from the ledger (in case of temporary storage). The data stored in the archive can be restored on-chain later and thus become active again. TTL also may be extended however many times are necessary, for a fee. Read more about state archival here.Persistent storage
This storage type is used for storing data on the network over an indefinitely long time period. For persistent storage, when the TTL reaches zero, the entry is moved to the archival storage. It can then be restored when needed — usually automatically, by including the entry in a transaction’s restore list (which transaction simulation typically populates for you), or manually using theRestoreFootprintOp operation.
Persistent storage is the default storage type use-case-wise. Instance and temporary storage are only useful for the specific use cases described in the respective sections. Stellar protocol also uses persistent storage to store the contracts and their Wasm executables, so that they always can be accessed or restored.
Examples of data that may be stored on persistent storage include user balances, token metadata, voting and governance decisions, and all data that need to either remain accessible forever, or until explicitly deleted.
Let’s look at a contract for a loyalty points system where users can accumulate points and redeem them for rewards. Each user’s point balance will be stored in persistent storage.
Instance storage
Instance storage is a small, limited-size map attached to the contract instance. It is physically stored in the same ledger entry as the contract itself and shares TTL with it. Like persistent storage, instance storage stores data permanently. However, it has a few pros and cons compared to it:- Pro: Data TTL is tied to the contract instance, thus making state archival behavior much easier
- Pro/Con: Data is loaded automatically together with the contract, thus reducing the transaction footprint size, but increasing the number of bytes read every time the contract is loaded (usually this still will result in a lower fee)
- Con: The total size of all the keys and values in the instance storage is limited by the ledger entry size limit. See the current value of the limit on the Stellar Lab. The total number of keys supported is on the order of tens to hundreds depending on the underlying data size and the current network limit. The limit is set by validator vote, and the protocol only requires it to stay at or above a small fixed minimum, so it isn’t guaranteed to never decrease. Leave headroom rather than filling instance storage close to the current limit.