Solana V1 transactions: more room, new budget rules
Solana transaction v1 raises the size cap from 1232 to 4096 bytes and moves compute budget into the message config. What breaks for readers and indexers, how to test locally, and when to send v1.
devrels.xyz/a/260short linkSolana V1 transactions: more room, new budget rules. Official write-up: Larger Transaction Sizes. Copy-paste examples: solana-foundation/transaction-v1-examples. Clear field explainer from @a_milz.
The short version
Solana is adding a new transaction message format — v1 — that can carry about 3× more bytes than today (roughly 1.2 KB → 4 KB). That is how you fit things like a full Token-2022 confidential transfer, fat multisigs, or other proof-heavy flows into a single atomic transaction instead of a multi-tx plan.
The catch is not only “bigger packets.” v1 also changes where compute budget lives. Priority fee and CU limits stop being normal instructions and become fields on the message itself. If your indexer still greps for the ComputeBudget program, v1 transactions will look like they have no fee settings — and they will not throw an error to warn you.
Legacy and v0 keep working. You only build v1 when you need it. You still have to teach every reader about v1 before the feature gate flips on a cluster you care about.
What actually changes
Two proposals show up in the docs: SIMD-0296 (raise the size cap) and SIMD-0385 (the v1 message format that carries the bigger body and the new config). On the wire, v1 messages use version prefix 0x81 (v0 used 0x80).
Budgets move like this:
- CU limit →
config.computeUnitLimit - Priority fee →
config.priorityFeeLamportsas a total in lamports (not micro-lamports per CU likeSetComputeUnitPrice) - Loaded accounts data size and heap size → matching config fields
Address lookup tables are a v0-only trick. v1 does not use ALTs. If your tx only works because of lookup tables, stay on v0 or redesign the account list — extra bytes do not mean unlimited accounts.
If you only read chain data (you still have homework)
This is the break that will wake people up at 3am. RPC treats maxSupportedTransactionVersion as a ceiling. Leave it at 0 and the node will refuse to return a v1 transaction. On getBlock, one v1 tx in the slot can fail the whole block response, not just that transaction.
Fix is boring and mandatory: pass maxSupportedTransactionVersion: 1 on getTransaction and getBlock (and anything equivalent in your SDK). Do it before mainnet activation, not after your dashboards go blank.
Large v1 payloads may also outgrow base58 JSON encoding. Prefer base64 where your stack allows — Cloakd and others flagged this on the public thread.
If you index fees and compute
Most fee dashboards and MEV tooling still walk instructions looking for ComputeBudget. On v1 that walk returns nothing useful. The numbers sit on config / transactionConfig.
Over Yellowstone gRPC there is no version ceiling flag. After activation, v1 just appears in the stream. Both v0 and v1 can look “versioned”; the real signal is whether config is present. Stale protobuf stubs that never learned field 7 (Message.config) will decode v1 as if the budget never existed — silent data loss. Bump clients (e.g. @triton-one/yellowstone-grpc 6+, yellowstone-grpc-proto 12.6+, geyser 15.1.1+) so config survives the hop.
When you compare “priority fee” across versions, normalize units. v0 is price × CU limit (including implicit limits when unset). v1 is already a total in lamports. The Foundation example repo ships helpers that do this so you do not invent three different formulas.
If you send transactions
Sending v1 is opt-in. Existing wallets and bots can keep producing legacy/v0 until they choose otherwise.
When you do opt in, set the important config fields yourself. An absent computeUnitLimit or loaded-accounts limit is zero, not “use the old 200k default.” Only heap size still falls back to a sensible default. Ship a v1 message with empty config and it will fail in ways that look like “network is broken” until you read the docs twice.
SDKs are growing version-aware setters. In kit, some helpers write ComputeBudget instructions on v0 and config fields on v1 automatically — but priority fee is the awkward one because the unit system changed. Use the total-lamports setter on v1; do not paste a per-CU price into the wrong API.
When v1 is worth it
Use v1 when the payload simply does not fit today: confidential transfers, large proof bundles, admin batches that currently need a planner. Skip v1 when you rely on ALTs for account compression, or when you only need a normal swap/transfer — v0 remains the default path for most app traffic.
Test before the gate flips
Mainnet activation is aimed around Agave 4.2 feature gates (schedule moves — check the upgrade page). Locally you can exercise v1 today with Anza CLI 4.2+ and the example suite:
# feature gate id
solana -u m feature status txv1aq4pp281K9um3tnPgkfX8UqtFT6wcVW3hNezGLL
# examples repo
git clone https://github.com/solana-foundation/transaction-v1-examples
cd transaction-v1-examples
just setup-solana && just setup && just demoRecommended floors called out by Foundation docs and the examples README: @solana/kit 8.0+, solana-* crates 4.2.x, solders 0.29+, Yellowstone stacks that know Message.config. web3.js and Go support are still catching up — check the upgrade matrix before you promise a client.
Practical checklist
- Every service that reads txs/blocks →
maxSupportedTransactionVersion: 1 - Every fee/CU indexer → read config on v1, keep ComputeBudget scan for legacy/v0
- Regenerate gRPC protos; confirm config is not stripped
- Only then decide if your product should send v1; set CU + data-size limits explicitly; no ALTs
- Run the official examples against a local validator and watch the gate on devnet/testnet/mainnet
People and links
| Link | Why |
|---|---|
| Upgrade page | Breaking changes, version matrix, activation status |
| transaction-v1-examples | Rust / TS / Python / Go samples |
| @a_milz thread | Builder-facing summary of the breakers |
Resources
Keep reading
Pubkey/sig Base58 that treats 32/64-byte hot paths as first-class — append, batch, and optional intern cache.
Hosted head-slot RPC without credit gimmicks — and a self-hostable path that shoots txs at N+1 leaders over QUIC/UDP.
The Bot API costs zero. The real bill is RPC, streaming, landing fees, hosting that never sleeps, and the engineering that keeps keys and uptime honest. Three budgets, line by line.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
