Skip to content

Homelab System Architecture

Detailed architectural overview, hardware specifications, networking topology, and resource allocation strategies for the self-hosted homelab.


1. System Topology & Interconnect

flowchart TD
    subgraph Clients ["📱 Client Devices (Encrypted Mesh)"]
        Phone["📱 Mobile Client\n(Tailscale)"]
        Laptop["💻 Laptop\n(Tailscale)"]
        EReader["📖 E-Reader\n(KOReader)"]
        Discord["🤖 Discord App\n(Mobile Widget)"]
        Telegram["🔒 Telegram App\n(Encrypted Bot)"]
    end

    subgraph NetworkMesh ["🔐 Network Ingress"]
        TailscaleMesh["Tailscale WireGuard Mesh\n(MagicDNS: 'homelab')"]
    end

    subgraph Host ["🖥️ HP ProDesk Server (Core 24/7 Stack)"]
        subgraph MediaServices ["Core Media Services"]
            ImmichWeb["Immich Photos\n(:2283)"]
            Navi["Navidrome Music\n(:4533)"]
            ABS["Audiobookshelf\n(:13378)"]
            Calibre["Calibre-Web\n(:8083)"]
        end

        subgraph DatabaseLayer ["Internal Databases & Sidecars"]
            Postgres[("Immich PostgreSQL 14\nVectorChord + pgvector")]
            Valkey[("Immich Valkey Cache")]
            ImmichML["Immich ML Sidecar\n(Profile: 'ml', On-Demand)"]
        end

        subgraph Ingestion ["Mobile Ingestion Pipeline"]
            DiscordBot["Discord Bot\n(Stealth Emoji)"]
            TelegramBot["Telegram Bot\n(AES-256 Crypto)"]
            PipelineEngine["Pipeline Engine\n(yt-dlp + mutagen)"]
        end

        subgraph StorageSubsystem ["💾 Storage Subsystem"]
            AppData["SSD: /srv/docker\n(Databases, Configs, ML Models)"]
            MediaStorage["Bulk Storage: /srv/storage/media\n(Music, Books, Audiobooks, Photos)"]
            DownloadsStorage["Bulk Storage: /srv/storage/downloads\n(Drop-Chute & Scratch)"]
            RestrictedStorage["Bulk Storage: /srv/storage/restricted\n(Private & Sensitive Media)"]
        end
    end

    %% Client Ingress
    Phone -->|WireGuard| TailscaleMesh
    Laptop -->|WireGuard| TailscaleMesh
    EReader -->|OPDS| Calibre
    TailscaleMesh --> MediaServices

    %% Bot Ingestion
    Discord -->|Links & Files| DiscordBot
    Telegram -->|Restricted Links| TelegramBot
    DiscordBot --> PipelineEngine
    TelegramBot --> PipelineEngine

    %% Database & ML Connections
    ImmichWeb --> Postgres
    ImmichWeb --> Valkey
    ImmichWeb -.->|Batch Ingest| ImmichML

    %% Storage Volume Handoffs
    MediaServices --> AppData
    MediaServices --> MediaStorage
    PipelineEngine --> DownloadsStorage
    PipelineEngine --> MediaStorage
    PipelineEngine --> RestrictedStorage

2. Hardware Context & Constraints

  • Host Platform: HP ProDesk 400/600/800 G6 Microtower / SFF
  • CPU: Intel Core i5-10400 (6 Cores, 12 Threads, 2.90 GHz base, 4.30 GHz turbo, Intel UHD Graphics 630 with QuickSync)
  • RAM: 32 GB Dual-Channel DDR4 (2x 16GB Micron DDR4-3200 1Rx8 MTA8ATF2G64AZ, configured for high headroom: ~1.3 GB idle stack leaves >30.5 GB for OS caching, ZFS/Btrfs, local LLMs/Ollama, and active workloads)
  • Storage Subsystem:
  • OS & Appdata Drive (SSD Permanently): High-speed NVMe SSD hosting / and persistent container state (/srv/docker/). SQLite and PostgreSQL databases thrive on SSD 4K random I/O.
  • Bulk Media Storage (/srv/storage/): High-capacity storage hosting media libraries (/srv/storage/media/), staging drop-chutes (/srv/storage/downloads/), and private content (/srv/storage/restricted/). Starts on SSD, designed to migrate cleanly to a dedicated bulk HDD without changing Docker configs.

3. Network Architecture (Tailscale Mesh)

  • Zero Open Ports: No public port-forwarding or dynamic DNS exposed to the public internet.
  • Mesh Connectivity: All connections occur over an encrypted WireGuard mesh via Tailscale.
  • MagicDNS: Devices reach services using friendly DNS names (e.g., http://homelab:2283, http://homelab:4533).
  • Mobile Access: Mobile phones access media and streaming directly through the Tailscale mobile client.
  • E-Reader Sync: E-ink devices running KOReader connect to Calibre-Web's OPDS catalog over Tailscale.

4. Storage Architecture & Directory Schema

The storage layout cleanly separates high-IOPS transactional state (SSD) from bulk sequential media streams (HDD-migration ready). Placing media/ and downloads/ on the same filesystem root (/srv/storage) ensures all intake operations occur via instant, atomic zero-copy inode moves.

Persistent Bulk Storage (/srv/storage/)

Starts on SSD, moves cleanly to HDD later:

/srv/storage/
├── media/
│   ├── music/              # FLAC, MP3, and Opus files (Navidrome)
│   ├── audiobooks/         # Audiobook files organized by Author/Title (Audiobookshelf)
│   ├── podcasts/           # Downloaded and subscribed podcasts (Audiobookshelf)
│   ├── books/              # EPUB, PDF, and MOBI library (Calibre-Web)
│   ├── video/              # Video archives & Jellyfin library
│   └── photos/             # Raw and encoded photos & videos (Immich uploads)
│
├── downloads/              # Atomic staging & ingestion chute
│   ├── intake/             # Drop folder monitored by `make watch`
│   │   ├── music/
│   │   ├── audiobooks/
│   │   ├── books/
│   │   └── video/
│   └── scratch/            # yt-dlp transcoding and assembly working directory
│
└── restricted/             # Isolated partition for private/restricted downloads (Telegram bot)

Application Data & Container State (/srv/docker/)

Databases, runtime configs, and model weights (strictly .gitignored, stays on SSD):

/srv/docker/
├── audiobookshelf/
│   ├── config/             # ABS configuration
│   └── metadata/           # Scraped metadata cache & SQLite state
├── calibre-web/            # User preferences and app settings
├── navidrome/              # Navidrome SQLite database (navidrome.db)
├── immich/
│   ├── postgres/           # PostgreSQL 14 cluster data & VectorChord indexes
│   └── model-cache/        # CLIP and facial recognition models
├── jellyfin/               # Transcode cache & server config (Phase 6)
├── ollama/                 # Local LLM model weights (fast NVMe retrieval)
└── portainer/              # Container management agent data


5. Zero-Idle Performance Verification

During laptop benchmark testing (September 26, 2026), the entire 24/7 core stack yielded the following live resource measurements:

Container Idle CPU Measured Idle RAM Peak Under Load Strategy
navidrome 0.03% 13.8 MB ~200 MB 24/7 background daemon
immich-valkey 0.37% 5.3 MB ~80 MB 24/7 background daemon
audiobookshelf 0.06% 36.2 MB ~500 MB 24/7 background daemon
calibre-web 0.02% 187.8 MB ~300 MB 24/7 background daemon
immich-postgres 0.00% 399.4 MB ~1.0 GB 24/7 background daemon
immich-server 0.17% 697.2 MB ~1.2 GB 24/7 background daemon
Combined Core 0.65% ~1.33 GB ~3.2 GB Zero-idle verified
immich-machine-learning 0.00% 0 MB (Stopped) ~1.5 - 3.5 GB Profile ml (isolated)