Web Storage API

Also known as: localStorage · sessionStorage

On this page 7

The Web Storage API is a browser interface that lets a web page store string key-value pairs on the user’s device, scoped to the page’s origin, through two objects: localStorage, which persists across browser sessions, and sessionStorage, which lasts only for the lifetime of a single tab. Among Web APIs it is the simplest way to keep small amounts of client-side data without cookies or a database.

Its strengths are a synchronous, very small API and universal browser support. Its limits are equally important: values are strings only, capacity is typically around 5 MB per origin, every call blocks the main thread, and data is readable by any script running on the page, which makes it unsuitable for secrets.

How localStorage and sessionStorage work

Both storage objects implement the same Storage interface with methods setItem(key, value), getItem(key), removeItem(key), clear() and key(index), plus a length property. Values are always converted to strings, so objects must be serialized with JSON.stringify and parsed back with JSON.parse. Storing an object directly saves the useless text [object Object].

The difference between the two lies in lifetime and sharing. localStorage is shared by all tabs and windows of the same origin and survives browser restarts. sessionStorage belongs to one top-level browsing context: each tab has its own copy, the data survives reloads and restoring the tab, and it disappears when the tab is closed. Opening a link in a new tab copies the current session storage into the new tab at that moment, after which the two copies diverge.

PropertylocalStoragesessionStorage
LifetimeUntil deleted by code, user or browser policyUntil the tab is closed
SharingAll tabs of the same originOne tab only
Survives reloadYesYes
Survives browser restartYesOnly if the session is restored
Change notificationstorage event in other tabsNo cross-tab events in practice
localStorage and sessionStorage compared

Scope, capacity and the storage event

Web Storage is partitioned by origin, meaning the combination of scheme, host and port. Data written by a shop served over HTTPS is invisible to the same host served over plain HTTP and to a blog on a different subdomain. Modern browsers additionally apply storage partitioning to third-party contexts, so an embedded iframe gets storage keyed to the top-level site and cannot track users across sites through it.

Browsers set quotas per origin, commonly about 5 MB for localStorage and a similar separate amount for sessionStorage, measured in UTF-16 characters in some engines. When the quota is exceeded, setItem throws a QuotaExceededError, so robust code wraps writes in try and catch and degrades gracefully.

When localStorage changes, the browser fires a storage event on the window of every other document of the same origin, but not on the document that made the change. The event exposes key, oldValue, newValue and url, which makes it a simple tool for synchronizing state across tabs, such as logging out everywhere when the user logs out in one tab.

LimitTypical value or behaviorConsequence
Quota per originAround 5 MBUnsuitable for media or large datasets
Data typeStrings onlySerialization required for objects
Execution modelSynchronousLarge reads and writes block the main thread
Worker accessNot available in web workers or service workersBackground code needs IndexedDB
Private browsingCleared at the end of the sessionNo long-term persistence
Key limits of the Web Storage API

Web Storage compared with cookies and IndexedDB

Choosing a client-side storage mechanism depends on size, structure, access pattern and whether the server needs the data. Cookies travel with every HTTP request, which is useful for sessions and costly for anything else. IndexedDB handles large, structured and asynchronous storage. Web Storage sits between them for small preferences and UI state.

MechanismCapacityAPI styleSent to serverBest for
CookiesAbout 4 KB per cookieString headerYes, with each requestSession identifiers
localStorageAbout 5 MBSynchronousNoPreferences, small cached values
sessionStorageAbout 5 MBSynchronousNoPer-tab form drafts and flow state
IndexedDBLarge, quota-managedAsynchronousNoStructured data, offline apps
Cache APILarge, quota-managedAsynchronousNoHTTP responses for service workers
Client-side storage options

A useful rule is that anything larger than a few kilobytes, anything accessed from a worker, or anything that needs indexing belongs in IndexedDB. Anything the server must read belongs in a cookie or a request header. Web Storage covers the remaining small, page-level cases.

Security and privacy considerations

Web Storage has no protection against scripts on the same origin. Any JavaScript running on the page, including a compromised third-party library or a cross-site scripting payload, can read every stored value. For this reason authentication tokens are generally safer in HttpOnly cookies, which scripts cannot read, than in localStorage.

  • Never store passwords, payment data or long-lived tokens in Web Storage.
  • Treat stored values as untrusted input when reading them back, because users and extensions can edit them.
  • Version stored data with a schema key so that a new release can migrate or discard old formats.
  • Respect consent rules; persistent identifiers in localStorage are subject to the same privacy regulations as cookies in many jurisdictions.

Practical patterns and common mistakes

Good uses include remembering a theme or language choice, keeping a draft of a long form in sessionStorage, and caching small configuration responses with a timestamp for expiry. Because Web Storage has no built-in expiration, code must store a time value alongside the data and check it when reading.

MistakeSymptomFix
Storing objects without JSONValue reads as [object Object]Serialize and parse explicitly
No error handling on writesCrash when quota is full or storage is blockedWrap in try and catch
Large data on startupSlow first interactionMove to IndexedDB
Reading during server renderingReference error on the serverAccess only in the browser
Assuming permanenceLost data after browser cleanupTreat as a cache, not a source of truth
Common mistakes and fixes

Put simply

The Web Storage API is a small notebook that a website keeps inside your browser. The site can write short notes in it, such as your preferred language or whether you chose dark mode. The next time you visit, it reads those notes back.

There are two notebooks. One is kept until it is erased. The other is thrown away when you close the tab. Each website gets its own notebook and cannot read the notes of other sites. It is handy for small things, but it is not a safe place for secrets.

In practice

A municipal portal offers a long permit application with about 40 fields across five steps. Residents often lose their progress when the page reloads or when they briefly navigate to read the guidance pages.

The developers save the form state to sessionStorage as a JSON string on every field change, debounced to one write per 500 milliseconds. On page load the form checks for a saved draft, validates its schema version and restores the values. Sensitive fields such as identity numbers are excluded from the draft and must be entered again. The user’s chosen language is stored separately in localStorage so that it applies to future visits.

After the change, abandoned applications decrease noticeably, and support calls about lost form data largely disappear, without any change to the server.