MCPcopy Index your code
hub / github.com/MrRobotoGit/tiramisu

github.com/MrRobotoGit/tiramisu @v1.9.11

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.9.11 ↗ · + Follow
2,669 symbols 8,573 edges 303 files 859 documented · 32%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README
████████╗ ██╗ ██████╗   █████╗  ███╗   ███╗ ██╗ ███████╗ ██╗   ██╗
╚══██╔══╝ ██║ ██╔══██╗ ██╔══██╗ ████╗ ████║ ██║ ██╔════╝ ██║   ██║
   ██║    ██║ ██████╔╝ ███████║ ██╔████╔██║ ██║ ███████╗ ██║   ██║
   ██║    ██║ ██╔══██╗ ██╔══██║ ██║╚██╔╝██║ ██║ ╚════██║ ██║   ██║
   ██║    ██║ ██║  ██║ ██║  ██║ ██║ ╚═╝ ██║ ██║ ███████║ ╚██████╔╝
   ╚═╝    ╚═╝ ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚═╝     ╚═╝ ╚═╝ ╚══════╝  ╚═════╝

Tiramisu is the most advanced BitTorrent engine and FUSE virtual filesystem for live streaming to your private Plex/Jellyfin library. Forget Real-Debrid.

Ask DeepWiki Docker Pulls Docker Image Size

[!NOTE] This project used to be called GoStream. It is now Tiramisu, same project, same codebase, just a new name. Nothing about how it works has changed, and everything in this README still applies. If you are upgrading from an older install, note that the binary name, config paths, and systemd service name have all changed too, so a fresh run of the install script is the easiest way to pick up the new layout.


Tiramisu exposes a custom FUSE virtual filesystem where every .mkv file is a perfect illusion: it looks like a real file on disk, but every byte is served live from a BitTorrent swarm on demand. No downloading. No temp files. No storage quota.

The BitTorrent engine runs inside the same OS process as the FUSE layer, connected by an in-memory io.Pipe(). When Plex/Jellyfin reads a byte range, there is no HTTP round-trip, no serialization, no proxy overhead, just bytes, flowing directly from peers through RAM to the media server at full speed.

The result: 4K HDR Dolby Vision, fully seekable, starting in 0.1 seconds, even on a Raspberry Pi 4.

This is not a torrent client with a media server bolted on. The FUSE filesystem is the product, custom-built from scratch around the constraints of torrent streaming: non-sequential byte-range requests, multi-gigabyte files that must be seekable at any position, and a Plex/Jellyfin scanner that probes every file in a library of hundreds of titles on startup.

Tiramisu: click play on a torrent, streaming starts in about a second

What's included

  • Custom FUSE virtual filesystem: every .mkv is a live torrent presented to the media server as a real file. No temp files, no persistent downloads, torrent data never touches the disk.
  • The embedded torrent engine is GoStorm, a fork of TorrServer Matrix 1.37 and anacrolix/torrent v1.55, running in-process with the FUSE layer (no separate HTTP proxy). Both upstreams carry targeted streaming patches not present in the originals.
  • Built-in sync engine discovers trending and popular titles from TMDB on a schedule, finds the best torrent via Prowlarr (with Torrentio fallback), and registers them automatically. All in pure Go, no Python, no external scripts. Existing entries are upgraded when a better version becomes available (e.g. 1080p → 4K HDR).
  • TV Series sync runs on schedule with a fullpack-first season pack strategy and a Plex-compatible directory structure.
  • Add a title to your Plex cloud watchlist and it shows up in your library within the hour.
  • NAT-PMP for WireGuard setups: Tiramisu requests an inbound port mapping from the VPN gateway and installs iptables REDIRECT rules, all without a restart.
  • A peer blocklist of ~700,000 IP ranges is downloaded on startup and refreshed every 24 hours, injected into the torrent engine before any connection is made.
  • Plex & Jellyfin Webhook integration: media.play triggers Priority Mode with aggressive piece prioritization. IMDB-ID is extracted from the raw payload via regex, so it works even when the media server sends localized titles. Jellyfin is supported natively via JSON body, no code change, no plugin hacks.
  • The embedded Control Panel at :9080/control lets you adjust all FUSE and engine settings live, compiled directly into the binary.
  • The Health Monitor Dashboard at :9080/dashboard shows a real-time speed graph, an active stream panel with movie poster and quality badges, sync controls, and system stats, all embedded in the Go binary.
  • Adaptive Chunk Size keeps playback smooth on any file, any bitrate, without manual tuning: the buffer scales itself to what the file actually needs instead of using one fixed size for everything.
  • AdaptiveShield automatically balances speed against data integrity: it runs fast by default and only slows down to verify data more strictly when it detects a peer sending bad data, then relaxes again once the swarm proves clean.
  • TailHedge kills the specific kind of stutter caused by a single slow peer holding up the exact byte the player needs right now, by quietly asking a second peer for the same data and using whichever arrives first.
  • PEXChurn speeds up cold starts by dropping peers that turn out to be useless for the file you are actually watching, freeing connection slots for peers that can actually help.
  • Everything ships as a single binary: GoStorm engine, Tiramisu, metrics, control panel, and webhook receiver in one tiramisu executable.

Control Panel

Tiramisu Control Panel overview


Table of Contents


The Setup: Tiramisu + Plex/Jellyfin/Infuse on Apple TV

Not a developer? This section explains what you actually get and why it works so well.

Plex library populated by sync scripts

The end result: you open Infuse on your Apple TV, your entire movie library appears with posters and metadata, you press Play on a 4K Dolby Vision film and it starts in under a second. No buffering. No "downloading...". No subscription to Real-Debrid or any external service. Everything runs on a single board computer or any always-on Linux box in your home.

How the three pieces fit together

Tiramisu runs on your Linux device, a Raspberry Pi, a NAS, a VPS, or any always-on machine. It creates a virtual hard drive that looks completely real to the rest of your network: it contains thousands of .mkv files, each the correct size, each seekable. In reality, none of those files exist on disk. When anything reads a byte, Tiramisu silently fetches it in real-time from the BitTorrent network and passes it through.

Plex (or Jellyfin, or any media server) sees this virtual hard drive as a normal media library. It scans the files, downloads posters and descriptions from the internet, tracks what you've watched, and makes everything available on your home network, just like it would with a real NAS.

Infuse on Apple TV connects to your Plex/Jellyfin library and plays the files using Direct Play: it reads the video stream directly from the file, with no conversion or re-encoding. This is why it handles 4K HDR Dolby Vision effortlessly, even though it is coming from a torrent in real time.

Because Tiramisu exposes standard .mkv files on a standard filesystem, any player or media server that can read a network share works: Plex, Jellyfin, Emby, Kodi, VLC, mpv, or anything else. No plugins, no special configuration.

How your library gets populated automatically

Tiramisu includes a built-in sync engine that runs on a schedule and keeps your library up to date without any manual intervention.

Every day, the engine queries TMDB (The Movie Database) for the latest releases, trending titles, and popular movies. For each title it finds, it searches Prowlarr (with Torrentio fallback) for the best available torrent (preferring 4K Dolby Vision, falling back to 1080p). If a good torrent is found, it registers it in GoStorm and creates the corresponding virtual .mkv file in the library.

The next time the media server scans, it finds a new file, downloads the poster and description, and the film appears in your library ready to play.

If a better version of a film becomes available later (for example a 4K HDR release of a title you already have in 1080p), the engine replaces it automatically.

TV series work the same way: the sync engine finds new seasons and episodes, organises them in the Plex/Jellyfin-compatible folder structure (Show Name (Year)/Season.01/), and they appear in your library within the week.

You can also add a title to your Plex Watchlist from any device and it will appear in your library within the hour.

Prowlarr Integration (Resilience)

To ensure the system remains functional even when public aggregators like Torrentio are down, Tiramisu includes a Prowlarr Adapter. This allows you to use your own self-hosted Prowlarr instance as the primary source for torrents.

The sync engine implements a Strict Fallback logic: it first queries your Prowlarr indexers using IMDB IDs for maximum precision. If no results are found locally, it automatically falls back to Torrentio.

Configuration is done via config.json (or the Control Panel → Prowlarr Indexer section):

"prowlarr": {
  "enabled": true,
  "api_key": "your-api-key",
  "url": "http://192.168.1.x:9696"
}

See the Prowlarr Adapter Documentation for technical details.

100% local, no subscriptions

Tiramisu has no external dependency at playback time. No third-party service, no monthly fee, no data leaving your home. Your library is always available, even without an internet connection, and it never disappears because a remote service went down.

Why Infuse starts in under a second

When you press Play, Infuse immediately reads the beginning and end of the file to load the video index and seek tables. On a real hard drive this is instant. Tiramisu replicates this with an SSD warmup cache: the first 64 MB and last few MB of every file are pre-cached on the Pi's SSD during the initial Plex/Jellyfin library scan. By the time you press Play, those bytes are already on disk and Infuse gets them in milliseconds.

Why your library survives a reboot

Every file on a real filesystem has a permanent ID called an inode. Plex/Jellyfin and Infuse use these IDs to recognize files across restarts, so they know "this is the same film I scanned last week" and do not re-download metadata or reset your watch history.

On a standard virtual filesystem, these IDs are random and change every time the system restarts. Tiramisu solves this by persisting a permanent inode map to a SQLite database (STATE/tiramisu.db). After a reboot, every virtual .mkv gets back the exact same ID it had before. To Plex/Jellyfin and Infuse, it is indistinguishable from a file that never moved.

When you press Play: the full chain

  1. You press Play on Infuse (Apple TV) -> Infuse requests the file from Plex/Jellyfin
  2. Plex/Jellyfin reads the file from Tiramisu's virtual filesystem
  3. Plex or Jellyfin sends a webhook to Tiramisu: "user started playing this film"
  4. Tiramisu identifies the torrent from the IMDB ID and switches to Priority Mode: all bandwidth focuses on the film you are watching, background activity is paused
  5. Bytes flow: BitTorrent peers -> Tiramisu RAM -> Plex/Jellyfin -> Infuse -> your TV
  6. If you seek, Tiramisu jumps directly to that position in the torrent with no re-buffering from the start

How the Magic Works

Plex/Jellyfin reads /mnt/tiramisu-mkv-virtual/movies/Interstellar.mkv. From Plex/Jellyfin's perspective, it's a normal 55 GB file on a local disk. In reality, the file does not exist. The FUSE kernel module intercepts the read, calls into Tiramisu, and Tiramisu serves the exact bytes from a three-layer cache, backed by a live BitTorrent swarm.

Layer What Size Purpose
L1 In-memory Read-Ahead 256 MB 32-shard concurrent buffer with per-shard LRU
L2 (optional) SSD Warmup Head 64 MB/file Instant TTFF on repeat playback, served at 150–200 MB/s from SSD
L3 (optional) SSD Warmup Tail 16 MB/file MKV Cues (seek index), Plex/Jellyfin probes the end of every file before confirming playback

What makes this non-trivial: a FUSE filesystem that backs a real directory of static files is straightforward. A FUSE filesystem that must handle non-sequential byte-range requests across hundreds of files, each backed by an independent torrent with variable peer availability, while a Plex/Jellyfin scanner hammers every inode in parallel: that required building every subsystem from scratch.


Architecture

``` BitTorrent Peers ←→ GoStorm Engine

Extension points exported contracts — how you extend this code

Syncer (Interface)
Syncer is the interface all sync engines must implement. [6 implementers]
internal/syncer/scheduler/scheduler.go
PieceCompletion (Interface)
Implementations track the completion of pieces. It must be concurrent-safe. [23 implementers]
internal/anacrolix-torrent/storage/piece-completion.go
Logger (Interface)
Logger interface for optional logging. [2 implementers]
internal/metadb/db.go
Logger (Interface)
Logger interface for compatibility [2 implementers]
internal/vfs/inodemap.go
GoStormDB (Interface)
(no doc) [4 implementers]
internal/gostorm/settings/gostormdb.go
Client (Interface)
Client refreshes a media server library section.
internal/catalog/mediaserver/client.go
Syncer (Interface)
Syncer is the interface all sync engines must implement. [6 implementers]
internal/syncer/engines/syncer.go
ClientImpl (Interface)
Represents data storage for an unspecified torrent. [5 implementers]
internal/anacrolix-torrent/storage/interface.go

Core symbols most depended-on inside this repo

Printf
called by 398
internal/vfs/inodemap.go
Unlock
called by 291
internal/anacrolix-torrent/deferrwl.go
Lock
called by 180
internal/lockmgr/locks.go
Add
called by 139
internal/anacrolix-torrent/request-strategy/peer.go
TLogln
called by 129
internal/gostorm/log/log.go
gc
called by 122
main.go
String
called by 114
internal/anacrolix-torrent/peer-impl.go
Close
called by 107
internal/anacrolix-torrent/socket.go

Shape

Method 1,612
Function 550
Struct 400
TypeAlias 45
Interface 44
FuncType 18

Languages

Go100%

Modules by API surface

internal/anacrolix-torrent/torrent.go217 symbols
internal/anacrolix-torrent/client.go105 symbols
main.go85 symbols
internal/anacrolix-torrent/peerconn.go71 symbols
internal/anacrolix-torrent/peer.go61 symbols
internal/syncer/engines/tv_go.go44 symbols
internal/syncer/engines/movie_go.go37 symbols
internal/anacrolix-torrent/mse/mse.go36 symbols
internal/anacrolix-torrent/piece.go35 symbols
internal/vfs/inodemap.go34 symbols
internal/monitor/collector/collector.go34 symbols
internal/anacrolix-torrent/t.go34 symbols

For agents

$ claude mcp add tiramisu \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page