Borsh Structs
Borsh structs are the workhorse for Solana account bodies. Design them for stable field order, explicit sizing, and forward-compatible versioning.
Recipe
#[derive(BorshSerialize, BorshDeserialize)]
pub struct User { pub authority: Pubkey, pub points: u64 }When to reach for this:
- Defining new account types.
- Calculating rent space.
- Planning schema upgrades.
Working Example
#[derive(BorshSerialize, BorshDeserialize)]
pub struct User {
pub authority: Pubkey,
pub points: u64,
pub bump: u8,
}
impl User {
pub const LEN: usize = 32 + 8 + 1;
}What this demonstrates:
- Field order is serialization order.
- LEN matches sum of fields.
- Bump stored for PDA signing.
Deep Dive
Sizing
Pubkey 32 + u64 8 + u8 1 = 41 bytes body.
Versioning
Append fields; migrate old accounts.
Rust Notes
// Option<Pubkey>: 1 + 32 bytesGotchas
- Reorder fields - Breaks all accounts.. Fix: Only append new fields.
- String without max - Unbounded rent.. Fix: Cap length or use fixed array.
- Enum in account - Variant changes risky.. Fix: Prefer u8 tag + struct.
- LEN wrong - Runtime failures.. Fix: Test serialize len.
- Missing padding awareness - Rare in Borsh - unlike C layouts.. Fix: Borsh is packed sequentially.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| bytemuck header + Borsh tail | Hybrid | Pure zero-copy |
| Multiple small accounts | Less realloc | More rent total |
| Account compression | Off-chain | On-chain raw bytes |
FAQs
Pubkey in struct?
32 bytes Borsh.
Vec sizing?
4 byte len + elements - variable rent.
bool size?
1 byte.
i64?
8 bytes LE.
Nested struct?
Supported - sums sizes.
Default trait?
Helps init on host.
MAX account?
10 MB theoretical.
Anchor InitSpace?
Derives space macro.
Schema hash?
Document in upgrades.
Flatten?
Single level preferred for clarity.
align?
Borsh ignores Rust align.
Fuzz deserialize?
Recommended.
Related
- Borsh Serialization - Format
- Space Calculation - Rent
- Data Versioning & Migration - Upgrades
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.