Cookies vs localStorage vs sessionStorage in JavaScript
Compare cookies, localStorage, and sessionStorage side by side. Learn which storage mechanism to use for authentication, preferences, caching, and temporary data.
The browser gives you three ways to store data on the client: cookies, localStorage, and sessionStorage. They look similar from a distance, but each one serves a fundamentally different purpose. Choosing the wrong one leads to security problems, performance issues, or data that disappears when you expect it to persist.
Here is the decision in one sentence: use cookies when the server needs the data, localStorage when data should survive forever, and sessionStorage when data should die with the tab.
Side-by-side comparison
The differences become clear when you put the three mechanisms in a single table. Pay attention to lifetime and server access, because those two columns drive most real-world decisions.
| Cookies | localStorage | sessionStorage | |
|---|---|---|---|
| Capacity | About 4 KB per cookie | About 5 MB per origin | About 5 MB per origin |
| Lifetime | Configurable (session or persistent) | Forever, until manually deleted | Until tab closes |
| Sent to server | Yes, with every HTTP request | No | No |
| Shared across tabs | Yes | Yes | No (each tab isolated) |
| Accessible via JS | Yes (unless HttpOnly) | Yes | Yes |
| API style | String parsing on document.cookie | Simple key-value methods | Same as localStorage |
| Secure context required | No (Secure flag optional) | No (but recommended) | No (but recommended) |
| HttpOnly flag | Yes (set by server) | Not applicable | Not applicable |
Each difference matters for a specific use case. Capacity matters when storing large JSON. Server access matters for authentication. Tab isolation matters for multi-tab workflows.
When to use cookies
Cookies are the only storage mechanism that the browser automatically attaches to HTTP requests. Every time the browser requests a page, image, or API endpoint from your server, it includes all cookies for that domain in the request headers.
This automatic server access makes cookies the right choice for authentication tokens. The server receives the session cookie with every request and knows who the user is without any client-side code. Combined with the HttpOnly flag set by the server, cookies protect tokens from cross-site scripting attacks because JavaScript cannot read HttpOnly cookies at all.
Cookies also support server-controlled expiration dates, domain scoping to include or exclude subdomains, and the SameSite attribute to prevent cross-site request forgery. Use cookies when the server is the primary consumer of the data.
When to use localStorage
localStorage is the simplest storage API and the best choice for data that only matters on the client side. User interface preferences like theme, font size, and language belong in localStorage. Cached API responses that prevent redundant network requests also fit here.
The 5 MB capacity is generous enough for most client data. Since localStorage is never sent to the server, it does not add overhead to every HTTP request like cookies do. Data persists until your code explicitly removes it or the user clears their browser data.
Use localStorage for information that should survive across sessions: a shopping cart for an unauthenticated user, onboarding flags that track whether a tutorial has been seen, or a dashboard layout that the user customized.
When to use sessionStorage
sessionStorage is localStorage with one critical difference: the data is scoped to a single tab and disappears when that tab closes. Each tab gets its own isolated sessionStorage, so opening the same site in two tabs gives each tab an independent storage space.
This isolation makes sessionStorage ideal for temporary state. Multi-step form wizards store partial data without worrying about cross-tab interference. One-time security tokens can live in sessionStorage where closing the tab guarantees they are gone. Page state like scroll position or expanded accordion sections persists across refreshes but resets on the next visit.
Use sessionStorage when you want localStorage's simple API but need the data to clean itself up automatically.
Security considerations
Storage security is about access control. Any JavaScript running on your page can read localStorage and sessionStorage. This means a cross-site scripting vulnerability exposes everything in both stores to an attacker.
Cookies with the HttpOnly flag are invisible to JavaScript. An XSS attack cannot steal them because document.cookie does not include HttpOnly cookies. For authentication tokens, this is the critical difference. Always set HttpOnly, Secure, and SameSite=Lax on session cookies from the server.
For sensitive client data in localStorage, consider encrypting values before storage. This does not prevent XSS from reading the encrypted data, but it protects the plaintext if the user's device is compromised outside the browser.
Practical decision flowchart
Here is a simple way to decide which storage mechanism fits your use case. Start with the top question and follow the answer.
If the server reads the data, the answer is always cookies. If the data is client-only and should persist, use localStorage. If the data is client-only and temporary, sessionStorage wins. The flowchart covers nearly every real-world decision.
Common mistakes
- Storing authentication tokens in localStorage. They are accessible to any JavaScript on the page, making XSS attacks far more dangerous. Use HttpOnly cookies.
- Using cookies for large data. The 4 KB limit per cookie and the overhead of sending cookies with every request make them a poor choice for storing JSON blobs.
- Expecting sessionStorage to be shared across tabs. Each tab is isolated. Use localStorage with manual cleanup if you need cross-tab shared temporary data.
- Storing sensitive unencrypted data in localStorage. It is readable by any script on the page and persists on disk indefinitely.
- Creating too many cookies. Browsers limit the total number of cookies per domain. Consolidate related data into fewer cookies when possible.
Related articles
- JS localStorage API Guide: A Complete Tutorial -- full API reference for persistent client storage
- JS sessionStorage API Guide: Complete Tutorial -- tab-scoped temporary storage in detail
- How to Manage Cookies in JS: Complete Tutorial -- creating, reading, and configuring cookies
- Parsing and Deleting Browser Cookies with JS -- working with the document.cookie string
Quick reference
| Decision | Use |
|---|---|
| Server needs the data | Cookies (with HttpOnly from server) |
| Data survives forever, client only | localStorage |
| Data dies with the tab, client only | sessionStorage |
| Security-sensitive token | Cookies with HttpOnly + Secure + SameSite |
| Large structured data (> 5 MB) | IndexedDB, not any of these three |
Rune AI
Key Insights
- Cookies are sent to the server automatically. Use them for authentication and server-read data.
- localStorage persists until explicitly deleted. Use it for user preferences and cached data.
- sessionStorage clears when the tab closes. Use it for form drafts and temporary state.
- Cookies are limited to about 4 KB. localStorage and sessionStorage allow about 5 MB.
- HttpOnly cookies are invisible to JavaScript, making them the safest choice for session tokens.
Frequently Asked Questions
Which storage mechanism should I use for authentication tokens?
Can I use all three storage mechanisms at the same time?
How do I clear all three storage types on logout?
Is IndexedDB better than these three options?
Conclusion
Cookies, localStorage, and sessionStorage each solve a different problem. Cookies are for server communication and secure tokens. localStorage is for persistent client-side data that survives tab close. sessionStorage is for temporary data scoped to a single tab. Choose based on lifetime, server access needs, and capacity requirements, not on API preference.
More in this topic
Using Decorators for Logging in JS Architecture
Learn how JavaScript decorators wrap class methods to add logging without touching the original code, including setup with Babel and how execution order works.
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.