localStorage and indexedDB are used for offline storage of data in HTML5. What are their key differences and which one is preferable in what situations?

  • 24
    Close voters: While I completely understand how this seemed "primarily opinion based" (the "vs" in the original version didn't help), the two technologies are distinctly different and there are objective reasons for choosing one over the other. user221287 doing some minimal prior research in the topic of the question and getting a basic understanding of the concepts involved before you ask will most probably save you from downvotes and close votes in the future.
    – yannis
    Commented Dec 1, 2013 at 9:25
  • 1
    You can test performance among different storage options and across browsers here: nolanlawson.github.io/database-comparison (credits to Nolan Lawson) Commented May 3, 2018 at 20:45

3 Answers 3


On the surface the two technologies may seem directly comparable, however if you spend some time with them you'll soon realize they are not. They were designed to achieve a similar goal, client side storage, but they approach the task at hand from significantly different perspectives and work best with different amounts of data.

localStorage, or more accurately Web Storage, was designed for smaller amounts of data. It's essentially a strings only key - value storage, with a simplistic synchronous API. That last part is key. Although there's nothing in the specification that prohibits an asynchronous Web Storage, currently all implementations are synchronous (i.e. blocking requests). Even if you didn't mind using a naive key - value storage for larger amounts of data, your clients will mind waiting forever for your application to load.

indexedDB, on the other hand, was designed to work with significantly larger amounts of data. First, in theory, it provides both a synchronous and an asynchronous API. In practice, however, all current implementations are asynchronous, and requests will not block the user interface from loading. Additionally, indexedDB, as the name reveals, provides indexes. You can run rudimentary queries on your database and fetch records by looking up theirs keys in specific key ranges. indexedDB also supports transactions, and provides simple types (e.g. Date).

At this point, indexedDB might seem the superior solution for every situation ever. However, there's a penalty for all its features: Compared to Web Storage, its API is quite complicated. indexedDB assumes a general familiarity with database concepts, whereas with Web Storage you can jump right in. If you have ever worked with cookies, you won't have an issue working with Web Storage. Also, in general you'll need to write more code in indexedDB to achieve exactly the same result as in Web Storage (and more code = more bugs). Furthermore, emulating Web Storage for browsers that don't support it is relatively straightforward. With indexedDB, the task wouldn't be worth its time. Lastly, before you dive into indexedDB, you should first take a look at the Quota API.

At the end of the day, it's completely up to you if you use Web Storage or indexedDB, or both, in your application. A good use case for Web Storage would be to store simple session data, for example a user's name, and save you some requests to your actual database. indexedDB's additional features, on the other hand, could help you store all the data you need for your application to work offline.

  • 25
    Also, IndexedDB is supported by recent browsers only: IE 10+, Chrome 23+, Firefox 10+, Opera 15+, and Android 4.4+. Commented Mar 19, 2014 at 18:41
  • 1
    @yannis, is there any difference between DOM storage and Web storage? Commented Apr 23, 2017 at 15:20
  • 2
    No, localStorage is not deleted when the browser closes. It only clears when you do it either programmatically or manually (such as in a browser's Dev Tools). However, someone in another SO thread claims it got cleared on him when he updated Chrome.
    – ultrageek
    Commented May 10, 2020 at 19:30
  • 2
    sessionStorage is the one deleted when the browser is closed. Commented May 14, 2020 at 13:40
  • 1
    More specifically, sessionStorage is deleted when the Tab is closed, and each browser tab gets its own separate sessionStorage, so you can't share a sessionStorage instance across multiple tabs, even on the same hostname.
    – diamondsea
    Commented Oct 28, 2020 at 16:04

@yannis answer is excellent. Just want to add a couple of things.

  1. In a few situations, like Service Workers, you cannot use blocking code, hence, you cannot use localStorage, and must use something like indexedDB.

  2. The API for indexedDB is complex and tedious (I'd go so far as to say "horrific", YMMV). There are several "wrapper" libraries to simplify the API, I strongly suggest that you look at those.

  • 2
    re cannot use localStorage and blocking code, could you not wrap the blocking code with a Promise and make it non-blocking ?
    – joedotnot
    Commented Sep 15, 2019 at 11:56
  • @joedotnot Interesting idea that would simplify my life. Have you tried it?
    – user949300
    Commented Nov 20, 2020 at 21:36
  • 2
    Regarding wrapper libraries; I strongly suggest Jake Archibald’s idb wrapper: github.com/jakearchibald/idb
    – Kalaschnik
    Commented Jan 5, 2022 at 12:45

For me, I found that I can store blobs in IndexedDB while in localStorage I can store strings only. It is mean that IndexdDB is better for binary data like images, audio, video. Yes we can store images in base64 in the localStorage, but blobs will be smaller and faster because we do not need to decode them.

Quote from MDN:

The keys and the values are always strings.

About IndexedDB:

Any objects supported by the structured clone algorithm can be stored:  
All primitive types However not symbols
Boolean object   
String object    
RegExp  The lastIndex field is not preserved.
ArrayBufferView This basically means all typed arrays like Int32Array etc.
Object  This just includes plain objects (e.g. from object literals)