Best Browser Web Storage for Web Apps
There is no single browser storage technology that is best for every web application. Use localStorage for small persistent preferences, sessionStorage for temporary tab-specific data, IndexedDB for large structured application data, Cache API for network resources and offline assets, and appropriately configured cookies for server-managed sessions.
Choosing browser storage is easy when an application only needs to remember a theme or language preference. It becomes much more important when the application must work offline, synchronize data, cache large resources, preserve multi-step forms, or handle authentication securely.
Developers commonly compare IndexedDB vs localStorage, but that comparison alone is incomplete. A modern web application may use several storage mechanisms at the same time because each one solves a different problem.
The wrong choice can create practical problems: storage quota errors, slow main-thread operations, lost temporary state, stale cached resources, unnecessary network traffic, or sensitive information becoming accessible to JavaScript after an XSS vulnerability.
This guide explains the major browser storage options, their practical limits, security implications, and the situations in which each should be considered for modern web apps and Progressive Web Apps.
What Is Browser Storage?
Browser storage refers to technologies that allow a web application to keep information on the user's device. Depending on the API, that information can include simple key-value pairs, structured objects, database records, files, or cached HTTP responses.
Modern browsers provide several storage mechanisms, including:
- Cookies
- localStorage
- sessionStorage
- IndexedDB
- Cache API
- Origin Private File System (OPFS) for specialized file-based workloads
Important distinction: browser storage is generally scoped by origin. It should not be treated as a replacement for a server-side database, and stored client-side data should not automatically be assumed to be permanent or trusted.
Browser Storage Options at a Glance
| Technology | Primary Purpose | Typical Limit Model | Best Use |
|---|---|---|---|
| Cookies | Server/client state | Small, commonly about 4 KB per cookie | Sessions and authentication |
| localStorage | Persistent key-value data | 5 MiB per origin | Preferences and small settings |
| sessionStorage | Temporary tab-specific data | 5 MiB per origin | Temporary workflows |
| IndexedDB | Structured client-side database | Browser/device managed | Large offline datasets |
| Cache API | Request/response caching | Browser/device managed | Offline web resources |
| WebSQL | Legacy SQL storage | Legacy implementation-dependent | Do not use for new projects |
Storage availability varies by browser, device, origin, storage pressure, and privacy settings. Do not design production applications around an assumed IndexedDB or Cache API number.
1. Cookies: Best for Server-Managed Sessions
Cookies are small pieces of data that browsers can send to servers with HTTP requests. Their main strength is not large-scale client-side storage; it is maintaining state between the browser and server.
When Should You Use Cookies?
- Server-managed login sessions
- Session identifiers
- Small server-side preferences
- Consent or state that needs controlled transmission to the server
A cookie is normally much smaller than browser database storage. A commonly encountered practical limit is approximately 4 KB per cookie, although actual browser and server limits can vary.
Cookie Security
For session cookies, security attributes matter. Secure restricts transmission to HTTPS, HttpOnly prevents JavaScript from reading the cookie through APIs such as document.cookie, and SameSite controls cross-site transmission behavior.
Security rule: Do not treat cookies as automatically secure. Configure session cookies deliberately with appropriate Secure, HttpOnly, and SameSite settings.
2. localStorage: Simple Persistent Browser Storage
localStorage is part of the Web Storage API and provides a simple string-based key-value store. Data normally remains available across page reloads and browser restarts until it is removed by the application or browser.
Typical localStorage Use Cases
- Theme selection
- Language preference
- UI settings
- Recently viewed item identifiers
- Small application preferences
- Non-sensitive client-side configuration
localStorage Example
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme");
localStorage.removeItem("theme");
How Much Can localStorage Store?
Current MDN documentation describes Web Storage as having a maximum of about 10 MiB total per origin, divided into approximately 5 MiB for local storage and 5 MiB for session storage. Applications should still handle quota errors rather than assuming storage will always be available.
Important localStorage Limitations
- Values are strings.
- Objects normally need serialization with JSON.
- Operations are synchronous.
- It is not designed to replace a database.
- JavaScript running in the same origin can access it.
const user = {
name: "Alex",
theme: "dark"
};
localStorage.setItem("user", JSON.stringify(user));
const savedUser =
JSON.parse(localStorage.getItem("user"));
localStorage and XSS
One of the biggest security concerns is storing sensitive information in Web Storage. If an attacker can execute malicious JavaScript through an XSS vulnerability, that script may be able to read values stored in localStorage.
For that reason, avoid using localStorage as a convenient place for passwords, highly sensitive credentials, banking information, or other secrets.
3. sessionStorage: Temporary Tab-Specific Data
sessionStorage looks similar to localStorage from a programming perspective, but its lifetime and scoping are different. It is associated with the current page session and is particularly useful when data should not remain as permanent application state.
Good sessionStorage Examples
- Temporary checkout information
- Multi-step forms
- Temporary filters
- Short-lived navigation state
- Data that should disappear when the browsing session ends
sessionStorage.setItem("checkoutStep", "3");
const step = sessionStorage.getItem("checkoutStep");
Like localStorage, sessionStorage is string-based and synchronous. It should therefore remain a lightweight storage mechanism rather than becoming a repository for thousands of records.
4. IndexedDB: Browser Storage for Large Structured Data
IndexedDB is a browser database designed for significant amounts of structured data. Unlike Web Storage, it can store structured objects and other data types supported by the structured clone algorithm, and its operations are asynchronous.
This makes IndexedDB particularly useful when an application behaves more like a database-driven application than a simple web page.
When Should You Use IndexedDB?
- Large offline datasets
- Product catalogs
- Offline-first applications
- CRM data
- Notes and documents
- Structured application records
- Data that needs indexes and efficient queries
Why IndexedDB Is Different from localStorage
The key difference in the IndexedDB vs localStorage discussion is the data model. localStorage is a simple string key-value store, while IndexedDB provides database-style object stores, indexes, transactions, and asynchronous operations.
Practical rule: If you are starting to design tables, records, indexes, searches, synchronization queues, or offline datasets, IndexedDB is generally a more appropriate architectural fit than localStorage.
IndexedDB Storage Limits
There is no single universal "IndexedDB limit" that applies to every modern browser. Quotas are managed by the browser's storage system and can depend on factors such as available device storage, browser policy, origin usage, and storage pressure.
For this reason, avoid publishing a fixed claim such as "IndexedDB always allows X GB." Instead, applications can use the Storage API to estimate current usage and available quota.
if (navigator.storage && navigator.storage.estimate) {
const estimate = await navigator.storage.estimate();
console.log("Usage:", estimate.usage);
console.log("Quota:", estimate.quota);
}
5. Cache API: Best for Offline Web Resources
The Cache API is designed around cached request and response objects. It is especially useful when a Progressive Web App needs to continue loading resources when network connectivity is unavailable.
Typical Cache API Content
- HTML documents
- CSS files
- JavaScript files
- Images
- Fonts
- Selected API responses
The Cache API is commonly used together with service workers. A service worker can intercept requests and serve appropriate resources from Cache Storage when the network is unavailable.
Think of the distinction this way: IndexedDB is suited to application data, while Cache API is suited to network resources. An offline-first PWA may use both.
6. WebSQL: Why You Should Not Build New Apps With It
WebSQL provided a browser database interface based around SQL, but it is a legacy technology. The W3C Web SQL specification is no longer actively maintained, and modern browser storage guidance has moved toward technologies such as IndexedDB and the Storage API.
If you are maintaining an old application that depends on WebSQL, migration planning may be appropriate. For a new application, WebSQL should not be selected as the foundation for browser data storage.
7. IndexedDB vs localStorage vs sessionStorage vs Cache API
| Feature | localStorage | sessionStorage | IndexedDB | Cache API |
|---|---|---|---|---|
| Data model | String key-value | String key-value | Structured database | Request/response cache |
| Persistence | Persistent | Session-scoped | Persistent by default | Persistent by default |
| Typical limit | 5 MiB | 5 MiB | Browser managed | Browser managed |
| Async | No | No | Yes | Yes |
| Large datasets | No | No | Yes | Not its primary purpose |
| Offline app data | Limited | Limited | Excellent | Excellent for resources |
| Best use | Preferences | Temporary state | Application data | Network resources |
8. Which Storage Should You Choose for Your Web App?
The best browser storage strategy starts with the type of data you need to store rather than the technology you happen to know best.
| Requirement | Suitable Technology | Reason |
|---|---|---|
| Theme preference | localStorage | Small persistent value |
| Language preference | localStorage | Small persistent value |
| Temporary checkout form | sessionStorage | Short-lived tab state |
| Large offline catalog | IndexedDB | Structured records and indexes |
| Offline images | Cache API | Network resource caching |
| Offline application shell | Cache API | HTML/CSS/JS resources |
| Server-managed login | Secure cookie | HTTP session management |
Scenario 1: Simple Website Preferences
If your application only needs to remember dark mode, language, font size, or a few UI preferences, localStorage is usually simpler than introducing IndexedDB.
Scenario 2: Multi-Step Forms
If a user is completing a temporary workflow and you want the information to survive a refresh without becoming long-term application data, sessionStorage can be useful.
Scenario 3: Offline-First Progressive Web App
An offline-first PWA commonly needs two different categories of local data. IndexedDB can hold structured application records, while the Cache API can hold the resources required to load and operate the application offline.
Scenario 4: Authentication
Authentication is a security architecture decision, not simply a storage-capacity decision. For server-managed sessions, appropriately configured HttpOnly, Secure cookies can prevent JavaScript from directly reading the session identifier.
Scenario 5: Large Client-Side Data
If your application needs thousands of records, indexed queries, offline synchronization, or structured objects, IndexedDB is a more suitable architectural choice than localStorage.
9. Browser Storage Quotas and QuotaExceededError
One of the most common mistakes is assuming that browser storage is unlimited. Storage quotas differ between APIs and browsers, and even browser-managed storage can be affected by available device capacity and eviction policies.
For Web Storage, a write that exceeds the available limit can result in a QuotaExceededError. IndexedDB and Cache API operations can also fail when the relevant storage quota is exceeded.
Handle Storage Failures
try {
localStorage.setItem("settings", JSON.stringify(settings));
} catch (error) {
if (error.name === "QuotaExceededError") {
console.warn("Browser storage quota exceeded.");
} else {
console.error("Storage failed:", error);
}
}
For larger storage systems, use navigator.storage.estimate() where appropriate, monitor application storage growth, remove obsolete data, and design a fallback path for storage failures.
10. Browser Storage Security Best Practices
Storage selection and application security are closely connected. Client-side storage should never be treated as a trusted vault simply because the browser manages it.
Protect Against XSS
Web Storage data is accessible to JavaScript running in the same origin. If an XSS vulnerability allows an attacker to execute JavaScript in your application context, stored values can become exposed.
Use output encoding, safe DOM APIs, input validation, appropriate Content Security Policy controls, dependency management, and regular security testing to reduce XSS risk.
For a broader explanation of web application attack protection, see Kovendo's web application security and WAF guide.
Do Not Store Secrets Just Because It Is Convenient
Avoid placing passwords and highly sensitive credentials into localStorage or sessionStorage. IndexedDB is not automatically a secure vault either; JavaScript running in the same origin can interact with application data.
Use Secure Cookies for Appropriate Sessions
When cookies are used for session management, consider Secure, HttpOnly, and SameSite attributes according to the application's threat model.
Do Not Cache Private Responses Carelessly
The Cache API can retain responses beyond the immediate request. Avoid blindly caching personalized or sensitive responses, and use versioned caches with explicit cleanup during service-worker updates.
11. Common Browser Storage Mistakes
- Putting thousands of records in localStorage. Use a database-oriented storage mechanism for structured datasets.
- Assuming IndexedDB has a fixed universal quota. Browser storage quotas are implementation and environment dependent.
- Putting sensitive credentials in Web Storage. XSS can expose values accessible to JavaScript.
- Using cookies for large application data. Cookies are transmitted with HTTP requests and are not intended to be a general-purpose database.
- Ignoring QuotaExceededError. Storage writes can fail and should be handled gracefully.
- Using Cache API as a database. Cache API is designed around request/response caching.
- Leaving obsolete caches indefinitely. Version and clean up caches during service-worker lifecycle updates.
- Using WebSQL for a new application. Prefer modern, actively maintained browser storage APIs.
12. Browser Storage for Progressive Web Apps
Progressive Web Apps often combine several browser capabilities instead of relying on one storage API.
A practical PWA architecture might look like this:
- Cache API: application shell, JavaScript, CSS, images, fonts, and selected network responses.
- IndexedDB: products, documents, user-generated content, offline records, and synchronization queues.
- localStorage: small UI preferences such as theme or language.
- sessionStorage: temporary tab-specific workflow state.
- Cookies: server-managed session information where appropriate.
PWA design principle: separate application data from network resources. IndexedDB and Cache API solve different problems and can complement each other.
13. Storage Strategy and Modern Web Applications
Browser storage is increasingly important as applications become more interactive, offline-capable, and client-heavy. The storage layer should therefore be considered part of the application's architecture rather than a small JavaScript implementation detail.
When working on data-heavy applications, understanding how structured information moves through a system is equally important. Developers building analytical or intelligent applications can also explore Kovendo's practical machine learning development guide for a broader perspective on building data-driven systems.
For applications that expose interactive tools directly in the browser, Kovendo's online browser-based tools provide another example of how computation and user interaction can happen directly in the web environment.
Modern AI-powered interfaces also increasingly depend on controlled client-side rendering. Kovendo's A2UI protocol guide explores how structured messages can be translated into controlled user interfaces without allowing arbitrary generated code to directly control the rendering layer.
For readers evaluating AI-enabled applications, Kovendo also provides an open source AI model comparison that can help place browser-based application architecture in the wider AI development context.
14. A Simple Browser Storage Decision Framework
Before selecting an API, ask five questions:
- How much data am I storing? Small settings may fit Web Storage; large datasets usually need IndexedDB or another suitable mechanism.
- What kind of data is it? Key-value settings, structured records, and HTTP resources have different storage requirements.
- How long should it live? Temporary state, persistent preferences, and offline data have different lifetimes.
- Does the server need the value? If it must accompany HTTP requests, a properly configured cookie may be appropriate.
- What happens if the browser removes it? Design applications so recoverable client-side storage can be rebuilt or synchronized when appropriate.
Quick decision: Use localStorage for small preferences, sessionStorage for temporary tab state, IndexedDB for structured offline data, Cache API for network resources, and secure cookies for appropriate server-managed sessions.
15. Frequently Asked Questions
There is no single best option. localStorage suits small persistent preferences, sessionStorage suits temporary tab-specific state, IndexedDB suits structured application data, Cache API suits network resources, and cookies suit appropriate server-managed sessions.
IndexedDB is more appropriate when an application needs structured data, large datasets, indexes, transactions, asynchronous operations, or offline-first behavior. localStorage is simpler for small key-value preferences.
Current MDN guidance describes approximately 5 MiB of local storage per origin and approximately 5 MiB of session storage per origin. Applications should handle quota errors rather than assuming storage will always be available.
Yes. IndexedDB is designed for significant amounts of structured browser data, but its available quota is browser and environment dependent rather than a universal fixed number.
Developers should carefully evaluate the security implications before putting sensitive authentication material in JavaScript-accessible storage. For server-managed sessions, appropriately configured HttpOnly cookies can prevent JavaScript from directly reading the session identifier.
No. WebSQL is a legacy technology whose specification is no longer actively maintained. New applications should use modern browser storage technologies such as IndexedDB and the Cache API where appropriate.
A PWA can use multiple technologies together. IndexedDB is suitable for structured application data, while the Cache API is designed for cached network resources. localStorage and sessionStorage can handle smaller pieces of UI or workflow state.
Conclusion
The question is not simply whether localStorage or IndexedDB is "better." The right choice depends on the type, size, lifetime, security requirements, and access pattern of the data.
For small persistent preferences, localStorage remains convenient. For temporary tab-specific state, sessionStorage can be appropriate. For structured offline application data, IndexedDB provides a much more capable database-style model. For offline web resources, the Cache API is designed for the job. For server-managed sessions, properly configured cookies remain an important part of web application architecture.
The strongest browser storage strategy is therefore usually a combination of technologies rather than a single API. By separating application data, temporary state, cached resources, preferences, and authentication state, developers can create web applications that are more resilient, responsive, maintainable, and secure.
Final takeaway: Choose browser storage according to the workload, not the popularity of the API. Small key-value data belongs in Web Storage; structured offline data belongs in IndexedDB; network resources belong in Cache API; and authentication should be designed around appropriate server-side session controls.

Comments
Post a Comment