A Solana transaction can have valid instructions and still fail before
execution because its serialized message is too large. Versioned v0 messages
and Address Lookup Tables reduce the bytes spent repeating account addresses,
but they add onchain state, authority, compatibility, and indexing concerns.
This guide gives you seven production checks for deciding, constructing, and
operating v0 transactions with ALTs. It also separates today’s v0 behavior from
the announced v1 format so you do not design against an upgrade that has not
been verified active on your target cluster.
Read Solana transactions explained first
if message compilation, account keys, and atomic execution are unfamiliar.
Checks 1 and 2: prove the size need and ALT fit
Check 1: prove that message size is the constraint
Current Solana core documentation describes legacy and versioned v0 messages
under the 1232-byte transaction packet limit. Use v0 when a transaction needs
many accounts and approaches that limit. If the legacy message fits, it remains
simpler and has broader tooling support.
Serialize the exact signed transaction shape in tests. Count instructions,
signatures, static keys, instruction data, and ALT lookup metadata. Do not infer
size from the number of program instructions alone.
An ALT only compresses eligible account addresses in the message. It does not:
- reduce program compute
- remove writable-account contention
- make instruction data smaller
- turn multiple state transitions into one valid invariant
- guarantee wallet or indexer support
For compute, use the
Solana compute-unit guide. For
hot writable state, use the
account-locking guide.
Check 2: understand what an ALT changes
A v0 message can reference an ALT account and identify stored public keys by
1-byte index instead of including each 32-byte key inline. Current documentation
states a 31-byte saving per ALT-resolved account and up to 256 public keys stored
in one table.
Before execution, the validator resolves the indexes back to full public keys.
Those loaded accounts still have read-only or writable privileges and still
participate in account locking.
ALT-loaded accounts cannot be transaction signers. Fee payers, required
signatures, invoked program IDs, and other keys selected by the compiler remain
in the static message key set. If the oversized portion is mostly signatures or
instruction data, an ALT may not solve it.
Check 3: control the table lifecycle
Treat an ALT as production infrastructure, not an incidental client cache. Track:
- table address and target cluster
- authority and payer
- creation slot
- ordered address list and expected index
- applications and transaction families that depend on it
- extension, freeze, deactivation, and closure policy
Extending a table requires onchain transactions. The official guide notes that
large address sets need multiple extension transactions because each extension
must fit the transaction size limit.
Never discover table contents by trusting a local array. Fetch the account from
the target cluster and verify its authority, state, length, and ordered addresses
against your deployment manifest.
Check 4: compile and sign the v0 message correctly
The instructions themselves do not need an ALT-specific form. The client
provides fetched lookup-table accounts while compiling the v0 message:
import {
AddressLookupTableAccount,
TransactionInstruction,
TransactionMessage,
VersionedTransaction,
} from '@solana/web3.js';
export function buildV0Transaction(input: {
payer: PublicKey;
blockhash: string;
instructions: TransactionInstruction[];
lookupTables: AddressLookupTableAccount[];
}) {
const message = new TransactionMessage({
payerKey: input.payer,
recentBlockhash: input.blockhash,
instructions: input.instructions,
}).compileToV0Message(input.lookupTables);
return new VersionedTransaction(message);
}Sign the VersionedTransaction before sending. Verify that every expected signer
is present and that no required signer was incorrectly moved into an ALT.
After compilation, inspect static account keys and address-table lookups. A
successful TypeScript compile is not proof that the message references the table
or indexes you intended.
Check 5: simulate the final compiled transaction
Simulate the same message shape you plan to sign and send. Preserve:
- simulation context slot
- transaction error and logs
- loaded writable and read-only addresses
- inner instructions
- units consumed
- serialized transaction length
A missing or stale ALT can fail before the business instruction produces useful
logs. A correct lookup can still load a wrong account when the table manifest and
compiler inputs drift.
The five-layer transaction debugger helps
to map an instruction error through its CPI stack and account state.
Check 6: make RPC and indexer compatibility explicit
RPC consumers that fetch blocks or transactions should declare the maximum
transaction version they support. Versioned responses expose
addressTableLookups, while resolved keys appear as loaded addresses in
transaction metadata or parsed account entries.
Test every boundary that decodes or displays the transaction:
- wallet signing
- backend serialization
- simulation endpoint
- submission endpoint
- confirmation and transaction fetch
- indexer, webhook, and explorer
- support and incident tooling
Record the version, ALT addresses, loaded keys, RPC host, and signature in your
operation trace. When failures differ across RPC nodes or transaction metadata is
missing, RPC Edge is the relevant delivery and observation
boundary. RPC routing cannot correct a malformed message or wrong table index.
Check 7: prepare for v1 without assuming activation
As of July 22, 2026, Solana’s official upgrade page targets v1 transactions and
a 4096-byte maximum for Q3 2026, about 3.3x the current payload ceiling. The
same page says v1 does not support ALTs,
while current core documentation still identifies v0 as the supported version.
Treat v1 as an announced migration target until activation is verified on the
cluster, SDK, wallet, RPC, and indexer set you operate. Do not replace a working
v0 path based only on the target date.
The clean readiness plan is:
- keep transaction-format selection behind a typed capability boundary
- measure legacy, v0, and later v1 serialized sizes in fixtures
- avoid coupling business instructions to ALT administration
- record decoder support per wallet, RPC, and indexer
- run devnet and mainnet activation checks before enabling v1
- retain a supported fallback for transactions that fit older formats
Larger transactions also carry more bytes over the network. The announced
upgrade notes added reliability and buffer pressure, so 4096 bytes should be a
ceiling, not a target.
The v0 and ALT Production Gate
Before enabling a versioned transaction path:
- prove the legacy transaction exceeds or approaches the current size limit
- identify which non-signer keys will be compressed by the ALT
- verify the table address, authority, cluster, and ordered contents onchain
- compile the final v0 message and inspect static keys plus lookup indexes
- sign and simulate the exact message shape used for submission
- test wallet, RPC, confirmation, indexer, explorer, and support compatibility
- preserve version, table, loaded-key, size, and signature evidence
- document extension, freeze, deactivation, and closure ownership
- keep compute and account-contention reviews separate
- gate v1 behind verified cluster and toolchain support
The result should be a repeatable transaction fixture and a table manifest, not
an undocumented address pasted into frontend code.
FAQ, sources, and next step
Do ALTs reduce transaction compute?
Their main purpose is on-wire address compression. Loaded accounts and program
work still exist at execution time. Measure compute separately.
Can an ALT contain signer accounts?
The table can store public keys, but ALT-resolved accounts in a v0 message cannot
be transaction signers. Required signer keys must remain static.
Should every application use v0?
No. Legacy transactions are simpler when the complete message fits and all
required tooling supports them. Use v0 for a measured account-address size need.
Is v1 active on mainnet now?
This guide does not assume it. The official upgrade page lists a Q3 2026 target.
Verify activation and end-to-end wallet, RPC, and indexer support before enabling it.
Primary sources
- Solana versioned transactions
- Solana Address Lookup Tables guide
- Solana RPC JSON structures
- Solana larger transaction sizes and v1 roadmap
For submission, expiration, and safe retry behavior, continue with the
transaction reliability guide.
For a large transaction that crosses message design, wallet compatibility, and
RPC delivery, try a Builderz architecture review.



