Devnet to Mainnet Promotion
Promoting a Solana program and dApp from devnet to mainnet-beta is a staged gate process: each cluster has different economics, key material, and risk. Skipping a stage ships surprises at scale.
Recipe
Quick-reference recipe card - copy-paste ready.
anchor build --verifiable
anchor test
solana program deploy --url devnet target/deploy/my_program.so
# After checklist: deploy same .so hash to mainnet via multisigWhen to reach for this:
- First mainnet deploy after feature complete on devnet
- Migrating RPC or program ID between environments
- Launch week go/no-go review
- Auditor requests environment parity evidence
- Post-incident re-promotion of patched build
Working Example
#!/usr/bin/env bash
set -euo pipefail
PROGRAM_SO="target/deploy/vault.so"
DEVNET_HASH=$(solana-verify get-executable-hash "$PROGRAM_SO")
anchor deploy --provider.cluster devnet
echo "Devnet smoke..."
pnpm run smoke:devnet
echo "Hash for mainnet promotion: $DEVNET_HASH"
# Squads proposal attaches this hashWhat this demonstrates:
- Verifiable build hash recorded before mainnet
- Devnet deploy and smoke as hard gate
- Same artifact promoted - not rebuild on different machine
- Multisig proposal references executable hash
Deep Dive
Promotion Stages
| Stage | Cluster | Purpose |
|---|---|---|
| 1 | Surfpool / localnet | Fast CI, exploit replay |
| 2 | Devnet | Integration, airdrop testing |
| 3 | Mainnet-beta | Real economics and fees |
Environment Parity
- Program ID strategy: new keypair per env or same ID with upgrade path documented in ADR
.envfiles:RPC_URL,PROGRAM_ID,CLUSTERnever copied blindly between envs- Wallet keypairs: separate files; mainnet keys in HSM or Squads only
Gotchas
- Rebuilding on different machine - Bytecode differs; audit hash invalid. Fix: CI artifact promotion.
- Devnet airdrop reliance - Mainnet needs real SOL funding plan. Fix: Budget fee payer and deploy wallets.
- Same admin key on devnet and mainnet - Leaked dev key drains mainnet. Fix: Distinct key hierarchy.
- Skipping load test - Devnet empty; mainnet fees spike. Fix: Priority fee tests before launch.
- Frontend still points at devnet - Users sign wrong cluster. Fix: Build-time env validation.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Mainnet shadow deploy | Read-only canary | First ever deploy |
| Immutable skip devnet | Tiny throwaway demo | Any user funds |
| Feature-flagged mainnet | Gradual user exposure | Core logic untested |
FAQs
How long on devnet before mainnet?
Minimum one full sprint with integration tests; high-risk protocols add external audit.
Same program ID across clusters?
Usually different IDs per env; document mapping in ADR.
Who approves mainnet?
Tech lead + security + product; multisig signers for deploy.
What smoke tests run?
Top user flows simulate and send on devnet with CI wallet.
Devnet instability?
Use Surfpool 0.12.0 for CI; devnet for manual QA when needed.
How fund mainnet deploy?
Pre-funded ops wallet; alert below threshold.
IDL on mainnet?
Publish same IDL hash as verifiable build release.
Rollback plan?
Required in promotion ticket - link runbook.
Community launch timing?
Coordinate deploy, frontend, and comms in one change window.
Agave version match?
Validator and CLI align to 4.1.1 per manifest.
Related
- Program Upgrade Strategy - buffers and authority
- Delivery Best Practices - release gates
- Debugging Failed Transactions - post-promo triage
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.