Cookies vs localStorage vs sessionStorage vs IndexedDB
Browser Storage 101: Cookies vs localStorage vs sessionStorage vs IndexedDB
- All four store data in the browser, but they differ in size, lifetime, who can read them, and whether the data travels to the server.
Cookies
- Cookies are small pieces of data stored in the browser.
- Their maximum size is typically around 4 KB per cookie.
- They are automatically sent to the server with every HTTP request that matches the cookie's domain and path.
- Their expiration is configurable with
Expires or Max-Age. Without one, the cookie is a session cookie and is cleared when the browser session ends.
- Security attributes control how they are used:
HttpOnly: JavaScript cannot read the cookie through document.cookie.
Secure: the cookie is only sent over HTTPS.
SameSite: limits whether the cookie is sent with cross-site requests.
- Cookies are commonly used for authentication sessions. A properly configured
HttpOnly cookie protects the session token from being stolen by JavaScript, for example through an XSS (Cross-Site Scripting) attack.
localStorage
- localStorage stores data as string-based key-value pairs.
- Its capacity is typically around 5 MB per origin.
- Its data is not sent to the server automatically, and it has no built-in expiration. Data stays until your code or the user clears it.
- Its API is synchronous, so large reads and writes can block the main thread.
- It is shared by every tab and window of the same origin.
- Common use: user preferences like language, theme, or selected market.
localStorage.setItem("theme", "dark");
localStorage.getItem("theme"); // "dark"
sessionStorage
- sessionStorage also stores string-based key-value pairs, just like localStorage.
- It has similar storage limits, a synchronous API, and no time-based expiration.
- The main difference: its data is limited to the current tab's session.
- Data survives page reloads, but is cleared when the tab's session ends, typically when the tab is closed.
- Another tab of the same site gets its own separate sessionStorage.
- Common use: temporary data like multi-step form progress or page filters.
IndexedDB
- IndexedDB is a browser-based NoSQL database.
- It stores records by key, and values can be JavaScript objects, files, and binary data (
Blob, ArrayBuffer), not just strings.
- Unlike localStorage and sessionStorage, it has an asynchronous API and supports indexes and transactions.
- Its capacity depends on the browser, device, and available disk space. Check it with
navigator.storage.estimate().
- Common use: offline-first applications that store thousands of emails, messages, or files locally.
Comparison
Important qualifications
- Script-readable storage is exposed to XSS. Any script running on your origin can read localStorage, sessionStorage, IndexedDB, and non-
HttpOnly cookies. Avoid putting long-lived auth tokens there.
HttpOnly does not stop CSRF (Cross-Site Request Forgery). Because cookies are sent automatically, use SameSite and CSRF tokens where needed.
- Every cookie adds request overhead. Cookies travel with each matching request, so keep them small and few.
- "No expiration" is not "permanent". Users can clear site data, and browsers can evict storage under storage pressure or privacy rules. Treat browser storage as a cache, not the source of truth.
- Storage limits vary by browser. The 4 KB and 5 MB figures are common limits, not guarantees.
Takeaway
- Cookies: tiny, sent to the server automatically, best for auth sessions with
HttpOnly, Secure, and SameSite.
- localStorage: simple persistent key-value strings for preferences, shared across tabs.
- sessionStorage: the same API, but scoped to one tab's session.
- IndexedDB: an asynchronous database for large, structured, offline data.
References