Solana testnet vs devnet vs Surfpool: what you can and can’t do
Builder map of Solana’s test environments: public testnet, public devnet, and local Surfpool (mainnet-fork). What each is for, what works, what breaks, and when to use which.
devrels.xyz/a/204short linkSolana test environments: builders keep mixing up testnet, devnet, and local tools like Surfpool. Same runtime family, totally different jobs. This piece is the what you can and can’t do map — not another “three clusters” intro alone (see the companion clusters + faucet guide).
Three different machines
| Testnet | Devnet | Surfpool (local) | |
|---|---|---|---|
| What it is | Public cluster for core/validator soak | Public cluster for app developers | Local drop-in for solana-test-validator with mainnet fork + cheatcodes |
| Who it is for | Anza/core, validators, release stress | Almost every dApp team | Integration tests, mainnet-shaped local sims |
| RPC (typical) | https://api.testnet.solana.com | https://api.devnet.solana.com | http://localhost:8899 |
| Tokens | Not real; faucet exists | Not real; faucet + Circle devnet USDC | Synthetic; set any balance via cheatcodes |
| Mainnet state | No | No (separate genesis / programs) | Yes — clone accounts/programs JIT from mainnet |
| Stability | Can lag/break/reset more often | More stable for apps; still can reset | Your laptop; you control resets |
Official cluster roles (Anza): application developers should target Devnet; Testnet is where core contributors stress new releases and validator behavior. Surfpool lives in the Solana Foundation org (solana-foundation/surfpool) as the modern local path when plain solana-test-validator is not enough.
What you CAN do
| Task | Testnet | Devnet | Surfpool |
|---|---|---|---|
| Deploy a program with Anchor / native / Pinocchio | Yes | Yes (default) | Yes |
| Share a public RPC URL with a teammate or QA | Yes | Yes | No (unless you tunnel it) |
| Airdrop SOL from a public faucet | Yes | Yes (e.g. devnetfaucet.org) | N/A — mint local SOL / any token |
| Get test USDC without deploying a mint | Limited / DIY | Yes (Circle devnet faucet) | Yes — set ATA balances via cheatcodes |
| Call real mainnet program IDs with mainnet account data | No | No | Yes (fork/clone) |
| Time-travel, force balances, reset chain state | No | No | Yes (surfnet cheatcodes) |
| Stress a new validator / Agave release | Yes (primary job) | Secondary | No (not a public stake network) |
| Run CI without external RPC dependency | Fragile | Possible but flaky/rate-limited | Yes |
| Wallet UX testing (Phantom/Solflare cluster switch) | Yes | Yes | Yes (custom RPC → localhost) |
What you CAN’T do (or shouldn’t)
| Don’t expect… | Testnet | Devnet | Surfpool |
|---|---|---|---|
| Real economic security / real SOL value | Can’t | Can’t | Can’t |
| Balances or PDAs to transfer across clusters | Can’t | Can’t | Local only — never equals mainnet custody |
| “Test my consumer app” as the primary mission | Wrong tool (validators/core first) | Right tool | Right for deep integration, not shared beta users |
| Stable long-lived public state forever | Resets / churn | Can reset | You wipe it anytime |
| Mainnet Jupiter/Raydium liquidity without forks | Can’t | Can’t (different deployments) | Can clone; still not live mainnet orderflow |
| Production secrets / mainnet keys in the environment | Don’t | Don’t | Don’t — local ≠ permission to use prod keys |
| Replace audits or mainnet canaries | Can’t | Can’t | Can’t |
Testnet — can / can’t in practice
Can: point a validator or release candidate at a live public network that often runs newer software than mainnet/devnet; exercise gossip, catchup, and performance under load; use a faucet for non-real SOL if you must send txs.
Can’t / shouldn’t: treat it as your product QA environment. APIs, NFT stacks, and “the program everyone deploys” are not guaranteed to match mainnet the way builders assume. If your bug is “does my Anchor program instruction work with wallet X,” you wanted devnet or Surfpool.
solana config set --url https://api.testnet.solana.com
solana airdrop 2 # if faucet allows; not for app ship cyclesDevnet — can / can’t in practice
Can: deploy programs, mint tokens, wire wallets, share explorer links, run staging backends against a public cluster, grab free SOL and (via Circle) free devnet USDC. Same ed25519 addresses as mainnet — different account data.
Can’t: read mainnet oracle prices, mainnet pool vaults, or mainnet NFT collections as if they were local. Program IDs you care about on mainnet may differ or be absent. Public RPC rate limits and congestion are real. Ledger resets are rare-ish but not impossible — don’t store irreplaceable state only on devnet.
solana config set --url https://api.devnet.solana.com
# SOL: public faucets (e.g. devnetfaucet.org)
# USDC: faucet.circle.com (devnet mint ≠ mainnet mint)Surfpool — can / can’t in practice
Surfpool is a local mainnet-aware simulator: drop-in for many workflows that used solana-test-validator, with just-in-time mainnet account fetch, RPC cheatcodes, optional studio/TUI, and IaC hooks. Details and install: Surfpool deep-dive · v1.4 notes · surfpool.run.
Can: clone mainnet accounts and programs; set SOL/token balances; time-travel / reset; run integration tests against “real” program layouts without spending mainnet SOL; keep CI offline once warmed.
Can’t: create real mainnet effects; reproduce live MEV/Jito tips and congested blockspace perfectly; replace multi-user public staging; guarantee every mainnet dependency is cloneable without work (some sysvars/services still need stubs). Teammates don’t see your localhost unless you expose it.
curl -sL https://run.surfpool.run/ | bash
surfpool start
# RPC http://localhost:8899
# Cheatcodes e.g. surfnet_setAccount / surfnet_setTokenBalance / surfnet_timeTravelDecision guide
| If you need… | Use |
|---|---|
| A shared staging URL for wallets and PMs | Devnet |
| Mainnet program layouts / vaults without mainnet keys | Surfpool |
| Deterministic unit/integration tests in CI | Surfpool (or LiteSVM for pure unit — LiteSVM) |
| Validator client / release soak | Testnet |
| Production users and real settlement | Mainnet only |
Common footguns
- “I’ll test on testnet” — on Solana that phrase usually means the wrong public cluster for apps.
- Wrong explorer cluster — tx signature “not found” because Phantom was on mainnet and CLI on devnet.
- Assuming devnet USDC mint = mainnet USDC — different mints; hardcode the right one per cluster.
- Surfpool success ≠ mainnet readiness — still need mainnet canaries, monitoring, and real fee markets.
- Shipping with testnet RPC in prod config — silent rejects; always pin cluster in env, not vibes.
Resources
- Anza — available clusters
- Surfpool · GitHub · docs
- Devnet / testnet / mainnet + faucets · Surfpool mainnet fork · LiteSVM
Bottom line
Testnet = public soak for the network itself. Devnet = public playground for your app. Surfpool = private mainnet-shaped lab with cheatcodes. Can deploy and send fake value on all three; can’t get real settlement or true mainnet risk anywhere but mainnet. Match the environment to the question you’re asking — most “testnet” tickets from app teams should have been devnet or Surfpool.
Keep reading
v1.4.0 is the Jito-aware update: simulateBundle lets you test bundle execution locally before touching mainnet. Also new: slotUpdatesSubscribe WebSocket subscription, sysvar/feature-gate filters on snapshot export, and four bug fixes including correct memo and block_time in getSignaturesForAddress.
Drop-in alternative to solana-test-validator. Fork Mainnet state on demand, set any account or token balance via RPC cheatcodes, deploy via Infrastructure-as-Code, watch it in a real-time dashboard.
Bonfida built the rails; SNS is the identity product. Here is the arc from name PDAs to community token and Web2 bridges — and what matters for integrators.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
