Simple Program Execution
~2-4 MUs
- Base stack allocation: ~1-2 MUs
- Small local variables: ~1 MU
- Minimal event emission: ~1 MU
Compute Units (CUs) are Thru’s mechanism for metering computational work and preventing infinite loops or resource exhaustion attacks. Every smart contract execution consumes compute units, and transactions have a limited budget that must be specified upfront.
When you submit a transaction, you specify the maximum number of compute units your program is allowed to consume via the req_compute_units field. If your program exceeds this limit during execution, it will terminate with a TN_VM_SYSCALL_ERR_COMPUTE_UNITS_EXCEEDED error and all changes will be reverted.
The CU charge model is simple: 1 CU per byte of instruction or data processed. This means that the cost of an instruction is directly proportional to its size in bytes, and memory operations are charged based on the amount of data accessed.
Different types of operations consume different amounts of compute units:
The cost of an instruction is determined by its size:
This includes:
add, sub, mul, div)and, or, xor, shl, shr)beq, bne, jal, jalr)Examples:
add x1, x2, x3 # 4 CUs (32-bit instruction)c.add x1, x2 # 2 CUs (16-bit compressed instruction)Base Syscall Cost: 512 CUs
Every system call has a base cost of 512 compute units, representing the overhead of saving and restoring VM state (32 registers × 8 bytes × 2 operations).
Additional costs may apply based on the specific syscall operation:
See the syscalls documentation for detailed costs of each system call.
Memory Access: 1 CU per byte
The total cost for memory access instructions is the sum of the instruction’s base cost plus the cost for the bytes being accessed (1 CU per byte).
lb / sb (byte): 1 CUlh / sh (half-word): 2 CUslw / sw (word): 4 CUsld / sd (double-word): 8 CUsTotal Cost Example:
A standard lw (load word) instruction is 32-bits, so its base cost is 4 CUs. It also loads a 4-byte word from memory, which costs an additional 4 CUs.
lw instruction (4 CUs) + data access (4 CUs) = 8 CUs totalSimilarly, a standard sd (store double-word) instruction costs:
sd instruction (4 CUs) + data access (8 CUs) = 12 CUs totalPage Faults: 4,096 CUs
When your program accesses memory that hasn’t been allocated or loaded, a page fault occurs. Each page fault costs exactly 4,096 compute units (equal to the page size).
Memory Units (MUs) represent the scratch space allocation budget for your transaction. Each memory unit corresponds to 4,096 bytes (4KB) of memory that can be used for temporary storage during program execution.
When you submit a transaction, you specify the maximum number of memory units your program is allowed to consume via the req_memory_units field. Unlike compute units, memory units can be allocated and released during execution as your program’s memory needs change.
Memory units are consumed through various operations that require scratch space:
Growing Anonymous Segments
Examples:
# Allocating 8KB of stack space# Consumes 2 memory units (8KB ÷ 4KB = 2 MUs)Shrinking Anonymous Segments
Account Data Growth
Account Data Shrinkage
Account Data Access and Copy-on-Write (CoW)
CoW Memory Pattern:
// Example: Writing to account dataaccount_data[0] = 1; // First write to page 0: Consumes 1 MU (CoW)account_data[100] = 2; // Same page 0: No additional MUaccount_data[4096] = 3; // First write to page 1: Consumes 1 MU (CoW)Account Creation
Event Buffer Growth
Event Memory Pattern:
// Example: Emitting multiple eventsemit_event(small_event); // May not consume MU if fits in existing bufferemit_event(large_event); // Grows buffer, consumes additional MUsEstimate peak memory usage
Calculate the maximum simultaneous memory allocation your program will need. Consider all active segments, account growth, and event buffers at their peak.
// Conservative estimate for a complex operationlet memory_units = base_stack_pages + max_account_growth_pages + event_buffer_pages;Use memory efficiently
Handle allocation failures
Monitor available memory units before large allocations:
// Check available memory before growing segmentsif available_memory_units() < required_pages { return Err(ProgramError::InsufficientMemory);}Simple Program Execution
~2-4 MUs
Account Creation & Growth
Variable (depends on data size)
Heavy Event Emission
Variable (depends on event size)
Dynamic Memory Usage
Peak-based Charging