Storage: Quotas, Inboxes, and Economics

dregg provides computron-metered storage with anti-spam protection. Sovereign cells pay almost nothing (the federation stores only a 32-byte commitment). Hosted cells and inbox messages pay proportional to size and duration. Understanding storage economics helps you design applications that are sustainable and cost-efficient.

Storage Modes

ModeFederation StoresCostUse Case
Sovereign32-byte commitment onlyMinimal fixed feeDefault. You host your own state.
HostedFull cell statePer-byte-per-epoch rentWhen you want the federation to keep your state available.
Erasure-codedShards across nodesHalf per-byte rateData availability without full replication.

Storage Costs

OperationCost (computrons)Notes
Write (per byte, per epoch)1Ongoing cost for persistent state
Read (per byte)0.01Cheap reads encourage verification
MerkleQueue enqueue10 + message_sizeAnti-spam deposit (refunded on receipt)
Erasure shard (per byte, per epoch)0.5Redundancy at half price
Sovereign commitmentFixed (10/epoch)Regardless of actual state size

All costs are governance-adjustable per federation. The values above are devnet defaults.

Space Banks

Each federation maintains a total storage budget (e.g., 1 TiB). This is partitioned into space banks -- allocations that cells draw from.

# Check your space bank
dregg storage bank
# Output:
#   Bank: default
#   Allocation: 100 MiB
#   Used: 12.3 MiB
#   Available: 87.7 MiB
#   Cells: 45

When a bank is full, new writes queue until space is freed (via GC, cell migration, or governance increasing the allocation).

MerkleQueue Inboxes

Every cell has an inbox -- a Merkle-committed FIFO queue for pending messages. The inbox solves several problems:

Sender-Pays-Deposit Anti-Spam

Sending a message to a cell's inbox requires a deposit:

deposit = base_fee + (message_size * per_byte_rate) + (ttl_blocks * per_block_rate)

# Example: 1 KiB message with 1000-block TTL
# deposit = 100 + (1024 * 0.1) + (1000 * 1) = 1202.4 computrons

This makes inbox flooding expensive while keeping normal communication free (deposits are refunded when messages are read).

Offline Delivery

Messages persist in the inbox until the recipient processes them. No liveness requirement on the recipient. Combined with CapTP's sealed boxes, this enables fully offline capability delegation.

Inspecting Your Inbox

# Check inbox status
dregg storage inbox
# Output:
#   Pending messages: 3
#   Total size: 4.2 KiB
#   Oldest message: 45 blocks ago
#   Deposits held: 1500 computrons

# Process inbox messages
dregg storage inbox process --all

# Drop expired messages (reclaim space)
dregg storage inbox gc

Storage Rent and Lifecycle

Hosted cells pay storage rent at epoch boundaries:

rent_per_epoch = state_size_bytes * rent_rate_per_byte

If your balance is insufficient to pay rent, the cell enters Decay:

# Check rent status
dregg storage status
# Output:
#   Mode: hosted
#   State size: 45 KiB
#   Rent: 45 computrons/epoch
#   Balance: 12000 computrons
#   Runway: ~266 epochs

# Switch to sovereign to stop paying rent
dregg cell sovereign --cell $CELL_ID
# Now the federation stores only your 32-byte commitment (10 computrons/epoch)

Erasure Coding

For data availability without full replication, enable erasure coding. Your state is split into n shards, any k of which can reconstruct the full state.

# Enable erasure coding (7 shards, need any 4 to reconstruct)
dregg storage erasure enable --cell $CELL_ID --shards 7 --threshold 4

# Check shard health
dregg storage erasure status --cell $CELL_ID
# Output:
#   Shards: 7/7 healthy
#   Threshold: 4
#   Cost: 0.5 computrons/byte/epoch (vs 1.0 for full hosting)
#   Last challenge: 12 blocks ago (all passed)

# Disable erasure coding (return to sovereign-only)
dregg storage erasure disable --cell $CELL_ID

Nodes periodically prove they still hold their shard via challenge-response (random leaf queries against the committed shard Merkle root). Failed challenges trigger shard redistribution.

SDK Storage Operations

use dregg_sdk::AgentCipherclerk;

let mut cclerk = AgentCipherclerk::new();

// Check storage status
let status = cclerk.storage_status().await?;
println!("Used: {} bytes, Rent: {} computrons/epoch", status.used, status.rent);

// Send a message to another cell's inbox
cclerk.send_inbox_message(
    &target_cell_id,
    &message_bytes,
    InboxOptions {
        ttl_blocks: 1000,
        // deposit is calculated automatically
    },
).await?;

// Process your own inbox
let messages = cclerk.process_inbox().await?;
for msg in messages {
    println!("From: {:?}, size: {}", msg.sender, msg.payload.len());
    // Deposit is refunded to sender automatically
}

Best Practices

Next Steps