Memory and Persistence
A running Lyquid is a WASM module plus LyteMemory, the linear-memory layout behind Direct Memory Architecture (DMA). LyteMemory has three logical segments:
| Segment | Purpose | Lifetime | Visibility | Backing store |
|---|---|---|---|---|
| Volatile | Per-call scratch space and host I/O buffers | one call | current call frame | none |
| Network | deterministic persistent state | across calls and versions | all nodes at the same LyquidNumber | versioned state store |
| Instance | node-local persistent state | across calls | one node's Lyquid instance | simple state store |
The LDK exposes the layout boundaries as public constants:
| Constant | Value | Meaning |
|---|---|---|
LYTESTACK_BASE | 0x30000000 | stack base used by Lyquid calls |
LYTEMEM_BASE | 0x80000000 | base address of persistent LyteMemory |
NETWORK_MEMSIZE_IN_MB | 1024 | network segment size |
INSTANCE_MEMSIZE_IN_MB | 1024 | instance segment size |
VOLATILE_MEMSIZE_IN_MB | 1024 | volatile segment size |
The generated state! code routes each persistent allocation into the right segment (network or
instance) and keeps those objects at stable guest addresses for the lifetime of the Lyquid, so your
state behaves like ordinary long-lived Rust objects. You do not manage any of this directly — you
declare state in state! and use it as normal Rust values.
Practical consequences:
- persistent state behaves like normal Rust objects, but object address stability matters
- memory growth is disabled for LyteMemory, so the segment sizes above are hard limits
- network state is versioned through replay and dirty-page persistence
- instance state is shared across cached execution objects on a node
- an instance call at an older network version still sees current node-local instance state