How to Recover Solana Rent From Empty Token Accounts
Every SPL token account locks ~0.00204 SOL as rent. Most active wallets hold 40–200 empty ones. Here's how to identify them and reclaim the SOL in a single signature.
Every time a Solana wallet interacts with a new token — a memecoin airdrop, a Jupiter swap, an NFT mint — the network creates an SPL token account to hold that balance. Creating that account requires a rent deposit of roughly 0.00204 SOL. The SOL isn't a fee; it's a refundable deposit that the network holds until the account is closed.
The problem: almost nothing closes these accounts automatically. Sell the token, transfer it out, or watch it go to zero, and the account stays open. The SOL stays locked. Over a year of ordinary on-chain activity, a typical trader accumulates 40 to 200 of these zero-balance accounts. That's 0.08 to 0.4 SOL sitting idle in your own wallet, invisible in every wallet UI that only shows non-zero balances.
How Solana rent actually works
Solana charges rent to make on-chain storage economically sustainable. Every account — token accounts, program accounts, PDAs — must hold enough SOL to cover two years of rent, which for a standard SPL token account works out to 2,039,280 lamports (0.00203928 SOL). If it holds at least that much, it's considered "rent-exempt" and is never charged.
Rent-exemption is the network's compromise between the ideal of periodically deleting inactive accounts (which would break every dApp that relies on state persistence) and the reality that storage costs validators real money. In practice, everyone pays the two-year deposit upfront and no account ever actually pays ongoing rent. The tradeoff is that the deposit sits with the network until the account is explicitly closed.
When an account is closed, the entire rent deposit is refunded to a destination wallet you specify. This is not a bug or a loophole — it's the intended behavior. The SOL is yours; the token account was just a temporary escrow.
Why wallets don't clean up automatically
There are two structural reasons no one closes accounts for you. First, no on-chain program has the authority to close accounts it doesn't own — only the account's owner (or the program that created it under a PDA) can sign the close instruction. Second, wallet UIs are optimized to show you tokens you have balances of, not tokens you don't. Phantom, Solflare, and Backpack all hide zero-balance token accounts by default. If you can't see them, you don't think about them.
That's the entire mechanism behind the problem. There is no bad actor. No fee that got taken. Just a two-sided information gap between what the network is storing and what your wallet is showing.
Finding your empty accounts
There are two paths: manual or automated. Manually, you can query the token program directly through any Solana RPC endpoint. Fetch all token accounts owned by your wallet, filter for amount === 0, and you have your list.
const accounts = await connection.getParsedTokenAccountsByOwner(
new PublicKey(walletAddress),
{ programId: TOKEN_PROGRAM_ID }
);
const empty = accounts.value.filter(
(a) => a.account.data.parsed.info.tokenAmount.uiAmount === 0
);Don't forget Token-2022 accounts, which live under a separate program ID (TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb). They follow the same rent rules but use a different close instruction and can carry extensions like transfer fees, permanent delegates, or non-transferability. The account layout is different enough that generic Token-2022 handling requires careful decoding — but the close semantics are identical.
Closing accounts safely
Each close is a single closeAccount instruction from the SPL token program. You can batch up to about 25 closes into a single transaction, depending on how many other instructions you're including. The owner of the account must sign, and the destination for the reclaimed rent is up to you — usually your own wallet.
Transaction size is the main constraint. Solana caps a transaction at 1,232 bytes, which leaves room for roughly 25 closeAccount instructions once you account for the signer, fee payer, and blockhash. If you have hundreds of empty accounts (some of the wallets we scan do), you'll need to split into multiple transactions. Every transaction costs about 5,000 lamports in network fees — a rounding error compared to the recovery.
What about dust?
Accounts with a small non-zero balance — a few lamports of a dead token, a fraction of a scam airdrop — can't be closed directly. You have two options: burn the balance first (a burn instruction), then close in the same transaction; or transfer the dust to a burn address. Burning is cleaner and reclaims the rent atomically.
A subtle point: burning requires knowing the token's mint authority, decimals, and program (SPL vs Token-2022). Getting any of those wrong makes the burn instruction fail and takes the close down with it. If you're building this yourself, batch burns and closes carefully and test each mint on devnet first.
Scam token accounts
One category deserves its own note: scam airdrops. If a wallet has been used for anything visible on-chain, it has probably received dozens of unsolicited token airdrops — often with balances of a few lamports of a token whose name is a phishing URL. These are safe to close using the same closeAccount instruction. Don't interact with the token itself (no transfers, no swaps), and never click through to the domain the token name is trying to advertise. Just burn and close.
Doing it in one click
If you'd rather not build the transactions yourself, WalletSweep scans your wallet, identifies every closable account (empty SPL, empty Token-2022, dust, plus stale OpenBook orders and forgotten vesting), and builds a single signed transaction. You keep 80% of the reclaim; we take a 20% cut only on success.
Either way, do it. Rent that stays locked is capital that isn't compounding.
Run the scan on your own wallet
WalletSweep finds every category above in one pass and closes them in a single signed transaction.
Scan my wallet