Browser Storage Limits
How Much Chat History Can IndexedDB and OPFS Really Hold?

Published August 21, 2026

When people first hear that a chat app keeps its history in the browser instead of on a server, the same question comes up almost immediately: doesn't the browser run out of room? It sounds like a real constraint. Browsers are for web pages; surely they cannot hold years of conversations, hundreds of generated images, a folder's worth of uploaded PDFs.

The short answer is that the ceiling is far higher than most people guess — usually tens of gigabytes, often more — and that plain text cannot realistically fill it in a lifetime of chatting. The longer answer is more interesting, because the number itself is only half the story: the way people actually lose a local chat archive is almost never by hitting the quota. This article walks through the real per-browser numbers, does the arithmetic for chat history specifically, and ends with the limits that matter more than capacity. If you first want the plain-language explanation of what IndexedDB and OPFS actually are, start with our companion piece on local browser storage for AI chats — this article picks up where it leaves off.

One pool per site: how the quota actually works

The first thing to understand is that there is no separate "IndexedDB limit" and "OPFS limit." Browser storage is governed per origin — one website, as the browser defines it — and IndexedDB, OPFS and the other storage APIs all draw from a single shared pool for that origin. A chat app that keeps message records in IndexedDB and file data in OPFS is spending one budget, not two.

The second thing: the quota is not a fixed number written into the browser. It is calculated from your disk — specifically, from its total size. A site on a laptop with a 1 TB drive gets a far bigger allowance than the same site on a 64 GB tablet. Free space is a separate matter: the quota itself is derived from total capacity, but a drive that is genuinely running out of room can fail writes and trigger eviction long before any nominal ceiling is reached.

Third: you can simply look at yours. Open your browser's developer console on any site and run await navigator.storage.estimate() — the browser reports an estimate of how many bytes the site is using and how many it may use. It is an estimate rather than an exact accounting — browsers deliberately round the figures, partly to resist fingerprinting, and the reported headroom is not a promise that every byte of it is writable — but it turns an abstract discussion into two concrete numbers for your own machine.

Finally, storage comes in two modes. By default everything is "best-effort": the browser keeps it, but reserves the right to evict it if the device runs critically low on space. A site can call navigator.storage.persist() to request an upgrade to persistent storage, which protects against that pressure-driven eviction — the browser decides whether to grant it, and it never protects against the user clearing site data.

The numbers, browser by browser

These are the per-origin ceilings as the browser makers document them today. Treat them as ceilings, not promises — they change between versions, and the browser can always decide to give less on a constrained device.

BrowserRoughly how much one site can storeWorth knowing
Chrome, Edge and other Chromium browsersUp to about 60% of your total diskOn a 256 GB drive, that is on the order of 150 GB for a single site
FirefoxThe smaller of 10% of disk or 10 GiB by defaultThe 10 GiB default is a group cap shared by a site and its subdomains; with granted persistent storage the limit rises to 50% of disk, capped at 8 TiB (Firefox may show a permission prompt)
SafariAround 60% of disk per siteAll sites combined are capped at about 80%; embedded in-app web views get roughly 15%; a separate seven-day deletion rule applies (below)
Any browser, private/incognito windowTypically far less, and only for the sessionStored data is usually discarded when the private session ends

For contrast, the storage most people have heard of — localStorage — holds around 5 MB per site. That three-orders-of-magnitude gap is exactly why serious local-first apps are built on IndexedDB and OPFS rather than on localStorage: one is a sticky note, the other is a filing cabinet backed by your actual disk.

The honest summary of the table: on a typical machine — any drive of 100 GB or more, outside a private window — the smallest default quota you are likely to meet is Firefox's 10 GiB. So the practical question becomes: how far does 10 GiB go when what you are storing is chat history?

What a year of chat text actually weighs

Text is astonishingly small, and it is worth feeling that concretely. The full text of War and Peace — about half a million words — is roughly 3 MB as a plain text file. Most people do not type War and Peace at their AI assistant every year.

Put numbers on a heavy user. Say a typical exchange is a question of a hundred words and an answer of several hundred — call the pair 5 KB of text, which is generous. Fifty exchanges a day, every single day for a year:

  • 5 KB × 50 exchanges × 365 days ≈ under 100 MB of raw text per year.
  • Real storage costs more than raw text — the database keeps timestamps, model labels, conversation structure and search indexes alongside the words, and browser engines have their own per-record overhead. Budget several times the raw figure to be safe.
  • Even at a paranoid 500 MB per year, Firefox's lowest default quota holds about two decades of this. Chromium's ceiling on an ordinary laptop holds centuries.

The conclusion is blunt: for a person typing and reading at human speed, browser text storage is effectively unlimited. No realistic amount of asking, drafting, and reading answers will fill it. If a local-first chat archive ever runs out of room, the text is not what did it.

Images and PDFs are the real payload

Files are a different regime. A single generated image at standard resolution is a few hundred kilobytes as a JPEG; higher-resolution tiers run to several megabytes each. Uploaded documents — scans, contracts, photos — land in the same range. One image can weigh as much as a month of text.

There is also an overhead worth knowing about because it is invisible from the outside: many local-first apps, Secret Chat included, store file bytes as base64-encoded strings — the same form in which the file travels to the model's API — rather than as raw binary. Base64 encodes every 3 bytes as 4 characters, so a stored file is about a third larger than the original. A 3 MB image occupies roughly 4 MB of your quota.

Run the same arithmetic as before, against the same lowest-common 10 GiB: at roughly half a megabyte per stored standard-resolution image, that is on the order of twenty thousand images before the smallest default quota is threatened — and several times that under Chromium's ceiling. A power user generating images all day will get there eventually; a chat-first user will not get there in years.

Two design details in Secret Chat push the practical number further out, and both are visible in its published architecture. Attachments are compressed before they are stored and sent, so a 10 MB phone photo does not cost 10 MB of quota. And every file is stored under a fingerprint of its own content (a SHA-256 hash), which deduplicates automatically: attach the same contract to ten different conversations and it is stored once, not ten times.

What happens if you actually hit the ceiling

Suppose you do fill it. The failure is more polite than people fear. When a write would exceed the quota, the browser rejects that write with a QuotaExceededError — it does not corrupt the database, and it does not silently delete old records to make room. Everything already stored stays exactly where it was; the new thing simply is not saved.

An app then has to tell you, and this is worth checking in any local-first tool you evaluate. Secret Chat catches the quota error and shows a plain message — "Browser's database overflow. Clear obsolete chats and projects!" — rather than failing silently. The fix is what the message says: delete what you no longer need. Because images dominate the budget, deleting a few old image-heavy conversations recovers far more room than deleting months of text ever could, and per-message and per-image deletion means you can prune the heavy items without losing the conversation around them.

One more thing people forget: the quota may be enormous, but the disk under it is real. A drive with no free space left can fail writes and trigger eviction long before any nominal ceiling is reached. Sometimes "browser storage is full" is just "the laptop is full."

The limit you will hit first is not the quota

Here is the part that matters more than any number above. In practice, local chat archives are almost never lost to overflow. They are lost to deletion rules — and those deserve more respect than the quota does.

  • Safari's seven-day rule. With tracking prevention on, WebKit deletes a site's script-writable storage — IndexedDB and OPFS included — after seven days of Safari use in which you never interact with that site. Not seven days of disk pressure; seven days without a click, a tap or typing on the site — WebKit counts interaction, and merely having a page load in the background does not necessarily qualify. For Safari users this is the single most likely way to lose a local archive. Installing the app to the Home Screen exempts it, and actually using it — which for a chat app means clicking and typing — resets the clock.
  • Eviction is all-or-nothing. When a browser does evict a best-effort origin under storage pressure, it removes that origin's stored data as a unit — it does not trim your three oldest chats and keep the rest. Least-recently-used sites go first, which protects the app you open daily and endangers the one you last opened in March.
  • Private windows keep nothing. An incognito session gets its own small, temporary store, discarded when the session ends. History "saved" there was never going to survive the evening.
  • "Clear browsing data" clears it. So do aggressive privacy cleaners and some anti-tracking extensions. The storage is yours, which also means every deletion control you own applies to it.
  • Storage does not follow you. A browser profile's storage belongs to that profile on that device. Switch from Firefox to Chrome, or to a new laptop, and the archive does not come along — and on iOS, a Home Screen web app keeps its own storage separate from Safari's tabs, so installing starts a fresh archive rather than inheriting the old one.

Requesting persistent storage via navigator.storage.persist() blunts exactly one of these — pressure-driven eviction — and none of the others. Which leads to the only durable answer:

Your browser can hold more chat history than you will ever write. What limits a local archive is not capacity — it is the rules under which browsers delete. Export what matters.

Where the archive is worth keeping, use the app's export feature and keep a copy under your own control — our guide to exporting, backing up and migrating local chat history covers how to do that without undoing the privacy you came for, including the fact that an export archive is plaintext and should be stored accordingly.

Why this trade is still worth it

It would be easy to read the list above as an argument against local storage. It is the opposite: it is the cost side of a trade whose benefit side is substantial. A cloud chat archive never evicts and follows you everywhere — because it is a centralized, provider-held record of everything you have asked, tied to your account. A local archive is bounded by your device and your browser's rules — because it is yours, on your machine, with no server-side copy for anyone to breach, subpoena or mine.

Secret Chat takes the local side of that trade deliberately: conversations live in your browser's IndexedDB, uploaded and generated files live in OPFS (falling back to IndexedDB where a browser does not support it), and there is no stored chat archive on our servers — a prompt exists on our side only for as long as it takes to fetch your answer. The quotas above are what make that architecture practical: the browser gives a single site enough room that "my whole history, locally" is not a compromise on capacity. The deletion rules are what make exports necessary. Understanding both is what it takes to rely on it.

Frequently Asked Questions

  1. How much data can IndexedDB store?

    There is no fixed IndexedDB limit — storage is governed by a per-site quota calculated from your disk. Chromium browsers allow one site up to roughly 60% of total disk space; Firefox allows the smaller of 10% of disk or 10 GiB by default (far more with granted persistent storage); Safari allows around 60% of disk. IndexedDB shares this pool with OPFS and other storage APIs.

  2. Do IndexedDB and OPFS have separate storage limits?

    No. Both draw from the same per-origin quota, along with the other storage APIs. An app that keeps chat records in IndexedDB and files in OPFS is spending one shared budget, and navigator.storage.estimate() reports the combined usage.

  3. How many chat messages fit in browser storage?

    More than you can write. A heavy year of chatting — fifty exchanges a day, every day — is under 100 MB of raw text, and even with database overhead it stays in the hundreds of megabytes. Against the smallest common quota of 10 GiB, that is decades of text. Images are what consume the budget: at a few hundred kilobytes to a few megabytes each, tens of thousands of them fit before the smallest default quota is threatened.

  4. What happens when the browser storage quota is exceeded?

    The failing write is rejected with a QuotaExceededError — nothing already stored is lost or trimmed. Secret Chat surfaces this as a visible "database overflow" message asking you to clear obsolete chats and projects; deleting old image-heavy conversations recovers the most space.

  5. Can I increase my browser's storage quota?

    There is no setting to raise it directly — the quota is derived from your disk's total size. A site can request persistent storage with navigator.storage.persist(): in most browsers that protects data from eviction under storage pressure without changing the ceiling, and in Firefox it also raises the ceiling from the 10 GiB default to up to 50% of disk. Nothing survives you clearing site data, and a drive with no free space left can stop writes well below any nominal quota.

  6. If the quota is so large, why did my local chat history disappear?

    Almost certainly a deletion rule, not overflow. The usual suspects: Safari's tracking prevention deletes a site's storage after seven days of Safari use without interacting with it — a click or a tap — (Home Screen web apps are exempt); a private/incognito session discarded it at close; "clear browsing data" or a privacy cleaner removed it; or the device ran critically low on disk and the browser evicted the site's storage as a unit. If the history matters, export it and keep a backup.

Sources