TLDR:
- Solana transactions are capped at 1232 bytes, which limits the number of accounts a single transaction can reference.
- Address lookup tables (ALTs) let you store frequently used addresses on-chain and reference them by index instead of including the full 32-byte public key in every transaction.
- With ALTs, a versioned transaction (v0) can reference up to 256 accounts per table—enough for complex DeFi interactions, Jupiter swaps, and multi-program calls.
- This guide walks you through creating a lookup table, adding addresses, and using it in a versioned transaction.
Why you need address lookup tables
Every Solana transaction has a hard 1232-byte size limit. Each account address takes 32 bytes, so a transaction with ~30 accounts already exhausts most of the budget before adding instructions. You will hit this limit when:
- Performing Jupiter or Raydium swaps that route through multiple pools
- Building multi-instruction transactions (swap + transfer + memo)
- Interacting with programs that require many accounts (Serum/OpenBook order books, Meteora DLMM)
The error looks like:
Address lookup tables solve this by storing addresses on-chain. Instead of embedding the full 32-byte key, the transaction references a table address and a 1-byte index—saving 31 bytes per account.
Get your own node endpoint today
Start for free and get your app to production levels immediately. No credit card required.You can sign up with your GitHub, X, Google, or Microsoft account.
Prerequisites
- A Chainstack Solana node endpoint. Deploy one.
- Node.js 18+
- A funded Solana wallet (creating a lookup table costs ~0.003 SOL in rent)
Project setup
Add your credentials to .env:
Create a lookup table
A lookup table is an on-chain account that holds a list of public keys. You create one with createLookupTable, which returns the table address and a creation instruction.
Run with:
Extend the lookup table
After creation, add the addresses you need to reference in your transactions. You can add up to 30 addresses per extendLookupTable instruction (limited by transaction size), and a table can hold up to 256 entries total.
After extending a lookup table, you must wait for the next slot before using it in a transaction. The newly added addresses are not available in the same slot they were added.
Use the lookup table in a transaction
Once the table is populated, pass it as an address lookup table when compiling your versioned transaction message. The runtime resolves the indices at execution time.
The critical line is .compileToV0Message([lookupTableAccount]) — this tells the runtime to resolve account references from the lookup table instead of embedding full public keys.
When to use address lookup tables
If you use the same set of accounts repeatedly (e.g., the same token pair, the same DEX pool), create the lookup table once and reuse it across all your transactions. The table persists on-chain until you explicitly close it.
Additional resources