Back to articles
Technology Insight

Building a Self-Hosted Video Hosting Platform with Bun, ElysiaJS, and FFmpeg on a Budget VPS

June 3, 2026

Introduction: The Cost of Video Scale and the Self-Hosted Alternative

In the digital landscape, video content is king. However, for startups, content creators, and enterprise operations alike, hosting video can quickly become a financial bottleneck. Relying on platforms like YouTube exposes your brand to external algorithms and advertisements, while premium alternatives like Vimeo or specialized CDNs can rack up massive monthly bills as your bandwidth scales. Fortunately, modern open-source technology enables us to build a robust, high-performance self-hosted video hosting platform on a budget Virtual Private Server (VPS) for a fraction of the cost.

By combining the blazing speed of Bun, the high-throughput architecture of ElysiaJS, and the unparalleled processing power of FFmpeg, you can create an end-to-end video pipeline. This pipeline handles everything from secure file uploads and asynchronous video transcoding to adaptive bitrate streaming. This article will guide you through the architectural design, implementation steps, and optimization strategies to make this system viable on cheap hardware.

The Modern Stack: Why Bun, ElysiaJS, and FFmpeg?

To run a resource-heavy application like video processing on a cheap VPS (e.g., 1-2 vCPUs, 2GB RAM), selecting an efficient software stack is non-negotiable. Traditional Node.js frameworks often introduce unnecessary overhead. Here is why our chosen stack excels:

  • Bun: A modern JavaScript runtime built from scratch using the Zig programming language and the WebKit WebCore engine. Bun acts as a fast runner, HTTP server, and package manager all in one. Its native file I/O operations and low memory footprint make it ideal for handling large video file buffers.
  • ElysiaJS: A TypeScript framework designed specifically for Bun. It is famously known for its extreme performance, beating Node.js frameworks like Express by magnitudes in requests per second. Furthermore, ElysiaJS offers native strict-typing via TypeBox, making API validation seamless.
  • FFmpeg: The swiss-army knife of multimedia processing. It handles decoding, encoding, transcoding, and packaging video streams. We will use FFmpeg to convert heavy uploaded videos into web-optimized, compressed formats, and slice them for adaptive streaming.

Architectural Overview of the System

A reliable video platform cannot process videos synchronously on the main thread; doing so would freeze the API and crash your VPS. Our self-hosted platform utilizes an asynchronous pipeline structured as follows:

  1. Upload Layer: Client uploads raw video chunks via an ElysiaJS multi-part form endpoint.
  2. Storage Layer: The raw file is safely saved into a temporary local directory.
  3. Queue & Processing Layer: A background worker triggers FFmpeg to process the video into multiple resolutions (e.g., 480p, 720p, 1080p).
  4. Streaming Layer: The output is formatted using HTTP Live Streaming (HLS) protocols, creating a .m3u8 playlist file along with segmented .ts video files.
  5. Delivery Layer: ElysiaJS streams these static segments efficiently back to the user's client-side video player (such as Video.js or HLS.js).

Step-by-Step Core Implementation

1. Setting Up the ElysiaJS Server

First, initialize your project using Bun. The lightweight setup lets us create a pristine structure. We define our main server file to accept multipart form uploads, enforcing file size and type boundaries to protect our VPS from malicious or oversized inputs.

Note: On low-cost servers, it is recommended to limit concurrent uploads to avoid running out of RAM during buffer aggregation.

2. Integrating FFmpeg for Asynchronous Transcoding

Once the file hits our server, we hand it off to an asynchronous process executing a spawned FFmpeg command. To ensure a seamless user experience across fluctuating network conditions, we transcode the video into HLS (HTTP Live Streaming). HLS splits the video into small, 10-second segments, meaning the client only downloads what they are currently watching rather than buffering the entire 500MB file at once.

The fundamental FFmpeg command string utilized within our Bun backend looks similar to this:

ffmpeg -i input.mp4 -codec:v libx264 -codec:a aac -hls_time 10 -hls_playlist_type vod -hls_segment_filename "output_%03d.ts" output.m3u8

Using Bun's native Bun.spawn or node:child_process, this task runs directly on the OS level. Because encoding is heavily CPU-bound, we restrict FFmpeg to a single thread or use the low-priority nice command on Linux to keep the ElysiaJS API responsive to other web traffic.

Optimizing a Cheap VPS for Video Workloads

Running this architecture on a $5-to-$10 per month VPS requires aggressive optimization. Without tweaking, FFmpeg will quickly trigger the Linux Out-Of-Memory (OOM) killer or saturate CPU cycles completely. Implement these strategies to maintain stability:

  • Configure SWAP Memory: If your VPS only has 1GB or 2GB of physical RAM, create a 2GB to 4GB SWAP file on your SSD. While slower than RAM, it prevents your server from hard-crashing during intensive encoding spikes.
  • Throttle FFmpeg CPU Usage: Use the -threads 1 or -preset ultrafast flags in FFmpeg. While ultrafast results in slightly larger file sizes, it drastically reduces CPU crunch time, preventing server timeouts.
  • Leverage Object Storage Offloading: Local SSD space on cheap virtual servers is limited. Implement a cron job or background script that automatically uploads completed .ts and .m3u8 files to an affordable S3-compatible object storage provider (like Cloudflare R2 or Backblaze B2) and deletes them locally.
  • Implement Nginx Caching: Place an Nginx reverse proxy in front of ElysiaJS. Nginx can cache the static .ts video segments efficiently, meaning repeat views of the same video bypass your Bun application entirely, reducing resource consumption to near zero.

Conclusion: Freedom and Full Control Over Your Media

Building your own video hosting platform is no longer reserved for large enterprises with massive budgets. By utilizing Bun's fast runtime, ElysiaJS's lightweight throughput, and FFmpeg's robust media processing, you unlock complete control over your media distribution pipelines. You escape restrictive vendor pricing, maintain absolute ownership of your data, and gain invaluable engineering insight into distributed multimedia architectures—all running seamlessly on a low-cost virtual private server.