DEV Community

Cover image for Anchor vs Pinocchio: the real deploy cost
Satori Geeks
Satori Geeks

Posted on

Anchor vs Pinocchio: the real deploy cost

The Solana mainnet deploy came in at $141. For a demo project. I stopped, recalculated, and stared at the number for a minute.

I'd built the tip jar in Anchor 0.32.1 — the standard framework, the one with real docs, the one everyone reaches for first. It worked. Seven integration tests passed. Then I checked the binary before committing 1.6 SOL to mainnet: 230 KB.

Three options, one decision

On Solana, accounts need to hold enough SOL to cover two years of rent to become rent-exempt, otherwise the runtime can garbage-collect them. For a program account, that's about 6,960 lamports per byte. At ~$86/SOL, 230 KB works out to ~1.64 SOL — $141.

You can close a Solana program later and reclaim that SOL to a recipient wallet. So it's not technically unrecoverable. But "recoverable in theory" doesn't change what you need in your wallet before you can deploy.

Option Binary size Approx. cost
Anchor 0.32.1, unoptimised 230 KB ~$141
Anchor + opt-level = "z", lto = true, strip = "symbols" ~90–100 KB ~$60
Pinocchio rewrite 15–20 KB (estimation) ~$9

Anchor with size flags was 15 minutes of work. Those flags strip symbols and merge compilation units — they don't touch Anchor's macro overhead. There's a floor, and $60 is still a lot for a demo. I went with Pinocchio.

What Pinocchio actually is

Pinocchio is a zero-dependency Rust framework for Solana programs. No macros, no IDL, no borsh. You write the discriminator logic, the account parsing, the PDA derivation — all of it.

Where Anchor's #[derive(Accounts)] generates validation from a handful of attributes with a lot happening out of sight, Pinocchio puts every check in explicit byte-offset reads. Nothing is invisible. The price for that is verbosity. The reason to pay it is binary size.

The rewrite

Four hours. Three instructions (initialize, send_support, withdraw) and three account types (MessageBoard PDA, Vault PDA, per-message Support PDA). I wrote the byte layout manually, encoded fields by hand, checked boundaries explicitly.

The 7/7 tests passed at the end. Worth noting: since Pinocchio generates no IDL, the TypeScript tests couldn't use Anchor's program.methods.sendSupport().rpc() style. Every instruction had to be built as a raw TransactionInstruction — manual Buffer.concat, explicit account list, correct discriminator byte. So the actual scope of the work was the Rust rewrite plus rewriting the test client from scratch.

Tests ran against a live solana-test-validator with the Pinocchio binary pre-loaded. No Anchor runner.

Binary: 30 KB. Above the 15–20 KB estimate — the manual validation boilerplate adds code that Anchor macros would have inlined. Still 87% smaller than the Anchor build.

Actual mainnet deploy: 0.214 SOL. ~$18. Within 1% of the rent calculation I'd done upfront.

Build Binary size Deploy cost
Anchor 0.32.1 230 KB ~$141 (never deployed to mainnet)
Pinocchio 0.9 — estimated ~15–20 KB ~$9
Pinocchio 0.9 — actual 30 KB $18

The rubric gap

My scoring rubric has a dimension for per-message transaction cost (D7) and one for deployment experience (D6). There's no dimension for the developer's one-time deploy cost.

On EVM weeks — Base, Scroll — this never came up. Both cost cents. On Solana, after the optimisation, it was $18. Before: $141. That's a real number with no rubric home. Worth flagging, because a methodology that doesn't measure something can't be honest about it.

Top comments (0)