Minting 1 million NFTs on Ethereum costs roughly $2–5 million in gas fees. On Solana without compression, you'd pay around $240,000 in rent costs. With compressed NFTs (cNFTs), that same million-NFT collection costs approximately $110.
That's not a typo. Compressed NFTs reduce minting costs by 99.9%+ compared to regular Solana NFTs, and by 99.999% compared to Ethereum. This isn't some experimental feature — cNFTs have been live on Solana mainnet since mid-2023, and hundreds of millions have been minted. Projects like DRiP, Helium, and Dialect use them in production at massive scale.
If you're building anything that requires issuing digital assets at scale — loyalty programs, gaming items, event tickets, digital collectibles, proof-of-attendance tokens — compressed NFTs are the only economically viable approach on any blockchain.
What Problem Do Compressed NFTs Solve?
To understand cNFTs, you need to understand why regular NFTs are expensive.
Every NFT on Solana is an account. Accounts consume on-chain storage, and Solana charges rent for that storage. A standard Metaplex NFT requires roughly 0.012 SOL in rent-exempt storage costs — that's the cost to keep the metadata and mint accounts alive on-chain forever.
At $150/SOL, that's $1.80 per NFT. Mint 10,000 NFTs for a PFP collection? That's $18,000 just in rent, before any transaction fees. Mint a million for a loyalty program? $1.8 million.
The cost scales linearly with the number of NFTs because each one is a separate on-chain account. This makes regular NFTs completely impractical for anything beyond small collections.
Compressed NFTs break this linear scaling by storing NFT data off-chain in a Merkle tree structure, with only a single hash (the tree root) stored on-chain.
How State Compression Works
State compression is the underlying technology. It's not specific to NFTs — it's a general Solana primitive that can compress any account data. Compressed NFTs are just the first (and most popular) application.
Here's the architecture:
Concurrent Merkle Trees
A Merkle tree is a data structure where every leaf node contains a hash of some data, and every parent node contains a hash of its children. The root hash at the top of the tree represents all the data in the tree — if any leaf changes, the root changes.
Solana stores only the root hash on-chain. The actual leaf data (NFT metadata) is stored off-chain by RPC providers and indexers. This is the key insight: instead of paying rent for N accounts, you pay rent for one account (the tree) regardless of how many NFTs it contains.
The "concurrent" part is important. Regular Merkle trees require sequential updates — you can't modify two leaves at the same time because each update changes the root. Concurrent Merkle trees allow multiple simultaneous updates by maintaining a changelog buffer. This is what makes cNFTs practical on a high-throughput chain like Solana.
The Cost Breakdown
A Merkle tree has two key parameters:
- Max depth: Determines the maximum number of leaves (NFTs). A depth of 20 supports 2^20 = ~1 million NFTs.
- Max buffer size: Determines how many concurrent updates can happen simultaneously. Higher = more parallel mints but more on-chain storage.
The on-chain cost is for creating the tree account (rent for the Merkle tree + changelog buffer). Here's what it actually costs:
| Collection Size | Tree Depth | Max Buffer | Tree Creation Cost | Cost per NFT |
|---|
| 1,000 | 10 | 32 | 0.05 SOL ($7.50) | ~$0.0075 |
| 10,000 | 14 | 64 | 0.15 SOL ($22.50) | ~$0.00225 |
| 100,000 | 17 | 256 | 0.65 SOL ($97.50) | ~$0.000975 |
| 1,000,000 | 20 | 512 | 0.75 SOL ($112.50) | ~$0.0001125 |
| 10,000,000 | 24 | 1024 | 3.5 SOL ($525) | ~$0.0000525 |
Compare this to regular Solana NFTs at ~$1.80 each or Ethereum NFTs at $2–5 each. The savings are staggering — especially at scale.
After the tree is created, each mint transaction costs only the standard Solana transaction fee (~0.000005 SOL). No additional rent.
Where Does the Data Live?
This is the most common question, and the answer matters for understanding the trade-offs.
The NFT metadata (name, image URI, attributes, creator address, etc.) is stored as leaf data in the Merkle tree. But the Merkle tree on-chain only contains hashes, not the actual data. So where is the actual data?
- Transaction history: Every mint/update transaction includes the full leaf data in its instruction. This data is stored permanently in Solana's transaction ledger.
- RPC indexers: Services like Helius parse these transactions and index the leaf data in their databases. When you query a cNFT, the indexer reconstructs its current state from the transaction history.
- The DAS API: The Digital Asset Standard API is how applications read cNFT data. It's supported by major RPC providers (Helius, Triton, QuickNode) and returns cNFT metadata in the same format as regular NFTs.
This is the key trade-off: cNFT data availability depends on indexers. If every indexer shut down simultaneously, the data would still be recoverable from the transaction ledger, but there's no quick way to read a cNFT's current state without an indexer. In practice, this hasn't been an issue — multiple independent indexers maintain the data, and the DAS API is well-established.
How to Mint Compressed NFTs
Using Helius (Simplest Path)
Helius provides a mint API that abstracts away Merkle tree management entirely. You don't need to create a tree, manage proofs, or understand Bubblegum instructions. You send a request, and Helius handles the rest.
const response = await fetch('https://mainnet.helius-rpc.com/?api-key=YOUR_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 'mint-cnft',
method: 'mintCompressedNft',
params: {
name: 'My cNFT #1',
symbol: 'CNFT',
owner: 'RECIPIENT_WALLET_ADDRESS',
description: 'A compressed NFT minted via Helius',
attributes: [
{ trait_type: 'Rarity', value: 'Common' },
{ trait_type: 'Level', value: '1' },
],
imageUrl: 'https://example.com/image.png',
externalUrl: 'https://example.com',
sellerFeeBasisPoints: 500, // 5% royalties
},
}),
});
const { result } = await response.json();
console.log('Minted:', result.assetId);
Helius manages a shared Merkle tree, so you don't pay tree creation costs. You only pay the transaction fee (~0.000005 SOL per mint). This is the fastest way to get started — especially for small-to-medium batches.
For large collections where you want your own dedicated tree, Helius also supports custom tree creation.
Using Metaplex Bubblegum (Full Control)
Bubblegum is the Metaplex program for cNFTs. It gives you full control over tree creation, minting, transfers, and burns.
Step 1: Create a Merkle tree
import { createTree } from '@metaplex-foundation/mpl-bubblegum';
import { generateSigner } from '@metaplex-foundation/umi';
const merkleTree = generateSigner(umi);
await createTree(umi, {
merkleTree,
maxDepth: 14, // Supports up to 16,384 NFTs
maxBufferSize: 64, // 64 concurrent updates
public: false, // Only tree authority can mint
}).sendAndConfirm(umi);
Step 2: Mint to the tree
import { mintV1 } from '@metaplex-foundation/mpl-bubblegum';
await mintV1(umi, {
leafOwner: recipientPublicKey,
merkleTree: merkleTree.publicKey,
metadata: {
name: 'My cNFT #1',
symbol: 'CNFT',
uri: 'https://arweave.net/METADATA_JSON_URI',
sellerFeeBasisPoints: 500,
collection: { key: collectionMint, verified: false },
creators: [
{ address: creatorPublicKey, verified: false, share: 100 },
],
},
}).sendAndConfirm(umi);
Step 3: Read cNFT data via DAS
const response = await fetch('YOUR_RPC_WITH_DAS', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 'get-asset',
method: 'getAsset',
params: { id: 'CNFT_ASSET_ID' },
}),
});
const { result } = await response.json();
console.log(result.content.metadata.name);
console.log(result.ownership.owner);
Batch Minting at Scale
For large collections (100K+ NFTs), you'll want to optimize:
- Create the tree first with appropriate depth (see the cost table above)
- Batch mint transactions — each Solana transaction can include multiple Bubblegum mint instructions (typically 5–8 per transaction due to compute limits)
- Use priority fees during congestion to ensure transactions land
- Parallelize — submit multiple transactions concurrently, leveraging the concurrent Merkle tree's buffer
A well-optimized minting pipeline can mint 100,000 cNFTs in under an hour at a total cost of under $25.
Use Cases
Gaming Assets
This is the killer use case. Games need to mint items constantly — weapons, armor, consumables, achievements, loot drops. With regular NFTs, a game giving out 10 items per player with 100,000 players would spend $1.8 million on rent alone. With cNFTs, the same 1 million items cost ~$113.
Games like Star Atlas and others in the Solana ecosystem are using cNFTs for in-game items that can be traded on marketplaces like Tensor. Players get verifiable ownership without the game developer going bankrupt on minting costs.
Loyalty Programs and Rewards
Starbucks proved that consumers understand digital collectibles tied to rewards programs. But traditional NFTs are too expensive for "give every customer a stamp with each purchase" use cases.
With cNFTs, a coffee chain could mint a loyalty token for every purchase at effectively zero marginal cost. These tokens could:
- Unlock rewards when a certain count is reached
- Be traded or gifted between customers
- Contain dynamic metadata (e.g., updating the image as the loyalty tier changes)
- Serve as proof of purchase for warranty or refund purposes
POAPs and Event Tickets
Proof of Attendance Protocol (POAP) tokens are popular for events, meetups, and online happenings. A conference with 5,000 attendees can mint attendance tokens for under $5 total with cNFTs.
The metadata can include the event name, date, location, and a unique artwork. Post-event, these become verifiable credentials — proof that someone attended, which can gate access to future events, Discord channels, or airdrops.
Digital Collectibles at Scale
DRiP is the poster child here. The platform distributes free digital art from creators to subscribers, minting millions of cNFTs weekly. Without compression, DRiP's model would be economically impossible. With cNFTs, they've distributed over 300 million collectibles.
This enables a new model: free-to-claim digital art with real ownership. Creators mint freely, collectors receive freely, and secondary markets (via Tensor and other marketplaces) enable price discovery.
Credentials and Certificates
Diplomas, course completions, professional certifications — all things that benefit from verifiable on-chain provenance but don't justify $2 per issuance. Universities issuing 50,000 diplomas per year as cNFTs would pay about $6 total in minting costs.
Trading and Marketplace Support
Compressed NFTs are fully tradable. Tensor supports cNFTs natively — you can list, bid, and trade them just like regular NFTs. The marketplace handles the Merkle proof verification transparently.
Wallets like Phantom display cNFTs in your collectibles tab alongside regular NFTs. From the user's perspective, there's no visible difference between a compressed and uncompressed NFT.
Transfers
Transferring a cNFT is slightly more complex under the hood than a regular NFT transfer. The sender needs to provide:
- The leaf data (current owner, metadata hash)
- A Merkle proof (the path from the leaf to the root)
- The tree's canopy data
RPC providers that support DAS handle all of this automatically. The transfer instruction in Bubblegum takes the proof and updates the Merkle tree atomically.
import { transfer } from '@metaplex-foundation/mpl-bubblegum';
// Get the asset and proof from DAS
const asset = await getAsset(umi, assetId);
const proof = await getAssetProof(umi, assetId);
await transfer(umi, {
...asset,
...proof,
leafOwner: currentOwner,
newLeafOwner: newOwner,
}).sendAndConfirm(umi);
Decompression
A powerful feature: any cNFT can be decompressed into a regular NFT. This is a one-way operation — the compressed leaf is replaced with a standard Metaplex NFT account. The NFT's metadata and ownership remain identical.
Why would you decompress? A few reasons:
- Marketplace compatibility: While major marketplaces support cNFTs, some niche platforms only support regular NFTs
- Program compatibility: Some Solana programs expect standard token accounts and don't handle cNFTs
- Perceived value: Some collectors prefer "real" NFTs (though this distinction is largely psychological)
Decompression costs the standard rent for creating a regular NFT account (~0.012 SOL).
Limitations and Trade-Offs
Compressed NFTs aren't strictly better than regular NFTs — they involve genuine trade-offs.
Indexer Dependency
The biggest one. Reading cNFT data requires a DAS-compatible RPC provider. If you're running your own RPC node without DAS indexing, you can't query cNFT metadata. This creates a dependency on providers like Helius.
In practice, this matters most for self-hosted infrastructure. If you're using any major RPC provider, DAS support is standard.
No On-Chain Metadata Account
Regular NFTs have a metadata account that any program can read on-chain via CPI. cNFTs don't — the metadata exists only in the Merkle tree leaves, which aren't directly readable by other programs during transaction execution.
This means programs that need to verify NFT ownership or read attributes during a transaction (e.g., staking programs, on-chain games) need to receive the proof data as instruction arguments. It's more complex and consumes more transaction compute budget.
Tree Immutability
Once a Merkle tree is created with a specific depth, it can't be resized. If you create a tree with depth 14 (16,384 max NFTs) and need more, you have to create a new tree. Collection-level metadata ties them together, but it's a management overhead.
Plan your tree size carefully. It's better to slightly over-provision (depth 20 costs only ~0.75 SOL for a million slots) than to need multiple trees.
Update Authority Constraints
Updating cNFT metadata (changing the image, adding attributes) requires the tree authority to submit a transaction with the full Merkle proof. This is more involved than updating a regular NFT's metadata account.
Batch updates are particularly expensive in terms of compute and proof data. If your use case requires frequent metadata changes across thousands of NFTs, factor this into your architecture.
When to Use cNFTs vs. Regular NFTs
| Scenario | Use cNFTs | Use Regular NFTs |
|---|
| Collection > 10,000 items | Yes | No (cost prohibitive) |
| Free mints / airdrops | Yes | No |
| Gaming items / loot | Yes | No |
| Loyalty / rewards tokens | Yes | No |
| PFP collection (10K) | Yes (saves ~$18K) | Acceptable if budget allows |
| 1/1 art pieces | Either works | Preferred (simpler) |
| On-chain program composability | No (complex proofs) | Yes |
| Maximum decentralization | Regular is simpler | Yes |
The rule of thumb: if you're minting more than a few hundred NFTs, use compression. The cost savings are too significant to ignore, and the ecosystem tooling (DAS, Tensor, Phantom) has matured to the point where the user experience is identical.
Getting Started
- For quick minting (up to ~10K): Use Helius's
mintCompressedNft API. No tree management, minimal code.
- For large collections (10K+): Create a dedicated Merkle tree via Bubblegum, then batch mint.
- For reading cNFT data: Use the DAS API through Helius or another DAS-enabled RPC provider.
- For trading: List on Tensor. Users view in Phantom.
Compressed NFTs are one of Solana's most underappreciated technical achievements. They make digital asset issuance economically viable at internet scale — something no other blockchain has accomplished. If you're building anything that involves minting assets for users, cNFTs should be your default choice.