Decentralized Storage: IPFS, Filecoin, Arweave – A Practical Guide
Regulatory claims due to an AWS S3 bucket or constant "we are updating infrastructure" from a centralized provider — two clear signals. Time to rethink data storage. Decentralized storage is not just ideology; it offers concrete properties: no single point of failure, verifiability through content addressing (CID), and permissionless storage. As noted in the article IPFS - Content Addressed, Versioned, P2P File System (Juan Benet): "content addressing ensures immutability and verifiability of data." This is the foundational principle for all modern DStorage solutions.
Today, DStorage comprises three fundamentally different stacks: IPFS + Filecoin, Arweave, and Storj/Sia. Each suits a specific class of tasks. Developing a decentralized storage system requires understanding both network protocols and token economics. In this article, we dive into the practical aspects of each solution, including code, configurations, and architectural trade-offs.
Choosing a Protocol: IPFS, Filecoin, or Arweave?
IPFS + Filecoin: Content Addressing and Storage Economics
For production systems, IPFS Cluster is essential — a coordinator for replication across multiple IPFS nodes. Minimum configuration: 3 nodes, replication factor 2. The cost of storing 1 GB per month in such a cluster is about $0.001 per replica, which is 100 times cheaper than Amazon S3.
// Example pinning via Cluster REST API type ClusterPinRequest struct { CID string `json:"cid"` ReplicationMin int `json:"replication-min"` ReplicationMax int `json:"replication-max"` Name string `json:"name"` Meta map[string]string `json:"meta"` } func PinToCluster(cid string, name string) error { req := ClusterPinRequest{ CID: cid, ReplicationMin: 2, ReplicationMax: 3, Name: name, } body, _ := json.Marshal(req) resp, err := http.Post( "http://cluster-api:9094/pins/" + cid, "application/json", bytes.NewReader(body), ) // ... return err } Filecoin Storage Deals are implemented via web3.storage, which automatically does hot IPFS pinning and cold Filecoin deals.
import { Web3Storage } from 'web3.storage' const client = new Web3Storage({ token: process.env.W3S_TOKEN }) async function storeWithReplication(files: File[]): Promise<string> { const cid = await client.put(files, { wrapWithDirectory: false, onRootCidReady: (rootCid) => { console.log('Root CID:', rootCid) }, onStoredChunk: (size) => { console.log(`Uploaded chunk of ${size} bytes`) } }) return cid } Arweave: Permanent Storage with One-Time Payment
Arweave offers a different model: pay once, data is stored "forever" (endowment fund designed for 200+ years). This fundamentally changes use cases. Arweave provides permanent storage 200 times longer than a 1-year Filecoin deal at a comparable cost per GB. Writing 1 MB to Arweave costs $10 one-time, which is more cost-effective in the long run than monthly IPFS pinning fees.
When Arweave Is the Right Choice
- Smart contract source code and ABI (permanent verifiability)
- NFT metadata and media (avoiding NFT rot)
- Legal and notarial documents
- Governance protocols and voting results (DAO governance history)
Data in Arweave is a transaction with a data field and tags. Tags are key for indexing via GraphQL:
import Arweave from 'arweave' const arweave = Arweave.init({ host: 'arweave.net', port: 443, protocol: 'https' }) async function uploadDocument(data: Buffer, mimeType: string, metadata: Record<string, string>) { const tx = await arweave.createTransaction({ data }) tx.addTag('Content-Type', mimeType) tx.addTag('App-Name', 'YourDApp') tx.addTag('Version', '1.0.0') for (const [key, value] of Object.entries(metadata)) { tx.addTag(key, value) } await arweave.transactions.sign(tx, jwk) const response = await arweave.transactions.post(tx) return tx.id } For instant confirmation, we use Irys (formerly Bundlr) — a layer 2 on top of Arweave.
import Irys from '@irys/sdk' const irys = new Irys({ url: 'https://node1.irys.xyz', token: 'ethereum', key: privateKey, }) const price = await irys.getPrice(data.length) console.log(`Cost: ${irys.utils.fromAtomic(price)} ETH`) const receipt = await irys.upload(data, { tags: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Contract-Address', value: contractAddress }, ] }) When Is a Hybrid Architecture Needed?
Real-world systems rarely use only one protocol. A typical architecture for a DApp with performance and permanence requirements:
Protocol Comparison Table
| Component | Purpose | Latency |
|---|---|---|
| IPFS Cluster | Hot storage with fast access | < 1 s |
| Arweave (via Irys) | Cold permanent storage | 2 min |
| PostgreSQL | Index CID/TXID and metadata | < 10 ms |
| Protocol | Transaction confirmation time | Cost per 1 MB write |
|---|---|---|
| IPFS (pin) | Seconds | $0.0001/month per replica |
| Filecoin | ~1 hour | $0.001 |
| Arweave (native) | ~2 min | $10 (one-time) |
| Irys | Instant | $10 (one-time) |
Compare the protocols and choose the right fit. For a consultation, contact us.
Verification of integrity: content addressing provides built-in verification for IPFS — CID is the content hash. For Arweave, it's through transaction proofs.
Case Study: NFT Project Migration
On a recent project for an NFT marketplace with over 10,000 assets, we migrated from centralized cloud storage to a hybrid solution. We used IPFS Cluster (3 nodes, replication factor 2) for active metadata and Arweave via Irys for permanent media storage. The result: monthly storage costs dropped from $500 to a one-time $200, pinning management was eliminated, and data integrity was guaranteed by content addressing.
Encryption and Access Control
Decentralized storage does not mean public. For sensitive data, we use Lit Protocol for threshold encryption with on-chain access conditions:
import * as LitJsSdk from '@lit-protocol/lit-node-client' const accessControlConditions = [{ contractAddress: NFT_CONTRACT, standardContractType: 'ERC721', chain: 'ethereum', method: 'balanceOf', parameters: [':userAddress'], returnValueTest: { comparator: '>', value: '0' } }] const { ciphertext, dataToEncryptHash } = await LitJsSdk.encryptString( { accessControlConditions, dataToEncrypt: sensitiveData }, litNodeClient ) const decrypted = await LitJsSdk.decryptToString( { accessControlConditions, ciphertext, dataToEncryptHash, chain: 'ethereum' }, litNodeClient ) How We Develop a Decentralized Storage System: Step-by-Step
- Requirements Analysis: data volume, latency, permanence needs, compliance.
- Stack Selection: IPFS+Filecoin for active data, Arweave for archives.
- Architecture Design: hybrid schema with PostgreSQL index.
- IPFS Cluster Setup: 3 nodes, replication factor 2, monitoring.
- Filecoin/Arweave Integration: via web3.storage or Irys.
- Encryption Addition: Lit Protocol for confidentiality.
- Testing: load testing, fault tolerance checks, security audit.
- Deployment and Documentation: CI/CD, monitoring, runbook.
Our process is iterative. We start with a proof of concept and refine based on your specific requirements. The timeline and cost are determined after a thorough analysis — contact us to discuss your case.
Deliverables
- Architectural document with protocol selection justification
- IPFS Cluster setup (3+ nodes, replication, monitoring)
- Filecoin or Arweave integration (web3.storage / Irys)
- Lit Protocol-based encryption system
- Testing (load, fault tolerance, security)
- API documentation and developer guides
- Team training (1 day)
- 1 month post-launch support
Our team has over 8 years of experience in decentralized systems and has delivered 50+ blockchain projects. Contact us for a project assessment — we'll calculate the cost and timeline. Submit a request today and receive a free architectural document.







