Menu

Understanding localStorage, sessionStorage, and IndexedDB

Understanding localStorage, sessionStorage, and IndexedDB

Web storage is essential for modern websites and apps, helping you store data on the client side to improve performance, user experience, and offline capabilities. But choosing the right one — localStorage, sessionStorage, or IndexedDB — depends on your use case.

In this guide, we're going to:

  • Break down the differences between localStorage, sessionStorage, and IndexedDB
  • Show real-world examples of how to use each one
  • Provide a comparison chart and decision-making flowchart
  • Help you pick the right storage API for your next project

Whether you're building a simple landing page or a full offline-capable web app, understanding these APIs will make your work more efficient and reliable.

TL;DR Comparison Table

Feature localStorage sessionStorage IndexedDB
Storage Limit ~5-10MB ~5-10MB >50MB (browser-dependent)
Lifespan Until manually cleared Until tab closes Until manually cleared
Sync Type Synchronous Synchronous Asynchronous
Data Format String only String only Structured data (objects)
Use Cases Preferences, themes Tab-specific data Complex data, caching
Accessibility All tabs/windows One tab only All tabs/windows

1. localStorage

Introduced as part of the Web Storage API in HTML5, localStorage provides a simple key-value storage mechanism that persists across sessions. It is designed for storing data in a way that's accessible by all tabs and windows from the same origin, and is retained even after the browser is closed and reopened.

localStorage is simple and persistent — great for small key/value data that needs to stay put.

Example:

localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');

Best for:

  • Dark/light mode
  • Language preference
  • Auth tokens (note: not safest for sensitive data)

Notes:

  • Data survives page reloads and browser restarts.
  • Shared across tabs from the same origin.

2. sessionStorage

Also introduced in HTML5 alongside localStorage, sessionStorage is intended for data that should only persist during a single page session. Each browser tab has its own sessionStorage area, making it useful for keeping temporary state information specific to that tab.

sessionStorage is similar to localStorage, but it only lasts for the duration of the browser tab.

Example:

sessionStorage.setItem('step', '2');
const step = sessionStorage.getItem('step');

Best for:

  • Multi-step forms (wizard interfaces)
  • Temporary state between page reloads

Notes:

  • Data is wiped when the tab or window is closed.
  • Not shared across tabs or windows.

Choose sessionStorage when you need temporary storage that's limited to a single browser session. This data is automatically cleared when the user closes the browser tab or window, making it perfect for temporary form data, single-session settings, or information that shouldn't persist between visits.

3. IndexedDB

IndexedDB was introduced as a more powerful alternative to Web SQL (now deprecated) and fills the need for storing large volumes of structured data. It functions as a full-fledged NoSQL database, allowing developers to store complex objects, perform queries, and manage data transactions — all within the browser.

IndexedDB is a low-level API for storing large amounts of structured data. It’s asynchronous and can store objects, blobs, arrays, etc.

Example:

const request = indexedDB.open("MyDB", 1);
request.onsuccess = (event) => {
  const db = event.target.result;
  const tx = db.transaction("users", "readwrite");
  const store = tx.objectStore("users");
  store.put({ id: 1, name: "Walt" });
};

Code Explanation

  1. indexedDB.open("MyDB", 1) - Initiates a connection to a database named "MyDB" with version 1. If the database doesn't exist, this creates it.
  2. request.onsuccess - Defines an event handler that executes when the database connection is successfully established.
  3. event.target.result - Retrieves the database object from the successful connection event.
  4. db.transaction("users", "readwrite") - Creates a transaction for the "users" object store with write permissions. Transactions group operations and ensure database integrity.
  5. tx.objectStore("users") - Accesses the "users" object store within the transaction. This is like a table in a traditional database.
  6. store.put({ id: 1, name: "Walt" }) - Stores an object with id and name properties. If an object with id: 1 already exists, it will be updated; otherwise, a new record is created.

Unlike localStorage and sessionStorage, IndexedDB is:

  • Asynchronous (won't block the main thread)
  • Capable of storing complex data types beyond strings
  • Designed for larger amounts of data
  • Structured with indexes for efficient querying
  • Transaction-based for data consistency

Best for:

  • Offline-first apps
  • Storing large datasets (chat messages, logs, files)
  • Complex data relationships

Notes:

  • Asynchronous and promise-friendly with libraries like Dexie.js.
  • Best used when localStorage and sessionStorage fall short.

Choosing the Right Storage Solution

When developing web applications, selecting the appropriate storage mechanism can significantly impact both performance and user experience.

localStorage excels for persistent client-side data that needs to survive across sessions. Its synchronous nature makes it ideal for storing user preferences, theme settings, or cached reference data under 5MB. However, be mindful that this data remains indefinitely until explicitly cleared, raising potential privacy considerations.

sessionStorage provides the perfect balance for ephemeral, session-bound information. By automatically clearing when a tab closes, it creates natural data lifecycles for temporary states, wizard progress, or single-session authentication tokens without requiring manual cleanup logic.

IndexedDB represents the most sophisticated browser storage solution when your requirements exceed simple key-value pairs. Its asynchronous architecture, transaction support, and indexing capabilities make it suitable for offline-first applications, complex data structures, and scenarios requiring efficient querying across large datasets (potentially hundreds of megabytes).

The most effective applications often leverage multiple storage technologies in concert—using localStorage for configuration, sessionStorage for transient states, and IndexedDB for substantial data requirements.

By thoughtfully matching your storage strategy to your specific data characteristics, persistence needs, and performance requirements, you can create responsive applications that respect both system resources and user expectations.

Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.
AD: "Heavy scripts slowing down your site? I use Fathom Analytics because it’s lightweight, fast, and doesn’t invade my users privacy." - Get $10 OFF your first invoice.

Community Comments

No comments posted yet

Code Your Own Classic Snake Game – The Right Way

Master the fundamentals of game development and JavaScript with a step-by-step guide that skips the fluff and gets straight to the real code.

Ad Unit

Current Poll

Help us and the community figure out what the latest trends in coding are.

Total Votes:
Q:
Submit

Add a comment