Associated Token Accounts (ATAs) are the backbone of token ownership on Solana. Every SPL token you've ever held lives in an ATA — a deterministic, per-wallet, per-token account that the protocol creates automatically. But when the token balance drops to zero, that account lingers on-chain holding your rent deposit hostage. This guide covers every method for closing ATAs: from the raw closeAccount instruction to CLI tools, programmatic approaches with web3.js, and automated bulk closure with SolRecover.
TL;DR: Closing an ATA requires calling the SPL Token Program's
closeAccountinstruction on a zero-balance account. You can do this via thespl-token closeCLI command, programmatically with@solana/spl-tokenin TypeScript, or automatically for all empty accounts using SolRecover.
What Are Associated Token Accounts?
An Associated Token Account is a token account whose address is deterministically derived from two inputs:
- Your wallet address (the owner)
- The token mint address (which token it holds)
The derivation uses a Program Derived Address (PDA) with seeds [wallet_pubkey, TOKEN_PROGRAM_ID, mint_pubkey], processed through the Associated Token Account Program. This means there's exactly one canonical ATA address for any given wallet-mint pair, and anyone can compute it without querying the chain.
ATAs are created automatically by most Solana dApps when you first interact with a token. The rent-exempt deposit of ~0.00204 SOL is deducted from your wallet (or sometimes paid by the dApp) and stored in the new account.
The ATA stores 165 bytes of data:
- Mint (32 bytes) — The token this account holds
- Owner (32 bytes) — Your wallet address
- Amount (8 bytes) — The token balance
- Delegate, state, close authority, and other fields — Remaining bytes
When the amount reaches zero, the account is closeable.
The closeAccount Instruction
At the protocol level, closing a token account is a single instruction to the SPL Token Program:
Instruction: CloseAccount
Accounts:
1. account — The token account to close (writable)
2. destination — Where to send the remaining lamports (writable)
3. owner — The account owner, must be a signer
When executed:
- The program verifies that the token balance is zero.
- The program verifies that the signer is the account owner (or the close authority, if one was set).
- All remaining lamports (the rent deposit) are transferred from the account to the destination.
- The account data is zeroed out and the account is marked for deallocation.
After the transaction confirms, the account no longer exists in the accounts database. The destination address — typically your wallet — receives the full rent deposit.
Method 1: Close via CLI (spl-token close)
If you have the Solana CLI tools installed, the spl-token command provides the simplest way to close individual accounts.
Close a specific token account by mint address:
spl-token close --owner <KEYPAIR_PATH> <TOKEN_MINT_ADDRESS>
This finds your ATA for the given mint and closes it, sending the lamports to your wallet.
Close a specific token account by account address:
spl-token close --owner <KEYPAIR_PATH> --address <ACCOUNT_ADDRESS>
Close all empty token accounts:
spl-token close --owner <KEYPAIR_PATH> --close-empty
The --close-empty flag scans all your token accounts, filters for zero-balance ones, and closes them. However, this sends individual transactions for each account rather than batching them, which can be slow if you have many accounts.
Important considerations:
- The
--ownerflag accepts a keypair file path or a hardware wallet path (e.g.,usb://ledger). - Each closure is a separate transaction with its own fee (~0.000005 SOL).
- The CLI doesn't support batching multiple closures into a single transaction.
- You need SOL in your wallet to pay transaction fees.
Method 2: Close Programmatically with TypeScript
For developers who want more control — or who need to batch closures — the @solana/spl-token library provides the building blocks.
Close a single account:
import { closeAccount } from "@solana/spl-token";
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const wallet = Keypair.fromSecretKey(/* your keypair */);
const tokenAccount = new PublicKey("AccountAddressHere...");
const signature = await closeAccount(
connection,
wallet, // payer for tx fee
tokenAccount, // account to close
wallet.publicKey, // destination for lamports
wallet // owner/signer
);
console.log("Closed:", signature);
Batch multiple closures in one transaction:
import {
createCloseAccountInstruction,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import {
Connection,
Keypair,
PublicKey,
Transaction,
} from "@solana/web3.js";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const wallet = Keypair.fromSecretKey(/* your keypair */);
// Array of empty token account addresses to close
const emptyAccounts: PublicKey[] = [
new PublicKey("Account1..."),
new PublicKey("Account2..."),
new PublicKey("Account3..."),
// ... up to ~20 per transaction
];
const tx = new Transaction();
for (const account of emptyAccounts) {
tx.add(
createCloseAccountInstruction(
account, // account to close
wallet.publicKey, // destination
wallet.publicKey, // owner
[], // multisigners (empty for single owner)
TOKEN_PROGRAM_ID
)
);
}
const signature = await connection.sendTransaction(tx, [wallet]);
console.log("Batch closed:", signature);
Key constraint: A single Solana transaction has a size limit of 1,232 bytes. Each closeAccount instruction takes approximately 55 bytes. After accounting for the transaction header, signatures, and blockhash, you can fit roughly 20 close instructions per transaction. For wallets with more empty accounts, you need to split across multiple transactions.
For a more comprehensive programmatic approach including account discovery, see our developer's guide to wallet cleanup.
Method 3: Close with SolRecover (Non-Technical Users)
If you're not a developer and don't want to touch the CLI, SolRecover handles the entire process through a browser interface.
Close all your empty Associated Token Accounts without writing a single line of code. SolRecover finds, batches, and submits transactions for you — just connect and approve.
Close Your Empty AccountsHow SolRecover handles the technical details:
- Account discovery — Calls
getTokenAccountsByOwneron your wallet to retrieve all token accounts. - Filtering — Identifies accounts with zero token balance that are safe to close.
- Batching — Groups closeable accounts into transactions of up to 20 closures each.
- Transaction construction — Builds the transaction client-side in your browser, connecting directly to Helius RPC (a trusted Solana infrastructure provider) with no backend server. Your keys never leave your wallet.
- Signing — Sends the transaction to your wallet (Phantom, Solflare, Backpack, Ledger, or any Wallet Adapter compatible wallet) for your approval.
- Fee handling — SolRecover's 1.9% fee is deducted transparently from the recovered rent. You keep 98.1% of the SOL.
The entire process takes under a minute for most wallets. For a detailed walkthrough, see our step-by-step recovery guide.
Close Authority: A Special Case
Some token accounts have a close authority set — a different address that has permission to close the account. This is common in DeFi protocols where a program manages accounts on behalf of users.
If you encounter accounts you can't close, it may be because:
- A protocol set itself as the close authority (common in older DeFi contracts).
- The account has a non-zero delegate balance that needs to be revoked first.
- The account belongs to Token-2022 (the newer token program) which has additional extension data that must be handled.
SolRecover handles these edge cases automatically, skipping accounts that can't be closed and reporting them to you.
What Happens After Closing
After closing an ATA:
- The rent deposit (~0.00204 SOL) is transferred to your wallet.
- The account data is deallocated from on-chain storage.
- The account address effectively becomes vacant — but it's still deterministic.
If you later interact with the same token again (buy it on a DEX, receive it in a transfer), the ATA Program will create a new account at the same address. You'll pay a new rent deposit, but the address will be identical because it's derived from the same wallet-mint pair. Closing an account doesn't prevent you from using that token in the future.
This is why periodic cleanup is a healthy habit. Close your empty accounts, recover the SOL, and if you need any of those accounts again, they'll be re-created automatically. Read more about ongoing wallet maintenance to build this into your routine.
Whether you're a developer or an everyday user, SolRecover is the fastest way to close empty ATAs and recover your SOL. Works with any Solana wallet.
Recover Your SOL NowHow Recovery Tool Fees Compare
Fees vary dramatically across SOL recovery tools. Here's how they compare on a typical 30-account cleanup at SOL's January 2025 peak of $295 (0.0612 SOL / $18.06 USD recoverable):
| Tool | Fee | Cost on 30 Accounts (USD) | You Keep (USD) |
|---|---|---|---|
| SolRecover | 1.9% | $0.34 USD | $17.72 USD |
| PandaTool | 4.88% | $0.88 | $17.18 |
| ReclaimSOL | 5% | $0.90 | $17.16 |
| SlerfTools | 8% | $1.44 | $16.62 |
| RefundYourSOL | 15% (base) | $2.71 | $15.35 |
| SolRefunds | 20% | $3.61 | $14.45 |
| RentSolana | 20% | $3.61 | $14.45 |
Competitor fees last verified: March 12, 2026. With SolRecover, you pay just $0.34 USD on a 30-account cleanup — over 10x less than the $3.61 USD charged by 20% tools like SolRefunds or RentSolana. That's a $3.27 USD difference for the exact same operation. SolRecover also runs fully client-side (your browser connects directly to Helius RPC with no backend server), and offers a generous referral program where the referrer earns 1% while the platform keeps just 0.9%.
Frequently Asked Questions About Closing Associated Token Accounts on Solana
What is an Associated Token Account (ATA) on Solana?
An ATA is a token account with a deterministic address derived from your wallet address and the token's mint address. It's created by the Associated Token Account Program and is the standard way wallets hold SPL tokens.
Can I close a token account that still has a balance?
No. The closeAccount instruction will fail if the token account has a non-zero balance. You must transfer or burn all tokens before closing. SolRecover automatically filters for zero-balance accounts only.
What happens to my SOL when I close a token account?
The rent-exempt deposit (~0.00204 SOL) is transferred to the destination address you specify — typically your main wallet. The account data is then deallocated from on-chain storage.
Can I reopen a closed Associated Token Account?
Yes. If you interact with the same token again, the ATA Program will create a new account at the same deterministic address. You'll pay a new rent deposit, but the address will be identical.