Cookie vs localStorage vs sessionStorage
By FrontendPro Editorial Team Updated 9/26/2026
Answer
All three store data in the browser, but they answer different questions: who needs to read it, how long should it live, and how much is there.
Cookies are the only one of the three sent to the server automatically, attached to every matching HTTP request. That makes them the right place for session identifiers, and the wrong place for anything bulky — the ~4 KB limit is per domain, and every extra byte is paid on every request. Cookies can be created by the server via Set-Cookie or by JavaScript, and a cookie marked HttpOnly is invisible to document.cookie, which is what protects a session token from XSS.
localStorage is a plain key/value store of about 5 MB, scoped to the origin and shared across every tab. Nothing is ever sent to the server. It survives closing the browser, so it suits user preferences such as theme or language, and cached data you are happy to serve on the next visit.
sessionStorage has the same API and size as localStorage, but its lifetime is a single tab. Close the tab and it is gone; open the same site in a second tab and that tab gets its own empty store. Good for state that should not leak between tabs, such as a multi-step form in progress.
| Cookie | localStorage | sessionStorage | |
|---|---|---|---|
| Sent with HTTP requests | Yes, every one | No | No |
| Size per origin | ~4 KB | ~5 MB | ~5 MB |
| Cleared when | Expiry date passes | Explicitly removed | Tab closes |
| Shared between tabs | Yes | Yes | No |
| Readable by JavaScript | Unless HttpOnly | Always | Always |
| Set by the server | Yes | No | No |
Choosing between them
Need the server to know? Cookie. Need it to persist for the user across visits, client-side only? localStorage. Need it scoped to one tab and gone afterwards? sessionStorage. And keep secrets out of localStorage and sessionStorage entirely — any script on the page can read them.
