Lightning-Fast Video Server on a $8 Droplet (Go + Nginx + SQLite)

✍️ Intro (why this setup)

Modern stacks are heavy.

Most tutorials still push full LEMP stacks—Linux, Nginx, MySQL, PHP—even when your app doesn’t need them. On a small 1GB server, that approach wastes memory and kills performance before you even start.

This setup takes a different direction:

  • No MySQL
  • No PHP
  • No unnecessary services

Instead, it focuses on what actually matters for a video-first app:

  • fast startup time
  • low memory usage
  • smooth playback on mobile networks

⚡ The idea behind this setup

The goal is simple:

Make videos start instantly, even on a tiny server

To achieve that, we combine:

  • Go → lightweight backend (low RAM, fast response)
  • SQLite → zero overhead database (no separate server)
  • Nginx → efficient static + video delivery
  • FFmpeg (FastStart) → videos playable before full download

This avoids the biggest bottleneck:

heavy background services eating your RAM


🧠 Why not LEMP?

A traditional LEMP stack:

  • MySQL alone can use 300–400MB RAM
  • PHP-FPM adds more overhead
  • Leaves very little room for actual work (like video processing)

On a 1GB droplet, that’s a problem.

With this setup:

  • total base usage stays low
  • more memory is available for real tasks (video + users)

🎯 What this is good for

  • MVPs and experiments
  • video-based apps (like short clips / reels)
  • solo developer projects
  • learning how to build efficient systems

⚠️ What this is NOT

This is not:

  • a “scale to millions instantly” setup
  • a fully hardened production environment

It’s a fast, minimal foundation you can build on.


🔥 Final thought

Instead of starting big and optimizing later, this approach flips it:

Start small, fast, and efficient—then scale only when needed

#!/bin/bash

set -e

echo "Starting lightweight video server setup..."

# -----------------------------
# 1. EMERGENCY RAM (2GB SWAP)
# -----------------------------
# Helps prevent crashes on 1GB droplets during FFmpeg spikes
fallocate -l 2G /swapfile || true
chmod 600 /swapfile
mkswap /swapfile || true
swapon /swapfile || true
grep -q swapfile /etc/fstab || echo '/swapfile none swap sw 0 0' >> /etc/fstab

# Reduce swap aggressiveness
sysctl vm.swappiness=10

# -----------------------------
# 2. KERNEL TUNING (TCP BBR)
# -----------------------------
# Improves network performance (especially mobile users)
grep -q "fq" /etc/sysctl.conf || echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
grep -q "bbr" /etc/sysctl.conf || echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p

# -----------------------------
# 3. INSTALL CORE PACKAGES
# -----------------------------
apt update
apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring ffmpeg snapd

# -----------------------------
# 4. INSTALL NGINX (WITH BROTLI)
# -----------------------------
mkdir -p /etc/apt/keyrings

curl -fsSL https://extras.getpagespeed.com/deb-archive-keyring.gpg \
  | tee /etc/apt/keyrings/getpagespeed.gpg >/dev/null

echo "deb [signed-by=/etc/apt/keyrings/getpagespeed.gpg] https://extras.getpagespeed.com/ubuntu $(lsb_release -sc) main" \
  | tee /etc/apt/sources.list.d/getpagespeed-extras.list

apt update
apt install -y nginx nginx-module-brotli

# -----------------------------
# 5. INSTALL GO
# -----------------------------
snap install go --classic

# -----------------------------
# 6. PREPARE APP DIRECTORIES
# -----------------------------
mkdir -p /var/www/app/videos
mkdir -p /var/www/app/db
chown -R www-data:www-data /var/www/app

# -----------------------------
# 7. BACKUP DEFAULT NGINX CONFIG
# -----------------------------
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup || true

# -----------------------------
# 8. OPTIMIZED NGINX CONFIG
# -----------------------------
cat <<'EOF' > /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

# Load Brotli modules (comment out if Nginx fails to start)
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

events {
    worker_connections 2048;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Core performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;

    # Brotli (for text assets only)
    brotli on;
    brotli_comp_level 4;
    brotli_static on;
    brotli_types text/plain text/css application/javascript application/json image/svg+xml;

    # Logging (minimal)
    access_log off;
    error_log /var/log/nginx/error.log crit;

    server {
        listen 80;
        server_name _;

        root /var/www/app;
        index index.html;

        # -------------------------
        # VIDEO SERVING (FAST)
        # -------------------------
        location /videos/ {
            alias /var/www/app/videos/;

            sendfile on;
            tcp_nopush on;
            tcp_nodelay on;

            add_header Cache-Control "public, max-age=31536000, immutable";
            add_header Access-Control-Allow-Origin *;
            add_header Accept-Ranges bytes;
        }

        # -------------------------
        # GO BACKEND API
        # -------------------------
        location /api/ {
            proxy_pass http://127.0.0.1:8080;
            proxy_http_version 1.1;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;

            proxy_buffering off;
        }
    }
}
EOF

# -----------------------------
# 9. RESTART NGINX
# -----------------------------
nginx -t && systemctl restart nginx

echo "Setup complete. Your lightweight video server is ready."