Storage Costs
Understanding storage costs helps you budget effectively and avoid service interruptions. This guide explains how to calculate costs and fund your account for Filecoin storage.
How Storage Costs Work
Section titled “How Storage Costs Work”Storage operates on a pay-per-epoch model where you deposit USDFC tokens and set allowances that control how much the storage service can spend.
Pricing Components
Section titled “Pricing Components”| Component | Cost | Notes |
|---|---|---|
| Storage | $2.50/TiB/month | Minimum $0.06/month per data set (~24.567 GiB threshold) |
| Sybil Fee | 0.1 USDFC (one-time) | Per new data set creation; prevents state-growth spam |
| CDN Egress | $14/TiB downloaded | 1 USDFC top-up ≈ 71.5 GiB of downloads |
| CDN Setup | 1 USDFC (one-time) | Per data set; reusing existing data sets incurs no cost |
Pricing Logic:
- Storage < 24.567 GiB: Minimum $0.06/month applies
- Storage ≥ 24.567 GiB: Actual cost
(bytes / TiB) × $2.50/month - CDN data sets require 1 USDFC setup on first creation only
- CDN egress credits can be topped up anytime
Real-World Cost Examples
Section titled “Real-World Cost Examples”Example 1: NFT Collection (10,000 × 5 KiB ≈ 48.82 MiB)
Section titled “Example 1: NFT Collection (10,000 × 5 KiB ≈ 48.82 MiB)”// 48.82 MiB less than 24.567 GiB threshold// Price is $0.06/monthconst const PRICE_PER_MONTH: 0.06
PRICE_PER_MONTH = 0.06;const const months: 24
months = 24;const const PRICE_FOR_24_MONTHS: number
PRICE_FOR_24_MONTHS = const PRICE_PER_MONTH: 0.06
PRICE_PER_MONTH * 24; // 1.44 USDFC| Duration | Total Cost |
|---|---|
| 1 month | 0.06 USDFC |
| 24 months | 1.44 USDFC |
Example 2: User Content Platform with CDN
Section titled “Example 2: User Content Platform with CDN”- Storage: 1,000 users × 100 MiB ≈ 100,000 MiB
- Traffic: 1,000 users × 100 MiB/month ≈ 100,000 MiB/month egress
const const STORAGE_PRICE_PER_TIB_PER_MONTH: 2.5
STORAGE_PRICE_PER_TIB_PER_MONTH = 2.5; // $2.50/TiB/monthconst const CDN_EGRESS_PRICE_PER_TIB: 14
CDN_EGRESS_PRICE_PER_TIB = 14; // $14/TiB downloadedconst const storageMiB: 100000
storageMiB = 100_000;const const egressMiB: 100000
egressMiB = 100_000;
// Storage: 100,000 MiB ≈ 0.0953 TiBconst const storageTiB: number
storageTiB = const storageMiB: 100000
storageMiB / 1024 / 1024;
// Egress: 100,000 MiB ≈ 0.0953 TiBconst const egressTiB: number
egressTiB = const egressMiB: 100000
egressMiB / 1024 / 1024;
// Storage cost per month: 0.0953 TiB × $2.50 ≈ $0.238/monthconst const storageCostPerMonth: number
storageCostPerMonth = const storageTiB: number
storageTiB * const STORAGE_PRICE_PER_TIB_PER_MONTH: 2.5
STORAGE_PRICE_PER_TIB_PER_MONTH;
// Egress cost per month: 0.0953 TiB × $14 ≈ $1.334/monthconst const egressCostPerMonth: number
egressCostPerMonth = const egressTiB: number
egressTiB * const CDN_EGRESS_PRICE_PER_TIB: 14
CDN_EGRESS_PRICE_PER_TIB;
// Total cost per month: $0.238/month + $1.334/month ≈ $1.572/monthconst const totalCostPerMonth: number
totalCostPerMonth = const storageCostPerMonth: number
storageCostPerMonth + const egressCostPerMonth: number
egressCostPerMonth;
// Total cost for 24 months: $1.572/month × 24 ≈ $37.728const const totalCostFor24Months: number
totalCostFor24Months = const totalCostPerMonth: number
totalCostPerMonth * 24;| Cost Component | Per Month | 24 Months |
|---|---|---|
| Storage | ≈ 0.238 USDFC | ≈ 5.71 USDFC |
| CDN Egress | ≈ 1.334 USDFC | ≈ 32.016 USDFC |
| Total | ≈ 1.572 USDFC | ≈ 37.728 USDFC |
Warm Storage Service Approvals
Section titled “Warm Storage Service Approvals”Before uploading, the WarmStorage operator must be approved and your account must be funded. FWSS requires a 30-day prepayment buffer — when your balance drops below 30 days, the provider may remove your data.
The SDK’s prepare() method handles all of this automatically. It computes the exact deposit needed, checks whether the FWSS operator is approved, and returns a single transaction that handles both.
Querying Upload Costs
Section titled “Querying Upload Costs”Use getUploadCosts() to preview costs without executing any transaction. This is useful for displaying pricing in a UI or letting users confirm before proceeding.
const const costs: getUploadCosts.OutputType
costs = await const synapse: Synapse
synapse.Synapse.storage: StorageManager
storage.StorageManager.getUploadCosts(options: Omit<GetUploadCostsOptions, "clientAddress">): Promise<UploadCosts>
getUploadCosts({ dataSize: bigint
dataSize: 1073741824n, // 1 GiB in bytes})The returned UploadCosts object contains:
| Field | Type | Description |
|---|---|---|
rate.perEpoch | bigint | Storage rate per epoch (30 seconds) |
rate.perMonth | bigint | Storage rate per month (for display) |
depositNeeded | bigint | USDFC to deposit (0n if sufficient funds) |
needsFwssMaxApproval | boolean | Whether FWSS operator approval is needed |
ready | boolean | true when no deposit or approval is needed |
Funding Your Account
Section titled “Funding Your Account”Use prepare() to compute costs and get a ready-to-execute transaction. This is the recommended approach for most use cases — it replaces the previous manual flow of calculating allowances, checking approvals, and branching between deposit/approve methods.
// Compute costs and get a transaction (if needed)const const prep: PrepareResult
prep = await const synapse: Synapse
synapse.Synapse.storage: StorageManager
storage.StorageManager.prepare(options: PrepareOptions): Promise<PrepareResult>
prepare({ PrepareOptions.dataSize: bigint
dataSize: 1073741824n, // 1 GiB})
// Inspect costsvar console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("Rate per month:", function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits(const prep: PrepareResult
prep.PrepareResult.costs: getUploadCosts.OutputType
costs.rate: { perEpoch: bigint; perMonth: bigint;}
rate.perMonth: bigint
perMonth))var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("Deposit needed:", function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits(const prep: PrepareResult
prep.PrepareResult.costs: getUploadCosts.OutputType
costs.depositNeeded: bigint
depositNeeded))
// Execute if the account isn't readyif (const prep: PrepareResult
prep.PrepareResult.transaction: { depositAmount: bigint; includesApproval: boolean; execute: (options?: { onHash?: (hash: Hash) => void; }) => Promise<{ hash: Hash; receipt: TransactionReceipt<bigint, number, "success" | "reverted", TransactionType> | null; }>;} | null
transaction) { var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("Deposit amount:", function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits(const prep: PrepareResult
prep.PrepareResult.transaction: { depositAmount: bigint; includesApproval: boolean; execute: (options?: { onHash?: (hash: Hash) => void; }) => Promise<{ hash: Hash; receipt: TransactionReceipt<bigint, number, "success" | "reverted", TransactionType> | null; }>;}
transaction.depositAmount: bigint
depositAmount)) var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("Includes approval:", const prep: PrepareResult
prep.PrepareResult.transaction: { depositAmount: bigint; includesApproval: boolean; execute: (options?: { onHash?: (hash: Hash) => void; }) => Promise<{ hash: Hash; receipt: TransactionReceipt<bigint, number, "success" | "reverted", TransactionType> | null; }>;}
transaction.includesApproval: boolean
includesApproval)
const { const hash: `0x${string}`
hash } = await const prep: PrepareResult
prep.PrepareResult.transaction: { depositAmount: bigint; includesApproval: boolean; execute: (options?: { onHash?: (hash: Hash) => void; }) => Promise<{ hash: Hash; receipt: TransactionReceipt<bigint, number, "success" | "reverted", TransactionType> | null; }>;}
transaction.execute: (options?: { onHash?: (hash: Hash) => void;}) => Promise<{ hash: Hash; receipt: TransactionReceipt<bigint, number, "success" | "reverted", TransactionType> | null;}>
execute() var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("Transaction confirmed:", const hash: `0x${string}`
hash)}
// Now safe to uploadprepare() returns:
costs: The fullUploadCostsbreakdowntransaction: A transaction object withexecute(), ornullif the account is already ready
The transaction automatically picks the right contract call:
- Needs deposit + approval: calls
depositWithPermitAndApproveOperator - Needs approval only: calls
approveService - Needs deposit only: calls
depositWithPermit - Already ready: returns
transaction: null
Next Steps
Section titled “Next Steps”- Storage Operations - Storage concepts and workflows
- Storage Context - Contexts and data sets