Back to experience

Archiving 11,000+ short-form videos, fully self-hosted

Solo Build · Personal Project · Self-Hosted · Docker · 2025 - Present

Short-form videos you save aren't really yours: they live on someone else's servers and vanish when a video is taken down or an account goes private. I built a self-hosted archive that pulls everything I'd favorited onto my own disk, indexes it, and streams it back through a fast web interface. No cloud, no account, nothing leaving the machine.

PythonFastAPIReactTypeScriptSQLiteDocker
Data-flow diagram: saved short-form media is pulled by a resumable, concurrent downloader, indexed in SQLite alongside a local media store, and served by a FastAPI backend with HTTP range streaming to a virtualized React interface and an optional Plex library, all running self-hosted with no cloud services.
11,000+
media items archived & streamable
Self-hosted
fully local, no cloud services
Docker
one-container deploy
  • Resumable, concurrent downloads that never restart from zero.
  • SQLite index keeps 11,000+ items de-duplicated and queryable.
  • FastAPI range streaming for instant seeking and scrubbing.
  • Virtualized React UI stays smooth thousands of items deep.
  • Optional Plex export to watch the archive anywhere.

The problem

I'd favorited thousands of short-form videos over the years, and they kept disappearing: deleted posts, private accounts, dead links. A 'saved' list is only a bookmark to content someone else controls, not a copy of it.

Archiving that much media is its own problem. Downloads fail and have to resume without starting over, 11,000+ files need to stay organized and de-duplicated, and browsing a library that large has to feel instant instead of loading everything at once.

What I built

  1. 1

    Download resumably, in parallel

    I built a concurrent downloader that fetches many items at once and checkpoints its progress, so an interrupted run picks up exactly where it stopped instead of re-downloading what it already has.

  2. 2

    Index everything in SQLite

    Every item is recorded in a SQLite index with its metadata, so the archive can dedupe, track what's already downloaded, and answer queries against 11,000+ entries without scanning the disk.

  3. 3

    Stream it back with FastAPI

    A FastAPI backend serves the media with HTTP range requests, so videos seek and scrub instantly and the browser only pulls the bytes it needs instead of whole files.

  4. 4

    Browse thousands of items smoothly

    The React front end is virtualized, rendering only the rows on screen, so scrolling a library thousands of items deep stays smooth. The whole thing ships as a Docker container and can optionally export into a Plex library.