# Two questions about canister storage

**URL:** <https://forum.dfinity.org/t/two-questions-about-canister-storage/7776>\
**Category:** Developers\
**Created:** [October 8, 2021, 6:12pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776 "2021-10-08T18:12:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![HelloRickey](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/hellorickey/32/2020_2.png) [@HelloRickey](https://forum.dfinity.org/u/HelloRickey)\
**Post date:** [October 8, 2021, 6:12pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/1 "2021-10-08T18:12:39Z")

</div>

Hi guys, can you answer these questions.thanks.

1. What is the current maximum storage of canister? 4GB or 8GB?

2. How can I query the storage that the canister has now used?

---

<div class="post-metadata">

**Author:** ![Safik](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/safik/32/953_2.png) [@Safik](https://forum.dfinity.org/u/Safik)\
**Post date:** [October 8, 2021, 7:27pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/2 "2021-10-08T19:27:51Z")

</div>

Hi Rickey.  
With almost every release, the size increases in DFX 0.8.1 4 GB in DFX 0.7.2, it is better to set it to 2 GB. The canister, like the actor, is the storage, you need an ID. Next, knowing the ID canister = actor(text\_canister\_id). That is, you have to implement the storage of identifiers somewhere

---

<div class="post-metadata">

**Author:** ![diegop](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/diegop/32/569_2.png) [@diegop](https://forum.dfinity.org/u/diegop)\
**Post date:** [October 8, 2021, 11:04pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/3 "2021-10-08T23:04:30Z")

</div>

The _stable memory_ of a canister is 8 GB (used to be 4 GB). The Wasm heap is still limited to 4 GB.

I will post an example to denote why I emphasized stable memory:

- Storing a 6 GB video - very possible
- Declaring a 6 GB Motoko Array that is thrown away after execution - not possible

Think about the Wasm heap as the “RAM memory” accessible to a normal program and the stable memory as the “disk” and this is close enough. You can have 6GiB on the “disk”, but not all of it in “RAM” at the same time.

---

<div class="post-metadata">

**Author:** ![C-B-Elite](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/c-b-elite/32/34356_2.png) [@C-B-Elite](https://forum.dfinity.org/u/C-B-Elite)\
**Post date:** [October 9, 2021, 6:54am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/4 "2021-10-09T06:54:44Z")

</div>

Second question:  
You can use the functions of Prim.mo to get the memory has used:

```auto
Prim.rts_memory_size() -> Nat : the maximum memory has been used
Prim.rts_heap_size() -> Nat : wasm(canister) heap size at present

```

---

<div class="post-metadata">

**Author:** ![HelloRickey](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/hellorickey/32/2020_2.png) [@HelloRickey](https://forum.dfinity.org/u/HelloRickey)\
**Post date:** [October 9, 2021, 9:32am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/5 "2021-10-09T09:32:03Z")

</div>

Hi @diegop thank you for your detailed answer.  
For example, I have a userMap now. When I upgrade canister, it will run preupgrade and postupgrade. If the data stored in my userMap is larger than 4GB, my upgrade will fail. Is that right?

```auto
var userMap = HashMap.HashMap<Text, User>(1, isEq, Text.hash); 

stable var userEntries : [(Text, User)] = [];

system func preupgrade() {
  userEntries := Iter.toArray(userMap.entries());
};

system func postupgrade() {
  userMap := HashMap.fromIter<Text, User>(userEntries.vals(), 1, isEq, Text.hash);
  userEntries := [];
};

```

---

<div class="post-metadata">

**Author:** ![chenyan](https://avatars.discourse-cdn.com/v4/letter/c/35a633/32.png) [@chenyan](https://forum.dfinity.org/u/chenyan)\
**Post date:** [October 11, 2021, 5:08pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/6 "2021-10-11T17:08:36Z")

</div>

Correct. `userMap` is not in the stable memory, so it can never be larger than 4GB. You can use `TrieMap` and define it as `stable`. This way you store more than 4GB and you don’t need the pre/post upgrade hooks, because the map is already in the stable memory, and it will persist across upgrades.

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [October 11, 2021, 7:56pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/7 "2021-10-11T19:56:59Z")

</div>

@chenyan, no, actually, stable variables live in regular memory, too, so can’t take up more than 4 GiB either. They just happen to be saved to stable memory during an upgrade.

We are working on providing a Motoko API for direct access to stable memory. Until that is available, Motoko cannot make use of the larger stable memory.

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [October 11, 2021, 8:06pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/8 "2021-10-11T20:06:41Z")

</div>

Also note that Motoko internally uses the pre and post upgrade hooks to do this copying, and you will very likely hit the cycle limit of that long before you hit the storage limit. I’m actually surprised this hasn’t bitten anyone more seriously so far…

---

<div class="post-metadata">

**Author:** ![diegop](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/diegop/32/569_2.png) [@diegop](https://forum.dfinity.org/u/diegop)\
**Post date:** [October 11, 2021, 11:50pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/9 "2021-10-11T23:50:37Z")

</div>

> [@diegop](#):
>
> The _stable memory_ of a canister is 8 GB (used to be 4 GB). The Wasm heap is still limited to 4 GB.
> 
> I will post an example to denote why I emphasized stable memory:
> 
> - Storing a 6 GB video - very possible
> - Declaring a 6 GB Motoko Array that is thrown away after execution - not possible

@rossberg it sounds like my original answer is accurate but potentially misleading because Motoko cannot yet take advantage of the stable memory. I have seen demos of access stable memory, so I assume those are all in Rust? Is that a more helpful description I can give for the future?

---

<div class="post-metadata">

**Author:** ![HelloRickey](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/hellorickey/32/2020_2.png) [@HelloRickey](https://forum.dfinity.org/u/HelloRickey)\
**Post date:** [October 12, 2021, 2:41am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/10 "2021-10-12T02:41:39Z")

</div>

OMG, if I have used userMap to store a lot of user data, and this data is still increasing, how can I upgrade?

---

<div class="post-metadata">

**Author:** ![HelloRickey](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/hellorickey/32/2020_2.png) [@HelloRickey](https://forum.dfinity.org/u/HelloRickey)\
**Post date:** [October 12, 2021, 3:19am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/11 "2021-10-12T03:19:52Z")

</div>

Hey rossberg, if I use TrieMap to replace HashMap, my userMap will have 8GB of stable storage, so I don’t need to use `preupgrade` and `postupgrade` to upgrade, so it won’t exceed the 4GB limit of Wasm heap, right?

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [October 12, 2021, 7:04am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/12 "2021-10-12T07:04:34Z")

</div>

@diegop, yes, your answer is correct. Plus what @nomeata said.

As for an outlook, I would say: We are working on adopting the IC’s new 64 bit stable memory and providing a Motoko API (almost done 😉 ) for direct, unlimited access to stable memory. With that, it will be possible to design and implement stable data structures that avoid copying for upgrades. But until that is released, Motoko cannot make use of large memory.

@HelloRickey, unfortunately no. As I said, stable vars still live in regular Wasm memory. The only advantage you get is that you will not need to write pre/postupgrade hooks, because the Motoko compiler does that for you. To actually use unlimited stable memory, you’ll need the upcoming API that I just mentioned – or a new library implementing a map on top of that.

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [October 12, 2021, 12:38pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/13 "2021-10-12T12:38:01Z")

</div>

@rossberg, what are the chances to get stable-memory-backed values that are _not_ in the main memory in between messages? I.e. that if one defines `stable var myState = …` that the data therein is backed by stable memory, and read on demand?

I know it’s not trivial (some form of fat pointers; generated code might have to dynamically handle objects in either place etc; a garbage collector for the main memory), but probably doable, and ultimately I think maybe the only way forward? (The current scheme doesn’t scale; raw memory access is too low level for the Motoko target audience)

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [October 12, 2021, 3:48pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/14 "2021-10-12T15:48:22Z")

</div>

@nomeata, the idea is that the raw memory API enables us (or inspired devs) to implement things like that as a library abstraction, in Motoko itself. I agree that most users wouldn’t want to go there themselves.

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [October 12, 2021, 5:39pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/15 "2021-10-12T17:39:25Z")

</div>

If it works as a library abstraction, sure. But really transparent support, where any (shared) data can live here or there, and GC takes care of it, probably needs to be built in.

Or put differently: can we achieve the current _semantics_ of the `stable` annotation with an implementation that scales (in particular no use of the dangerous `pre_upgrade` hook, and in general per-message cycle consumption that depends on the work done, independent of the total size of data)?

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [November 6, 2021, 6:58pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/16 "2021-11-06T18:58:47Z")

</div>

When will 8 GB become 300 GB?

My understanding is that the proposal that passed was to increase stable memory to 300 GB, and that 8 GB was just a temporary stopgap.

---

<div class="post-metadata">

**Author:** ![diegop](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/diegop/32/569_2.png) [@diegop](https://forum.dfinity.org/u/diegop)\
**Post date:** [November 6, 2021, 7:17pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/17 "2021-11-06T19:17:53Z")

</div>

It definitely is intended to keep growing as issues and bottlenecks are identified and removed at each stage. I will let @akhilesh.singhania lend some more clarity

---

<div class="post-metadata">

**Author:** ![akhilesh.singhania](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/akhilesh.singhania/32/487_2.png) [@akhilesh.singhania](https://forum.dfinity.org/u/akhilesh.singhania)\
**Post date:** [November 8, 2021, 11:20am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/18 "2021-11-08T11:20:25Z")

</div>

Thanks for the ping @diegop .

@jzxchiang : after increasing to 8GiB, as expected, we uncovered some performance bottlenecks that the team is currently working on addressing. One of the key bottlenecks that we discovered is discussed in more detail in [Quick Fix for Smart Contract Memory Bottleneck | E007 - YouTube](https://www.youtube.com/watch?v=NWSeM8YgGv4). The work here is not completely done yet.

In general, the problem is that when canisters produce too large a heap delta, they put a lot of load on the node’s memory system. Previously this was slowing down the entire subnet. @abk then worked on an optimisation where we track the heap delta per canister. This allowed us to mitigate the problem so that we only slow down the offending canister. Next @ulan and Adam are working on a file backed PageMap allocator so that we can further reduce the load on the memory system.

Note that in tandem they are also working on the canister sandboxing feature so progress here is a bit slow. Once, their PageMap allocator work is done, barring any other critical performance bottlenecks are discovered, we should be in a good place to further increase the canister capacity.

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [November 8, 2021, 10:02pm UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/19 "2021-11-08T22:02:34Z")

</div>

Interesting, thanks for the response.

I’m curious how wasmtime handles heap deltas for linear 4 GB memory? Is a large heap delta not an issue there because wasmtime is smart about memory allocation or because 4 GB is not big enough where it’s a problem?

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [November 9, 2021, 7:27am UTC](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776/20 "2021-11-09T07:27:03Z")

</div>

@jzxchiang, maybe I misunderstand your question, but wasmtime is a plain Wasm engine and as such neither implements persistence nor consensus, so “heap deltas” are simply not a notion it has to bother computing.

[Next page](https://forum.dfinity.org/t/two-questions-about-canister-storage/7776.md?page=2)
