IndexedDB in Practice: Large-File Storage and Offline Architecture in the Browser

技术架构(Updated May 22, 2026)

Why IndexedDB?

Browser storage options each have clear limits:

Option Capacity Data Types Sync API Use Case
Cookie ~4KB String Session identifiers
localStorage ~5MB String Simple settings
sessionStorage ~5MB String Temporary state
IndexedDB Hundreds of MB–GB Any structured data ❌ Async Large files, offline apps

For tool sites that need to cache PDF processing intermediates, WASM modules, or user upload history in the browser, IndexedDB is the only viable choice.


Core Concepts

Database → Object Store → Record

Database: "toolsku-cache"
  ├── ObjectStore: "wasm-modules"     (key: moduleName)
  ├── ObjectStore: "file-cache"       (key: fileHash, index: timestamp)
  └── ObjectStore: "user-preferences" (key: settingKey)

Transactions and Concurrency

IndexedDB transactions auto-commit, and only one read/write transaction per ObjectStore is allowed at a time:

const tx = db.transaction(['file-cache'], 'readwrite');
const store = tx.objectStore('file-cache');
await store.put({ hash: 'abc123', data: arrayBuffer, timestamp: Date.now() });
await tx.done; // Wait for transaction to complete

IndexedDB in ToolsKu

WASM Module Caching

ffmpeg.wasm is about 30MB and takes 3–5 seconds to load each time. After caching in IndexedDB, subsequent visits are nearly instant:

async function getWasmModule(name: string): Promise<ArrayBuffer> {
  const cached = await idb.get('wasm-modules', name);
  if (cached) return cached;

  const response = await fetch(`/wasm/${name}.wasm`);
  const buffer = await response.arrayBuffer();
  await idb.put('wasm-modules', buffer, name);
  return buffer;
}

Chunked Storage for Large Files

Files over 50MB are not ideal to store in IndexedDB all at once. A chunking strategy:

File (200MB) → split into 4MB chunks → store each in IndexedDB
key: "file:{hash}:chunk:{index}"
Read in order and concatenate → restore full file

Version Migration

When the database schema changes, handle migration in onupgradeneeded:

const request = indexedDB.open('toolsku-cache', 2); // version 2

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (event.oldVersion < 2) {
    db.createObjectStore('processing-history', { keyPath: 'id' });
  }
};

Best practice: add ObjectStores only—never remove them. Bump the version number to trigger migration and avoid deleting user data.


IndexedDB vs OPFS

Feature IndexedDB OPFS (Origin Private File System)
API maturity Broad support Chrome 86+ / Safari 15.2+
Read/write model Key-value store True file system
Performance Moderate Higher (especially sync access)
Best for Structured cache Large file I/O

ToolsKu primarily uses IndexedDB, with OPFS as a performance optimization on Chrome.


Summary

IndexedDB is essential infrastructure for offline-first browser tools. Well-designed ObjectStores, WASM caching, and chunked storage strategies let ToolsKu stay responsive even on slow networks.

Try these browser-local tools — no sign-up required →

#IndexedDB#浏览器存储#离线#大文件#架构