memory

작성자: convex-dev

메모리 회계 및 허용량 — 온체인 저장 비용, 그리고 이를 최소화하고 회수하는 방법. 상태 성장에 대해 추론하거나, 진단할 때 사용하세요…

npx skills add https://github.com/convex-dev/convex --skill memory

Memory Accounting

Memory prices storage. Unlike juice, it is a stock: held as an allowance, consumed when state grows, and refunded when state shrinks. Computation is priced separately — see the juice skill.

On-chain storage is potentially permanent, and every peer bears it. Memory accounting exists so that whoever creates that burden accounts for it.

Normative spec: https://docs.convex.world/docs/cad/memory.

Storage Size

storage size = 64 + (bytes of the cell's own encoding) + (memory size of child cells)

Two consequences worth internalising:

  • The 64-byte constant is per non-embedded cell. Cell count costs, not just bytes. A structure split across many small cells is far more expensive than the same data embedded.
  • Embedded cells have a memory size of zero. Their bytes are already inside the parent's encoding. Embedding is genuinely free storage — see the cad3-encoding skill for the 140-byte embedding limit.

Consumption

Measured per transaction, at the end:

Memory Consumption = state size at end − state size at start

When consumption is positive, resolved in this order:

  1. Deduct from the user's memory allowance, if sufficient.
  2. Otherwise buy from the memory pool, paying at most remaining juice × juice price. This is where memory and juice meet — a transaction can fail for memory because it spent its juice elsewhere.
  3. Otherwise fail with :MEMORY, roll back all state changes, and still charge the juice.

When consumption is negative, the allowance is refunded by the amount released. Freeing storage pays.

Minimise Allocation

Treat on-chain storage as the scarcest thing you are spending. In order of leverage:

  • Embed rather than branch. Small values inside a parent encoding cost nothing extra; each separate cell costs 64 bytes of overhead before its content.
  • Keep cell counts low. Prefer one compact structure over many small ones.
  • Store the minimum that satisfies the requirement. Derive what can be derived, and keep off-chain what does not need consensus. Storing a hash or a reference is usually enough when the payload itself need not be on-chain.
  • Do not store what a query can compute. On-chain caching of derived values trades permanent storage for transient compute — usually the wrong way round.
  • Actors should allocate sparingly when called by users. The caller pays for what your actor allocates, so a wasteful actor makes every interaction with it expensive. This is a competitive property, not just good manners.

Note that de-duplication does not help the allocating user: identical encodings are stored once network-wide, but you still pay allowance for what you allocate. Do not design around it.

Reclaim Aggressively

Every byte released is allowance refunded, so cleaning up is directly rewarded — for users and actors alike.

  • Delete data you no longer need. Definitions in your own account environment are yours to remove, and safe to remove if you hold backups — the data can always be restored later.
  • Give actors clean-up functions. A well-designed actor lets participants remove what is finished with: read messages, filled orders, zero-balance holder records, expired offers, de-registrations. Without such a function the storage is stranded permanently.
  • Expect callers to use them. The party who cleans up claims the refund, so clean-up paths get used. That is the intended incentive — a responder can come out ahead by tidying up after an interaction.
  • Give actors a way to reclaim their own allowance. Actors hold allowances but normally do not spend them: the transaction origin pays. The exception is scheduled execution, where the actor is itself the origin. An allowance that accumulates in an actor with no reclaim path is unreachable forever, and cannot be retrofitted without an upgrade.

Allowances may also be transferred directly between accounts, which is how actors and multi-account users manage them without allocate/deallocate tricks.

The Memory Pool

An automated market maker. Seeded at genesis with 1,000,000 bytes against 1,000 Convex Coins (~1 Coin/KB), and grown at a fixed rate (currently 1 MB per day).

Growth is deliberate: it avoids a hard supply ceiling and penalises hoarding, since new supply dilutes accumulated allowances.

Implementation Notes

Memory size is computed lazily and cached per cell; peers MUST cache it to meet performance requirements. Cells are immutable, so a cached size is never invalidated — that is what keeps accounting O(1) per allocated cell.

The accounting subsystem is designed to cause no net cell allocations itself, so it cannot drive the state growth it exists to control. Preserve that if you change it: update embedded fields on existing cells rather than allocating new ones.

convex-dev의 다른 스킬

convex-lisp
convex-dev
Convex Lisp 언어 참조 — CVM 규칙, 라이브러리 코드 호출, 액터 정의, juice 및 오류 코드. CVM 소스를 작성하거나 디버깅할 때 사용합니다…
ecosystem
convex-dev
Convex 생태계에서의 방향 안내 — 어떤 리포지토리에 무엇이 있는지, 사양과 문서가 어디에 있는지, 그리고 어떤 클라이언트 라이브러리가 존재하는지. 컨텍스트가 필요할 때 사용하세요…
local-network
convex-dev
로컬 Convex 테스트 네트워크를 개발용으로 실행합니다. 라이브 네트워크에 대한 변경 사항을 테스트하거나, 피어 문제를 재현하거나, 원격 네트워크가 없을 때 사용합니다.
protocol-versions
convex-dev
프로토콜 버전, 마이그레이션 및 v1 업그레이드 — 어떤 의미론을 기준으로 작성할지, 그리고 네트워크를 포크하지 않고 CVM 동작을 변경하는 방법. 다음 경우에 사용하세요…
etch
convex-dev
Etch 스토어를 검사하고 유지 관리합니다 — Convex의 콘텐츠 주소 지정 데이터베이스입니다. 피어 저장소를 검사하거나, 손상을 진단하거나, 가비지 컬렉션을 수행할 때 사용합니다.
juice
convex-dev
Juice 회계 — CVM에서의 연산 및 대역폭 비용. 트랜잭션 실행 비용을 추론하거나, :JUICE 실패를 진단하거나, …할 때 사용합니다.
trust
convex-dev
Trust 모니터 — Convex의 구성 가능한 온체인 인가 모델. 접근 제어 작성, 액터 함수 제한, 발행 권한 정의 시 사용합니다…
peer
convex-dev
Convex 피어를 운영합니다 — 네트워크 제네시스를 생성, 시작, 나열, 백업 또는 인스턴스화합니다. 네트워크에 대해 피어를 실행하거나 새 네트워크를 설정할 때 사용합니다.