This is an extremely broad scope question, and a lot of the pros/cons will be contextual to the situation.

localStorage, sessionStorage, and cookies are all client storage solutions. In all cases, these storage mechanisms will be specific to an individual browser on an individual computer/device.

Session data is held on the server where it remains under your direct control. Any requirement to store data on an ongoing basis across sessions will need to involve your application server side - most likely using a cache system like Redis, a database, or just a file on the filesystem.



sessionStorage (as the name suggests) is only available for the duration of the browser session (and is deleted when the tab or window is closed) - it does, however, survive page reloads.


Clearly, if the data you are storing needs to be available on an ongoing basis then localStorage is preferable to sessionStorage - although you should note both can be cleared by the user so you should not rely on the continuing existence of data in either case.

localStorage and sessionStorage

localStorage and sessionStorage are relatively new APIs (meaning, not all legacy browsers will support them) and are near identical (both in APIs and capabilities) with the sole exception of persistence.

localStorage and sessionStorage are perfect for persisting non-sensitive data needed within client scripts between pages (for example: preferences, scores in games). The data stored in localStorage and sessionStorage can easily be read or changed from within the client/browser so should not be relied upon for storage of sensitive or security-related data within applications.

localStorage and sessionStorage weren't designed to be used as a secure storage mechanism in a browser. It was designed to be a simple string only key/value store that developers could use to build slightly more complex single page apps. That's it.

Any data stored there may be vulnerable to cross-site scripting. If an attacker can run JavaScript on your website, they can retrieve all the data you've stored in localStorage and send it off to their own domain. This means anything sensitive you've got in localStorage (like a user's session data) can be compromised. If your website is truly secure and no attacker can run JavaScript code on your website then you are technically safe, but in reality that is incredibly hard to achieve.

Stop using localStorage for sensitive data

The only situation in which you should use localStorage: when you need to store some publicly available information that is not at all sensitive, doesn't need to be used in a high-performance app, isn't larger than 5MB, and consists of purely string data.

Any authentication your application requires can be bypassed by a user with local privileges to the machine on which the data is stored. Therefore, it's recommended not to store any sensitive information in local storage.



This is also true for cookies, these can be trivially tampered with by the user, and data can also be read from them in plain text - so if you are wanting to store sensitive data then the session is really your only option. If you are not using SSL, cookie information can also be intercepted in transit, especially on a public Wi-Fi.

On the positive side, cookies can have a degree of protection applied from security risks like Cross-Site Scripting (XSS)/Script injection by setting an HttpOnly flag which means modern (supporting) browsers will prevent access to the cookies and values from JavaScript (this will also prevent your own, legitimate, JavaScript from accessing them). This is especially important with authentication cookies, which are used to store a token containing details of the user who is logged in - if you have a copy of that cookie then for all intents and purposes you become that user as far as the web application is concerned, and have the same access to data and functionality the user has.

As cookies are used for authentication purposes and persistence of user data, all cookies valid for a page are sent from the browser to the server for every request to the same domain - this includes the original page request, any subsequent Ajax requests, all images, stylesheets, scripts, and fonts. For this reason, cookies should not be used to store large amounts of information. The browser may also impose limits on the size of information that can be stored in cookies. Typically cookies are used to store identifying tokens for authentication, session, and advertising tracking. The tokens are typically not human readable information in and of themselves, but encrypted identifiers linked to your application or database.

Cookies preview in Google Chrome

It's crucial that you turn off HTTP TRACE support on all web servers. An attacker can steal cookie data via Javascript even when document.cookie is disabled or not supported by the client. This attack is mounted when a user posts a malicious script to a forum so when another user clicks the link, an asynchronous HTTP Trace call is triggered which collects the user's cookie information from the server, and then sends it over to another malicious server that collects the cookie information so the attacker can mount a session hijack attack. This is easily mitigated by removing support for HTTP TRACE on all web servers.

localStorage vs sessionStorage vs Cookies

In terms of capabilities, cookies, sessionStorage and localStorage only allow you to store strings - it is possible to implicitly convert primitive values when setting (these will need to be converted back to use them as their type after reading), but not Objects or Arrays. It is possible to JSON serialise them to store them using the APIs.

Session data storage will generally allow you to store any primitives or objects supported by your server-side language and/or framework.

Non-string data

If you need to store data in the browser that isn't sensitive and isn't purely string data, the best option for you is IndexedDB. It's an API that lets you work with a database-esque object store in the browser.

What's great about IndexedDB is that you can use it to store typed information: integers, floats, etc. You can also define primary keys, handle indexing, and create transactions to prevent data integrity issues.

Because IndexedDB isn't supported by all browsers, you need to check that the user's browser supports it before using it.

Offline Data

If you need your app to run offline, your best option is to use a combination of IndexedDB along with the Cache API (which is a part of Service Workers).

The Cache API allows you to cache network resources that your app needs to load.

Store sensitive data

If you need to store sensitive data, here's how to do it:

  • When a user logs into your website, create a session identifier or JWT for them and store it in a cryptographically signed cookie.
  • Make sure that cookie library is setting the httpOnly cookie flag. This flag makes it impossible for a browser to read any cookies, which is required in order to safely use server-side sessions with cookies.
  • Make sure that your cookie library also sets the SameSite=strict cookie flag to prevent CSRF attacks, as well as the secure=true flag to ensure cookies can only be set over an encrypted connection.
  • Each time a user makes a request to your site, use their session ID or JWT access token (extracted from the cookie they send to you) to retrieve their account details from either a database or a cache (depending on how large your website is).

Once you have the user's account info pulled up and verified, feel free to pull any associated sensitive data along with it.

Client-side vs Server-side

As HTTP is a stateless protocol - web applications have no way of identifying a user from previous visits on returning to the web site - session data usually relies on a cookie token to identify the user for repeat visits (although rarely URL parameters may be used for the same purpose). Data will usually have a sliding expiry time (renewed each time the user visits), and depending on your server/framework data will either be stored in-process (meaning data will be lost if the web server crashes or is restarted) or externally in a state server or database. This is also necessary when using a web-farm (more than one server for a given website).

As session data is completely controlled by your application (server side) it is the best place for anything sensitive or secure in nature.

The obvious disadvantage of server-side data is scalability - server resources are required for each user for the duration of the session, and that any data needed client side must be sent with each request. As the server has no way of knowing if a user navigates to another site or closes their browser, session data must expire after a given time to avoid all server resources being taken up by abandoned sessions. When using session data you should, therefore, be aware of the possibility that data will have expired and been lost, especially on pages with long forms. It will also be lost if the user deletes their cookies or switches browsers/devices.

Some web frameworks/developers use hidden HTML inputs to persist data from one page of a form to another to avoid session expiration.

localStorage, sessionStorage, and cookies are all subject to "same-origin" rules which means browsers should prevent access to the data except the domain that set the information to start with.

TL;DR: Conclusion

Don't use localStorage unless you need to store publicly available information that:

  • is not at all sensitive
  • doesn't need to be used in an ultra high performance app
  • isn't larger than 5MB
  • consists of purely string data

Also, whatever you do, do not store session information (like JSON Web Tokens) in localStorage. This is a very bad idea and will open you up to an extremely wide array of attacks that could absolutely cripple your users.

Identifying tokens for authentication, session, and advertising tracking should be stored in cookies. Those cookies have to be properly configured to prevent XSS and CSRF.

Original: What is the difference between localStorage, sessionStorage, session and cookies?