# Storage Layout

Smart contract authors are given some flexibility in regards on how they want to organize the storage layout of their contracts. Let's dive deeper into the concepts behind ink! storage to get a better understanding of some of its implications and limitations.

### Storage Organization[​](https://use.ink/datastructures/storage-layout#storage-organization) <a href="#storage-organization" id="storage-organization"></a>

The following schema depicts the storage which is exposed to ink! by the contracts pallet:

<figure><img src="https://use.ink/img/kv.svg" alt=""><figcaption></figcaption></figure>

Storage data is always encoded with the [`SCALE`](https://docs.substrate.io/reference/scale-codec/) codec. The storage API operates by storing and loading entries into and from a single storage cells, where each storage cell is accessed under its own dedicated storage key. To some extent, the storage API works similar to a traditional key-value database.

### Packed vs Non-Packed layout[​](https://use.ink/datastructures/storage-layout#packed-vs-non-packed-layout) <a href="#packed-vs-non-packed-layout" id="packed-vs-non-packed-layout"></a>

Types that can be stored entirely under a single storage cell are considered [`Packed`](https://docs.rs/ink_storage_traits/4.0.0/ink_storage_traits/trait.Packed.html). By default, ink! tries to store all storage struct fields under a single storage cell. Consequentially, with a `Packed` storage layout, any message interacting with the contract storage will always need to operate on the entire contract storage struct.

For example, if we have a somewhat small contract storage struct consisting of only a few tiny fields, pulling everything from the storage inside every message is not problematic. It may even be advantageous - especially if we expect most messages to interact with most of the storage fields.

On the other hand, this can get problematic if we're storing a large `ink::prelude::vec::Vec` in the contract storage but provide messages that do not need to read and write from this `Vec`. In that scenario, each and every contract message bears runtime overhead by dealing with that `Vec`, regardless whether they access it or not. This results in extra gas costs. To solve this problem we need to turn our storage into a non-packed layout somehow.

<mark style="background-color:orange;">CAUTION</mark>

<mark style="background-color:orange;">If any type exhibiting</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`Packed`</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">layout gets large enough (an ever-growing</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`Vec`</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">might be a prime candidate for this), it will break your contract. This is because for encoding and decoding storage items, there is a buffer with only limited capacity (around 16KB in the default configuration) available. This means any contract trying to decode more than that will trap! If you are unsure about the potential size a data structure might get, consider using an ink!</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`Mapping`</mark><mark style="background-color:orange;">, which can store an arbitrary number of elements, instead.</mark>

### Eager Loading vs. Lazy Loading[​](https://use.ink/datastructures/storage-layout#eager-loading-vs-lazy-loading) <a href="#eager-loading-vs-lazy-loading" id="eager-loading-vs-lazy-loading"></a>

ink! provides means of breaking the storage up into smaller pieces, which can be loaded on demand, with the [`Lazy`](https://paritytech.github.io/ink/ink/storage/struct.Lazy.html) primitive. Wrapping any storage field inside a `Lazy` struct makes the storage struct in which that field appears also non-`Packed`, preventing it from being eagerly loaded during arbitrary storage operations:

<figure><img src="https://use.ink/img/storage-layout.svg" alt="" width="563"><figcaption></figcaption></figure>

Note that in above illustration, the key of `0x12345678` just serves as an example; we'll learn more about storage key calculation [later in this chapter](https://use.ink/datastructures/storage-layout#manual-vs-automatic-key-generation).

The following example demonstrates how we can solve the problem introduced in the above section. You'll notice that for the lazily loaded storage field, we now work with getters and setters to access and modify the underlying storage value:

```rust
#![cfg_attr(not(feature = "std"), no_std)]

#[ink::contract]
mod mycontract {
    use ink::prelude::vec::Vec;
    use ink::storage::Lazy;

    #[derive(Default)]
    #[ink(storage)]
    pub struct MyContract {
        tiny_value: Balance,
        /// This vector might get large and expensive to work with.
        /// We want to enforce a non-`Packed` storage layout.
        large_vec: Lazy<Vec<Balance>>,
    }

    impl MyContract {
        #[ink(constructor)]
        pub fn new() -> Self {
            Self::default()
        }

        /// Because `large_vec` is loaded lazily, this message is always cheap.
        #[ink(message)]
        pub fn get_balance(&self) -> Balance {
            self.tiny_value
        }

        /// Lazy fields like `large_vec` provide `get()` and `set()` storage operators.
        #[ink(message)]
        pub fn add_balance(&mut self, value: Balance) {
            let mut balances = self.large_vec.get_or_default();
            balances.push(value);
            self.large_vec.set(&balances);
        }
    }
}
```

<mark style="background-color:orange;">CAUTION</mark>

<mark style="background-color:orange;">`ink::prelude::vec::Vec`</mark><mark style="background-color:orange;">'s are always loaded in their entirety. This is because all elements of the</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`ink::prelude::vec::Vec`</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">live under a single storage key. Wrapping the</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`ink::prelude::vec::Vec`</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">inside</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`Lazy`</mark><mark style="background-color:orange;">, like the provided example above does, has no influence on its inner layout. If you are dealing with large or sparse arrays on contract storage, consider using a</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">`Mapping`</mark> <mark style="background-color:orange;"></mark><mark style="background-color:orange;">instead.</mark>

### ustustManual vs. Automatic Key Generation[​](https://use.ink/datastructures/storage-layout#manual-vs-automatic-key-generation) <a href="#manual-vs-automatic-key-generation" id="manual-vs-automatic-key-generation"></a>

By default, keys are calculated automatically for you, thanks to the [`AutoKey`](https://docs.rs/ink_storage_traits/4.0.0/ink_storage_traits/struct.AutoKey.html) primitive. They'll be generated at compile time and ruled out for conflicts. However, for non-`Packed` types like `Lazy` or the `Mapping`, the [`ManualKey`](https://docs.rs/ink_storage_traits/4.0.0/ink_storage_traits/struct.ManualKey.html) primitive allows manual control over the storage key of a field like so:

```rust
#[ink(storage)]
pub struct MyContract {
    /// The storage key for this field is always `0x0000007f`
    inner: Lazy<bool, ManualKey<127>>,
}
```

This may be advantageous: Your storage key will always stay the same, regardless of the version of your contract or ink! itself (note that the key calculation algorithm may change with future ink! versions).

<mark style="background-color:green;">TIP</mark>

<mark style="background-color:green;">Using</mark> <mark style="background-color:green;"></mark><mark style="background-color:green;">`ManualKey`</mark> <mark style="background-color:green;"></mark><mark style="background-color:green;">instead of</mark> <mark style="background-color:green;"></mark><mark style="background-color:green;">`AutoKey`</mark> <mark style="background-color:green;"></mark><mark style="background-color:green;">might be especially desirable for upgradable contracts, as using</mark> <mark style="background-color:green;"></mark><mark style="background-color:green;">`AutoKey`</mark> <mark style="background-color:green;"></mark><mark style="background-color:green;">might result in a different storage key for the same field in a newer version of the contract. This may break your contract after an upgrade 😱!</mark>

The storage key of the contracts root storage struct defaults to `0x00000000`. However, contract developers can set the key to an arbitrary 4 bytes value by providing it a `ManualKey` like so:

```rust
/// Manually set the root storage key of `MyContract` to be `0xcafebabe`.
#[ink(storage)]
pub struct MyContract<KEY: StorageKey = ManualKey<0xcafebabe>> {
    value: bool,
}
```

### Considerations[​](https://use.ink/datastructures/storage-layout#considerations) <a href="#considerations" id="considerations"></a>

It might be worthwhile to think about the desired storage layout of your contract. While using a `Packed` layout will keep your contracts overall code size smaller, it can cause unnecessarily high gas costs. Thus, we consider it a good practice to break up large or complex storage layouts into reasonably sized distinct storage cells.

<mark style="background-color:purple;">NOTE</mark>

<mark style="background-color:purple;">ink!</mark> <mark style="background-color:purple;"></mark><mark style="background-color:purple;">`Mapping`</mark><mark style="background-color:purple;">s are always non-</mark><mark style="background-color:purple;">`Packed`</mark> <mark style="background-color:purple;"></mark><mark style="background-color:purple;">and loaded lazily, one key-value pair at the time.</mark>

\
