Browser storage lets a website keep information on a person’s device. Cookies, localStorage, sessionStorage, and IndexedDB serve different purposes: they can help maintain a login, remember a preference, preserve work within a tab, or support a larger collection of offline data.Choosing between them requires more than asking how long the data lasts. What matters is who needs the information, which pages can access it, whether it must reach a server, and what should happen if it disappears.A site might remember your preferred text size yet lose an unfinished form when you return. Loading quickly, remembering settings, and recovering work are different kinds of continuity; one does not establish the others.

In this article:

The main storage mechanisms compared

These mechanisms all preserve browser-side information, but their access patterns and lifecycles differ.

Practical differences between four browser storage mechanisms
Mechanism Typical use Lifetime Automatically sent to a server?
Cookies Session identifiers, preferences, and other small values needed with requests Session-based or assigned an expiration, subject to browser policy and deletion Can accompany matching HTTP requests, depending on attributes and browser policy
localStorage Small string-based settings and lightweight application state Persists across visits without a built-in expiration, unless cleared or otherwise removed No; application code must explicitly transmit it
sessionStorage Temporary state associated with a particular tab Lasts for the page session and survives ordinary reloads No; application code must explicitly transmit it
IndexedDB Structured records, searchable local collections, and offline application data Can persist across visits, subject to storage policy, deletion, and eviction No; synchronization requires application logic

Cookies have small per-cookie limits. Web Storage is suitable for relatively small amounts of string data, while IndexedDB is designed for larger structured datasets. Exact limits vary, so an application should handle storage failure rather than depend on one universal capacity figure.

Cookies: information that can accompany requests

A cookie is a small piece of data stored by the browser that can be included with matching HTTP requests. A server can set a cookie through a response header; JavaScript can also create and read cookies when their attributes permit it.

This request behavior makes cookies useful when a server needs to recognize continuity between otherwise separate requests. In a common login design, a cookie carries an opaque session identifier. The server uses that identifier to locate session information and decide whether the requested action is authorized.

The cookie is not necessarily the account record or the complete session. It may be a reference to information maintained elsewhere.

Cookie attributes govern different aspects of behavior

  • HttpOnly prevents JavaScript cookie APIs from reading or changing that cookie.
  • Secure restricts the cookie to secure transport, generally HTTPS.
  • SameSite influences whether the cookie accompanies cross-site requests.
  • Domain and Path help determine which requests receive the cookie.
  • Max-Age and Expires can define an expiration.

These attributes address different concerns. A cookie’s Path is not a security boundary, and HttpOnly does not make an application immune to malicious scripts or unauthorized actions.

For the authentication-specific considerations, see Cookies and Session Security. The broader storage decision begins with whether the information needs to accompany requests at all.

Local storage: small values across visits

localStorage provides string key/value storage associated with an origin. An origin is generally defined by the combination of scheme, hostname, and port. For example, HTTP and HTTPS versions of the same hostname do not share the same local storage area.

A reading interface might use local storage to remember a preferred text size. When the person returns using the same browser profile, the application can read the saved value and apply it again.

Local storage does not automatically send that preference to the server, transfer it to another device, or attach it to an account.

Simple storage still has implementation costs

Both keys and values are strings. An application can serialize an object as JSON, but it must then handle parsing, missing fields, invalid data, and changes to the stored format.

Web Storage operations are synchronous: the calling script waits for an operation to finish. Repeatedly reading or writing substantial data can interfere with responsiveness. Local storage is therefore a better fit for a few small settings than for a large, frequently updated document collection.

There is no built-in per-item expiration. If a saved value should stop being used after a particular time, the application must implement that rule. Browser settings, private browsing behavior, and site-data deletion can still affect availability.

Session storage: continuity within a tab

sessionStorage uses the same string key/value model as local storage, but it is separated by both origin and top-level browsing context—usually a tab.

For example, a comparison tool could preserve a temporary selection while someone moves between pages and reloads the tab. Another tab can maintain a separate selection.

A tab opened from another page may initially receive a copy of the opener’s session storage in some circumstances. The storage areas then remain separate; they are not a shared, continuously synchronized store.

Session storage normally ends with the page session, but browser restoration behavior matters. It should not be treated as a security guarantee that closing a tab permanently destroys every trace of its state.

Most importantly, a browser page session is not the same thing as an authenticated server session. Clearing session storage does not necessarily log someone out, and a server can invalidate a login while session storage remains intact. The MDN sessionStorage reference explains its tab and lifecycle behavior in more detail.

IndexedDB: structured application data

IndexedDB is an asynchronous, transactional database within the browser. It stores structured records and supports keys and indexes for finding them. Unlike Web Storage, its values are not limited to strings; it supports data types handled by structured cloning.

An offline notes application might use IndexedDB to store individual notes, index them by modification date, and retrieve one note without loading the entire collection.

Transactions allow related database operations to succeed or fail together within their scope. Asynchronous operations also avoid the same synchronous access pattern used by local storage, although application code can still create performance problems through excessive processing or poorly planned queries.

A local database does not synchronize itself

IndexedDB supplies local database operations. Sharing a note across devices, reconciling conflicting edits, and confirming a remote save require separate application logic. Client State, Server State, and Synchronization explains how to keep local edits distinct from submitted and confirmed versions.

The MDN IndexedDB documentation provides a technical starting point for database structure, transactions, and access patterns.

Storage is not the same as caching

Browser caching primarily concerns reusing resources or responses. Application storage concerns information the application explicitly preserves and interprets.

  • A cached stylesheet can help a returning page load without downloading that file again.
  • A saved display preference can tell the application which appearance to use.
  • A session cookie can help the server recognize an authenticated session.
  • A locally stored draft can preserve unfinished work without proving that the server received it.

These mechanisms can coexist. A page may load quickly from cached resources while showing default preferences or requiring another login.

The Cache API, often used with service workers, also lets applications explicitly store request/response pairs. It is distinct from IndexedDB and from the browser’s ordinary HTTP cache. Having cached files alone does not guarantee that an application will work offline.

For resource reuse and freshness, continue with Browser Caching Explained.

Scope, security, and privacy

Browser storage boundaries affect which contexts can access data. They do not decide which people or application components should be trusted with it.

Local storage and IndexedDB are generally origin-scoped. Session storage adds a tab-level boundary. Embedded third-party contexts may face additional partitioning or access restrictions under browser privacy policies. Cookies follow their own delivery rules and policy restrictions.

Do not assume that an embedded service receives the same storage access everywhere, or that moving between subdomains preserves all application data.

JavaScript-accessible storage is not a vault

Scripts running with the page’s origin privileges can generally access its JavaScript-accessible storage. A cross-site scripting vulnerability can therefore expose stored information. Unlike cookies, local storage, session storage, and IndexedDB do not offer an HttpOnly attribute.

That does not make one mechanism universally safe and another universally unsafe. Credential and session design requires a threat model covering script execution, request behavior, server validation, and recovery—not a casual rule to put a token in whichever storage API is easiest.

Browser-held values must also be treated as untrusted input. A server should not accept a stored value such as role=administrator or a locally calculated price as authority.

Retention should have a reason

Preserve only what the feature needs, explain consequential local retention, and define when data should be removed. On a shared device, signing out should have an intentional policy for account-specific drafts and cached records—not merely for the login cookie.

The privacy consequences depend on what information is retained, why it is kept, and who can access it—not just on whether the mechanism is called a cookie.

What returning to a website can recover

Consider someone writing a long form, closing the browser, and returning the next day.

  • If the form existed only in page memory, it may be gone.
  • If it was saved in session storage, recovery depends on the page session and browser restoration behavior.
  • If it was saved in local storage or IndexedDB, the application may recover it from that browser profile, provided the data remains available.
  • If it was successfully saved to an account on the server, it may be available from another device after authentication, depending on the application.

None of those outcomes can be inferred solely from the page looking unchanged. A clear interface distinguishes “saved in this browser” from “saved to your account,” and distinguishes a pending synchronization attempt from confirmed completion.

Browser storage is commonly managed on a best-effort basis. Quotas can be reached, data can be evicted or cleared, and private browsing may use different retention rules. Applications can request persistent storage where supported, but a request is not guaranteed to be granted and does not prevent deliberate deletion.

The response to a failed save should reflect what is at stake. A display preference can fall back to a usable default. If a draft cannot be saved, keep the current text available where possible, explain that saving did not complete, and offer a working recovery route, such as copying or exporting it. Important work should have a recovery plan beyond a single browser copy. See Accessible Error Prevention and Recovery for preserving work and making the next step understandable.

The MDN guide to quotas and eviction explains why storage availability should be treated as a condition to handle, not a permanent promise.

Choosing and testing storage

Begin with the information’s purpose and the consequences of losing or exposing it.

  1. Does the server need it with matching requests? A cookie may fit, with attributes appropriate to its purpose.
  2. Is it a small preference needed across visits? Local storage may be sufficient.
  3. Should it belong to one tab’s temporary work? Session storage may fit.
  4. Does it require structured records, indexes, or substantial offline data? Consider IndexedDB.
  5. Must it survive device loss or appear elsewhere? Plan remote persistence, synchronization, or export separately.

Test in the environment where the application will run. Browser policy can block access to Web Storage, so error handling must cover obtaining the storage object as well as reading and writing values. For HTML files opened directly through file: URLs, localStorage behavior is undefined and browser-dependent; success in a local file is not evidence of the same behavior on a hosted site.

Then test more than the successful write:

  • Reload the page and open another tab.
  • Close and reopen the browser, including its session-restore behavior.
  • Try another profile, private browsing, and another device.
  • Clear relevant site data and check whether recovery instructions remain useful.
  • Test unavailable storage, quota errors, older data formats, and interrupted synchronization.
  • Sign out and sign in as another account to check for unintended data carryover.

Developer tools can help inspect cookies, Web Storage, IndexedDB, and outgoing requests. Panel names vary by browser. Inspection reveals what is present in that environment at that moment; it does not establish a universal retention guarantee. Debugging Websites with Browser Developer Tools offers a broader evidence-led approach.

The right storage choice matches the data’s purpose, access needs, and acceptable failure conditions. Reliable continuity comes from pairing that choice with understandable feedback and a recovery plan—not from assuming that information stored in a browser will always be there.