blogprojectshajspace
Back to blog

indexeddb ate my user's recording

·3 min read

A user on Android Chrome recorded a 4-hour meeting. Hit stop. Nothing showed up. No file, no recording session, just "Recording Not Found" errors everywhere.

I got woken up at 5am for this.

what happened

The weird part: the recording kept going even after the failure started. The failure only manifested at the very end.

Time Event
T+0m Recording started, session created successfully
T+0m → T+xm Recording running normally
T+xm ???????
T+240m User hits done, nothing's there

We save audio in 5-second chunks, tracked by a session record. We have checks on every chunk to verify the session exists. But something nuked the session at some point, and the recorder kept chugging along anyway.

the investigation

I couldn't replicate it. Tried everything. Finally, I manually deleted the IndexedDB entry for that session.

Same issue, replicated successfully.

So something deleted our IndexedDB entry. We don't have code that deletes session entries. Either .put() failed silently, or the browser did something.

the rabbit hole

While debugging, I found a post by @pesterhazy called The Pain And Anguish Of Using IndexedDB. Turns out IndexedDB is notoriously unreliable across Firebase, PouchDB, Amplify—basically anyone who thought browser storage was a good idea.

The post documented:

  • Safari randomly deleting storage after a few days
  • Transactions hanging without throwing
  • .put() failing silently but resolving anyway
  • Chrome tab throttling and memory pressure breaking data with no trace

Our situation:

text
- store.put succeeds at start
- Random deletion happens without QuotaExceeded or any error
- No stack traces, nothing

This wasn't a bug we could fix. We literally don't know what caused it.

the rewrite

Since we couldn't prevent this class of failure, we rewrote the recording flow to survive it:

  • Fail loudly when something goes wrong (no silent failures)
  • Redundancy via background uploads to cloud storage
  • Separate metadata from chunks
  • Verification on every read to confirm data exists and is ordered correctly

IndexedDB will still do whatever it wants. But now when it breaks, the system screams instead of silently losing four hours of someone's work.

the lesson

I don't trust any storage that resolves without verification. If a write says "done," I verify it actually wrote. If a session disappears, the system halts immediately. If storage breaks, recovery kicks in from another source.

Never trust blindly. Add redundancy even when you're sure it'll work. Because I don't want another 5am wake-up call because I trusted a "well-documented" browser API.

Back to blog