DEV Community

Weather Clock Dash
Weather Clock Dash

Posted on

Browser Storage Guide: localStorage vs sessionStorage vs IndexedDB vs Cache API vs OPFS

Modern browsers offer multiple storage mechanisms, each with different tradeoffs. Choosing the right one depends on data size, structure, persistence requirements, and whether you need server-sync. Here's a practical comparison for Firefox web developers.

The Storage Options

localStorage sessionStorage Cookies IndexedDB Cache API OPFS
Capacity ~5MB ~5MB ~4KB Hundreds of MB Hundreds of MB Gigabytes
Data type Strings only Strings only Strings Structured Request/Response Files/Blobs
Async No No No Yes Yes Yes
Persists Until cleared Tab session Configurable Until cleared Until cleared Until cleared
Server access No No Yes (sent in headers) No No No
Available in workers No No No Yes Yes Yes

localStorage

Use for: small amounts of simple persistent data

// Store
localStorage.setItem('theme', 'dark');
localStorage.setItem('user', JSON.stringify({ id: 1, name: 'Alice' }));

// Read
const theme = localStorage.getItem('theme'); // 'dark' or null
const user = JSON.parse(localStorage.getItem('user'));

// Delete
localStorage.removeItem('theme');
localStorage.clear(); // Delete everything

// Iterate
for (let i = 0; i < localStorage.length; i++) {
  const key = localStorage.key(i);
  console.log(key, localStorage.getItem(key));
}
Enter fullscreen mode Exit fullscreen mode

Pitfalls:

  • Synchronous — blocks the main thread (imperceptible for small data, noticeable for large data)
  • Strings only — must JSON.stringify/parse objects
  • 5MB limit — JSON stringify is inefficient; hits limit quickly with complex objects
  • Shared across all tabs (same origin) — use storage event to sync tabs
// Listen for changes from other tabs
window.addEventListener('storage', (event) => {
  if (event.key === 'theme') {
    applyTheme(event.newValue);
  }
});
Enter fullscreen mode Exit fullscreen mode

sessionStorage

Same API as localStorage, but:

  • Cleared when the tab/window closes
  • Each tab has its own sessionStorage (not shared)
  • Persists through page reloads within the same tab
// Good for: multi-step forms
sessionStorage.setItem('form-step-1', JSON.stringify(formData));

// Good for: per-session tokens (not persistent auth)
sessionStorage.setItem('session-token', token);
Enter fullscreen mode Exit fullscreen mode

Cookies

Sent to the server with every request. Use for authentication and server-side session state.

// JS can read/write non-HttpOnly cookies
document.cookie = 'name=value; path=/; max-age=3600; secure; samesite=strict';

// Reading (returns all cookies as one string)
const cookies = document.cookie; // "name=value; other=thing"
const value = cookies
  .split('; ')
  .find(row => row.startsWith('name='))
  ?.split('=')[1];
Enter fullscreen mode Exit fullscreen mode

For security: prefer HttpOnly (only server can read), Secure (HTTPS only), and SameSite=Strict (no cross-site sending).

Don't use cookies for client-side-only data — they're included in every HTTP request (bandwidth overhead).

IndexedDB

Use for: large structured data, offline apps, complex queries

See the full IndexedDB guide for details. Quick summary:

// idb library (recommended wrapper)
import { openDB } from 'idb';
const db = await openDB('MyApp', 1, {
  upgrade(db) {
    db.createObjectStore('tasks', { keyPath: 'id' });
  },
});

await db.add('tasks', { id: 1, title: 'Buy groceries', done: false });
const tasks = await db.getAll('tasks');
Enter fullscreen mode Exit fullscreen mode

Cache API (for Service Workers)

Use for: caching network requests, offline support

// In service worker
const cache = await caches.open('app-v1');
await cache.addAll(['/index.html', '/app.js', '/app.css']);

// Serve from cache
const cached = await caches.match(request);
if (cached) return cached;
return fetch(request);

// Cache a response
const response = await fetch(request);
cache.put(request, response.clone());
return response;
Enter fullscreen mode Exit fullscreen mode

The Cache API stores full HTTP request/response pairs — headers, body, status. It's designed for service worker caching strategies, not arbitrary data storage.

Origin Private File System (OPFS)

Use for: large files, binary data, file-like storage

Firefox 111+ supports OPFS — a private virtual file system per origin:

// Get root directory
const root = await navigator.storage.getDirectory();

// Create a file
const fileHandle = await root.getFileHandle('data.bin', { create: true });
const writable = await fileHandle.createWritable();
await writable.write(binaryData);
await writable.close();

// Read a file
const file = await fileHandle.getFile();
const content = await file.arrayBuffer();

// Available in workers too (synchronous in workers!)
Enter fullscreen mode Exit fullscreen mode

OPFS is great for: SQLite databases in the browser (via WebAssembly), large binary files, CAD tools, photo editors.

Storage Quota

Firefox manages storage per origin. Check available quota:

const estimate = await navigator.storage.estimate();
console.log('Used:', estimate.usage, 'bytes');
console.log('Quota:', estimate.quota, 'bytes');
console.log('Available:', estimate.quota - estimate.usage, 'bytes');
Enter fullscreen mode Exit fullscreen mode

Request persistent storage (won't be evicted by the browser under storage pressure):

const granted = await navigator.storage.persist();
console.log('Persistent storage:', granted); // true/false
Enter fullscreen mode Exit fullscreen mode

Firefox DevTools: Storage Inspector

View and manage all storage:

  1. DevTools → Storage tab
  2. Left panel: Cookies, localStorage, sessionStorage, IndexedDB, Cache Storage
  3. Click any entry to view/edit/delete

For IndexedDB: navigate database → object store → records. You can add, edit, and delete records directly.

Decision Guide

Small data (< 100KB) + need sync between tabs → localStorage
Per-tab session data → sessionStorage
Must reach server with requests → Cookies
Large structured data + queries → IndexedDB
Cache network responses → Cache API
Large files + binary data → OPFS
Enter fullscreen mode Exit fullscreen mode

For most web apps: localStorage for preferences, IndexedDB for app data, Cookies for auth. Service workers + Cache API for offline support.

Top comments (0)