Deploying Programs
Deploying a Solana program uploads BPF bytecode to a program data account via the upgradeable loader. Use Solana CLI 3.0.10 or anchor deploy after anchor build on Agave 4.1.1 clusters.
Recipe
Quick-reference recipe card - copy-paste ready.
anchor build
solana program deploy target/deploy/my_program.so \
--program-id target/deploy/my_program-keypair.json \
--url devnetWhen to reach for this:
- First devnet/mainnet deployment.
- Shipping audit-fixed bytecode.
- Resizing program data after large code changes.
- CI/CD automated releases.
Working Example
#!/usr/bin/env bash
set -euo pipefail
CLUSTER=devnet
PROGRAM_SO=target/deploy/my_program.so
PROGRAM_KEYPAIR=target/deploy/my_program-keypair.json
solana config set --url "$CLUSTER"
solana balance
# Build reproducible artifact
anchor build
# Estimate cost
solana program deploy "$PROGRAM_SO" --program-id "$PROGRAM_KEYPAIR" --dry-run
# Deploy
DEPLOY_OUT=$(solana program deploy "$PROGRAM_SO" --program-id "$PROGRAM_KEYPAIR")
echo "$DEPLOY_OUT"
PROGRAM_ID=$(solana-keygen pubkey "$PROGRAM_KEYPAIR")
solana program show "$PROGRAM_ID"What this demonstrates:
--dry-runpreviews rent and CU without landing.- Program ID comes from keypair pubkey matching
declare_id!. program showconfirms authority and data length post-deploy.
Deep Dive
How It Works
- CLI splits ELF into chunks written to buffer account.
- Deploy instruction copies buffer to program data account.
- Program account is executable proxy pointing at data account.
- Payer funds rent-exempt minimum for data account size.
Deploy Cost Drivers
| Factor | Impact |
|---|---|
.so file size | Rent proportional to bytes |
| Cluster | devnet cheaper SOL; mainnet real cost |
| Failed deploy | Buffer rent until closed |
| Priority fees | Landing speed during congestion |
bash Notes
# Close failed buffer to reclaim rent
solana program close <BUFFER_ADDRESS>Gotchas
- Program ID mismatch -
declare_id!!= keypair pubkey. Fix:anchor keys syncafter keygen. - Insufficient SOL - Rent + fees exceed balance. Fix:
solana program deploy --dry-runfirst. - Wrong cluster - Deploy to devnet, clients on mainnet. Fix:
solana config getbefore deploy. - Upgrade authority on hot wallet - Deployer key owns upgrades. Fix: Transfer to multisig immediately.
- Non-reproducible build - Hash differs from CI. Fix:
solana-verify buildpipeline. - Oversized program - Exceeds max deploy size. Fix: Strip debug, optimize, split logic across programs.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
anchor deploy | Anchor workspace | Raw native program only |
| Buffer resume | Large SO / flaky net | Tiny programs |
| Squads deploy proposal | Production governance | Solo devnet iteration |
FAQs
How much SOL does deploy cost?
Primarily rent for program data (~size of .so); use --dry-run for estimate on your cluster.
Can I change program ID later?
No - ID is keypair pubkey; changing ID is a new deployment and migration of state.
anchor build vs cargo build-sbf?
anchor build wraps cargo build-sbf and generates IDL - prefer for Anchor 0.32.1 projects.
What is the buffer account?
Temporary holding account for ELF chunks during multi-step deploy.
Deploy fails mid-way?
Partial buffer remains - close buffer or resume deploy from buffer address.
Same .so to multiple clusters?
Yes - deploy separately per cluster with cluster-specific program keypairs if needed.
CI deploy pattern?
Build in CI, deploy with secured key from secret manager, verify hash post-deploy.
Immutable on first deploy?
Possible by revoking authority immediately - rare; usually keep authority through audit period.
Program data address?
Separate account from program ID - program show lists ProgramData address holding ELF.
Agave 4.1.1 requirement?
Build with matching platform-tools so deployed ELF matches validator BPF loader expectations.
Related
- Deployment Basics - loader overview
- Program Upgrades - upgrading bytecode
- Verifiable Builds - hash verification
- Deployment Best Practices - release policy
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.