Never Lose an Interview: Resilient Video Uploads from the Browser
Candidates record proctored video interviews on flaky laptops and flakier Wi-Fi. Here is the IndexedDB + Web Worker + resumable-upload pipeline that stopped us from losing recordings.
Never Lose an Interview: Resilient Video Uploads from the Browser
A candidate finishes recording their interview answers, the Wi-Fi drops on the last chunk of a 100MB+ upload, and the recording is gone. They did the work. We dropped it. In a hiring product there is no apology that fixes this — the interview cannot be un-lived, and asking someone to re-record it tells them exactly how much your infrastructure respects their time.
At Navero, candidates record video interview answers directly in the browser — camera, microphone, and sometimes a screen share — so this worst-case failure is the one we engineered the entire upload pipeline around making impossible.
The Problem
Browser recording is hostile territory:
- The candidate closes the tab or the laptop lid mid-upload
- Wi-Fi drops on the last chunk of a 100MB+ recording
- Keeping recorded blobs only in memory means one refresh destroys them
- WebM files produced by MediaRecorder have broken duration metadata, so playback seeking fails downstream
- Naive retry loops spam the candidate with error toasts while silently going nowhere
A plain fetch upload in the page's main thread fails on every one of these.
The Solution: Persist First, Upload Off-Thread, Resume Forever
We rebuilt the pipeline around one principle: the recording is safe the moment it exists, not the moment it is uploaded.
MediaRecorder chunks
|
v
IndexedDB (persisted as recorded — survives refresh and crash)
|
v
Global upload manager (singleton, owns all upload state)
|
v
Web Worker (uploads off the main thread, UI stays responsive)
|
v
Resumable upload session to cloud storage via presigned URLs
(interrupted uploads continue from the last acknowledged byte)
The details that made it production-grade:
- Exponential backoff, bounded. Failed chunks retry with increasing delays up to 5 attempts.
- Retryable versus permanent. Exhausted uploads move to a distinct permanently-failed bucket instead of looping forever — surfaced on a dedicated retry page where the candidate can re-attempt with one click.
- Toast throttling. Transient network errors are batched and de-duplicated so a flaky connection produces one calm message, not a notification storm.
- Metadata repair. WebM duration headers are fixed client-side before upload, so every stored recording is seekable.
Key Lessons
Durability before transport. Writing chunks to IndexedDB as they are recorded turns "the upload failed" from a data-loss incident into a retry.
The main thread is not where uploads live. A Web Worker keeps a multi-hundred-megabyte upload from janking the interview UI the candidate is still using.
Name the terminal state. Distinguishing permanently-failed from retrying made both the code and the support conversations simpler — there is always a truthful answer to "where is my recording?"
Resumable beats restartable. Continuing from the last acknowledged byte is the difference between an invisible blip and re-uploading 100MB on hotel Wi-Fi.
Results
- Recordings survive tab closes, refreshes, and network loss — the candidate can come back and resume
- Uploads run entirely off the main thread; recording UI stays responsive during transfer
- Every recording ends in an explicit state: uploaded, retrying, or permanently failed with a one-click recovery path