QuestionsSystem Design

Design a resilient file uploader

RADIOHardSystem Design

Design a file uploader that handles large files with progress, retries, concurrency limits, and resilience to flaky networks.

What it tests

Chunking strategy, concurrency control, retry/backoff, and progress aggregation under real network conditions.

Approach & answer

Requirements: upload large files (hundreds of MB+), show accurate progress, survive transient failures, don't saturate the network, and ideally resume. Architecture — chunking is the core idea: slice each file with Blob.slice() into fixed-size chunks (e.g. 5MB) and upload them independently. This unlocks everything else: per-chunk retry (a failed chunk re-sends alone, not the whole file), resumability (ask the server which chunks it already has and skip them), and parallelism. Concurrency: run a bounded worker pool (e.g. 3-4 in-flight chunks) rather than firing all at once — too many parallel requests hurt throughput and hit browser connection limits; a simple queue drains work as slots free. Retry with exponential backoff + jitter on 5xx/network errors, capped at N attempts, so a blip self-heals without hammering the server. Progress: track bytes-sent per chunk and sum across chunks for whole-file percentage — use XHR's upload.onprogress (fetch lacks upload progress without streams) or a stream-based approach. Resilience extras: on final failure surface a retry affordance; pause/resume by stopping and restarting the queue; use an upload-session id so the server can assemble chunks and detect duplicates idempotently. Validate type/size client-side before starting, and compute a hash for integrity if the backend supports dedupe. Edge cases: user navigates away (warn/beforeunload), duplicate submissions, and very small files (skip chunking).

Use this technique when

Any 'design an uploader / resilient network transfer' prompt; reasoning about chunking, backoff, and concurrency caps.

Complexity

Bounded concurrency c keeps memory/connections O(c·chunkSize); total transfer parallelized across the pool.

References

js