Update: as confirmed in the bug I logged, this was fixed in Firefox 123!
See also: Keep your Indexed DB keys and values small if you want good performance! and Don’t store arrays of numbers in Indexed DB – use base64 instead.
We had performance problem in Element Web when upgrading the Indexed DB schema, and it turned out that in Firefox, deleting an object store can be incredibly slow. It can take tens of minutes or even hours.
(In Chromium the same operation can take tens of seconds, but it’s way, way faster.)
I was expecting this to be a near-instant operation, so this was a definite surprise to me.
Note that my analysis is based on widely-available browsers in February 2024, and will probably become out-of-date.
You can see the full graphs here: artificialworlds.net/indexed-db-perf/delete.html. Source code is at codeberg.org/andybalaam/indexed-db-perf.
Here’s what I learned:
Headline 1: Firefox can take a very long time to delete an object store
Firefox took 20 minutes to delete an object store containing 200K records, with one index.
In Chromium, I found that deleting a similar object store took 21 seconds, which is still slow, but rather more acceptable.
Consider not deleting stores you don’t need any more. If you must delete them, you will need to provide feedback to your users, especially if they are using Firefox.
Headline 2: Clearing the store before deleting it really helps(!)
On both Firefox and Chromium, running objectStore.clear() before upgrading the db and deleting the store made a significant improvement to the total time. On Chromium it more than halved the time to delete the store, and on Firefox (where the numbers were huge) it reduced the time by about 3 times!
Thanks to michael-p on Stack Overflow for giving me the idea.
Clear your store before deleting it.
Headline 3: With no indices, this is fine
Firefox deletes object stores fairly fast if there are no indices (and so does Chromium).
Even for 200K records, Firefox can delete an object store in under 500ms if there is no index on it.
If you need fast deletion, don’t use indices.
Observation: It’s not done until the DB is closed
In my timing experiments, I found that objectStore.delete() completed, but the operation was not really done. When I called the close() method on my IDBDatabase I had to wait a whole lot longer. (The close time is included in the measurements above.)
Even when I refreshed the browser, I found I had a long wait to open the Indexed DB database. After the wait, it worked fine and the schema update was complete.
Expect long close times after a deletion.