Skip to main content

M3U Proxy Overview

The M3U Proxy is a high-performance HTTP proxy server purpose-built for IPTV streaming. It sits between your media players and IPTV providers, handling stream delivery, failover, transcoding, and monitoring — all without introducing unnecessary overhead.

Design Philosophy

The proxy is built around a true live proxy model: every byte delivered to a client comes directly from the upstream provider with no persistent buffering layer. This means:

  • Zero transcoding by default — pure pass-through for maximum performance
  • Per-client connections — each viewer gets an independent provider connection
  • Immediate cleanup — connections close the moment a client stops watching
  • No shared state — one client's problem never affects another

Stream Types

The proxy automatically detects the stream type and applies the correct delivery strategy.

Continuous Streams (.ts, .mp4, .mkv, .webm, .avi)

Each client receives their own direct connection to the upstream provider:

Client A → Provider (independent connection)
Client B → Provider (independent connection)
Client C → Provider (independent connection)

This is the default mode for live IPTV channels. Key properties:

  • Truly ephemeral — provider connection opens only when the client starts consuming
  • Instant cleanup — connection closes the moment the client disconnects
  • Per-client failover — a failed connection only affects that one client
  • No buffering — raw bytes forwarded directly

HLS Streams (.m3u8)

HLS uses a shared connection model: multiple clients share one upstream connection, and segments are fetched on demand. The proxy rewrites playlist URLs so segments are served through the proxy itself.

  • One upstream connection serves many clients
  • Efficient playlist processing and URL rewriting
  • Shared HTTP client with connection pooling
  • Per-stream failover with seamless playlist switching

VOD Streams (Video on Demand)

VOD streams support full byte-range requests, allowing clients to seek freely within the content:

  • Each client can be at a different position simultaneously
  • Range headers are honoured and forwarded to the upstream
  • Works correctly with all standard video players

Performance Architecture

uvloop

The proxy uses uvloop as the event loop, providing 2–4x faster async I/O than the Python default. It is detected and enabled automatically at startup.

Connection Pooling

HTTP clients are configured with optimised connection limits to maximise throughput while avoiding resource exhaustion:

  • max_keepalive_connections: 20
  • max_connections: 100
  • keepalive_expiry: 30s

Lightweight Stats Tracking

Per-client metrics (bytes served, segments delivered, error counts) are tracked with minimal overhead. No database writes occur during streaming.

Seamless Failover

When an upstream connection fails, the proxy switches to a backup URL with less than 100ms interruption — transparent to the client. Failover is per-client, so a single viewer experiencing a hiccup doesn't impact anyone else.

See Failover for the full architecture and configuration.

Optional Features

The proxy is designed to work well out of the box, but includes several advanced capabilities you can enable as needed:

FeatureDefaultDescription
TranscodingOffFFmpeg-based video transcoding with hardware acceleration
Redis PoolingOffShared streams across multiple workers
Strict Live TSOffEnhanced stability for Kodi and PVR clients
Sticky SessionsOffLock clients to specific load balancer backends
Bitrate MonitoringOffAuto-failover on degraded streams
AuthenticationOffAPI token protection for management endpoints
Event SystemBuilt-inWebhook notifications for stream lifecycle events

Quick Start

The proxy ships as a Docker image. The quickest way to get started is via Docker Compose — see the M3U Proxy Integration deployment guide.

For a standalone run:

docker run -d \
-p 8085:8085 \
-e API_TOKEN="your-secret-token" \
sparkison/m3u-proxy:latest

The proxy starts on port 8085 by default. Visit http://localhost:8085/health?api_token=your-secret-token to confirm it is running.

Further Reading