Technical Deep DiveFeb 2026 (6 min read)

Architecting a Real-Time Audio Streaming Pipeline with FastAPI & Redis

Decoupling stream extraction, transcode jobs, and multi-worker audio piping to achieve sub-second playback startup.

FastAPIPythonRedisAudio ProcessingCelery
Abstract

How we built a scalable, distributed audio extraction and streaming backend for the Myra music platform, overcoming rate-limits, cold starts, and network jitter.

1. The Challenge of Low-Latency Audio Streaming

When building the backend for Myra Music, our primary performance metric was Time-to-First-Audio (TTFA). Standard approaches that download an entire audio stream, transcode it synchronously on disk, and then return a static URL resulted in 4–8 second delays on cold cache hits. To achieve sub-second audio startup times across mobile and web clients, we needed a fully streaming architecture where audio chunks begin piping to the client socket within 250 milliseconds of the request.

Core Bottleneck: Synchronous yt-dlp extraction blocks the Python GIL and event loop. Resolution requires asynchronous subprocess offloading and distributed worker queues.

2. The Distributed Pipeline Architecture

We designed a three-layer pipeline: 1. **Edge Gateway (FastAPI ASGI)**: Validates requests, checks two-tier cache (in-memory LRU + Upstash Redis), and immediately dispatches stream jobs. 2. **Worker Pool (Celery + yt-dlp)**: Background extractors resolve direct HLS/DASH media manifests with rotating proxy fallbacks. 3. **Chunked Stream Transcoder**: Pipes raw audio through an FFmpeg subprocess directly into FastAPI's `StreamingResponse` using non-blocking async generators.
stream_service.pypython
import asyncio
from fastapi import FastAPI, HTTPException
from fastapi.responses import StreamingResponse
import redis.asyncio as redis

app = FastAPI()
redis_client = redis.from_url("redis://localhost:6379")

async def audio_stream_generator(audio_url: str):
    """Pipes FFmpeg transcode chunks directly to ASGI response buffer."""
    cmd = [
        "ffmpeg",
        "-reconnect", "1",
        "-reconnect_streamed", "1",
        "-reconnect_delay_max", "2",
        "-i", audio_url,
        "-f", "mp3",
        "-acodec", "libmp3lame",
        "-b:a", "192k",
        "-vn",
        "pipe:1"
    ]
    process = await asyncio.create_subprocess_exec(
        *cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.DEVNULL
    )
    
    try:
        while True:
            chunk = await process.stdout.read(64 * 1024) # 64KB chunks
            if not chunk:
                break
            yield chunk
    finally:
        if process.returncode is None:
            process.kill()

@app.get("/api/v1/stream/{track_id}")
async def stream_track(track_id: str):
    cached_url = await redis_client.get(f"stream:{track_id}")
    if not cached_url:
        cached_url = await resolve_stream_url(track_id)
        await redis_client.setex(f"stream:{track_id}", 3600, cached_url)
        
    return StreamingResponse(
        audio_stream_generator(cached_url.decode("utf-8")),
        media_type="audio/mpeg",
        headers={"Accept-Ranges": "bytes", "Cache-Control": "public, max-age=3600"}
    )

3. Tiered Caching Strategy & Benchmarks

Audio streaming endpoints have high read amplification. We structured the caching strategy into two tiers: - **L1 In-Memory LRU**: Hot metadata and search queries (sub-1ms retrieval). - **L2 Redis (Upstash)**: Pre-resolved stream URLs with TTLs aligned with CDN token expirations (5ms retrieval). Under simulated load tests of 1,500 concurrent listeners, the caching layer absorbed 92% of extraction requests, reducing average server CPU utilization by 65% and lowering TTFA from 4.2s to 380ms.

Key Engineering Takeaways

  • Decouple extraction from streaming via Celery task queues to avoid blocking asynchronous ASGI worker loops.
  • Implement a two-tier caching layer (in-memory LRU for hot metadata + Upstash Redis for signed audio stream URLs).
  • Use chunked transfer encoding (`Transfer-Encoding: chunked`) to start client audio buffers before full transcode completes.
  • Build resilient proxy rotation with fallback mechanisms to maintain 99.9% audio stream availability.