# Display Media Request Handling with Timeout and Caching in Fluxer

> Explore Fluxer's display media request handling architecture. Discover how in-memory coalescing, network timeouts, and FFmpeg guards ensure reliable image and video delivery.

- Repository: [Fluxer/fluxer](https://github.com/fluxerapp/fluxer)
- Tags: architecture
- Published: 2026-03-17

---

**Fluxer processes display-media requests through a layered pipeline that combines in-memory request coalescing, network timeouts, and FFmpeg-level execution guards to serve transformed images and videos reliably.**

The `fluxerapp/fluxer` repository implements a robust media-proxy service designed to handle external display-media requests—such as signed URLs pointing to images or videos—while preventing redundant processing and ensuring strict timeout enforcement at every I/O boundary. This architecture guarantees that concurrent identical requests are deduplicated, upstream fetches are bounded by network timeouts, and CPU-intensive media operations are guarded by process-level timeouts.

## Architecture Overview

The request flow follows a deterministic pipeline orchestrated by `ExternalMediaController`. When a client requests a proxied media asset, the system first verifies the cryptographic signature, generates a cache key from the URL and transformation parameters, and checks the `InMemoryCoalescer` for an existing in-flight promise. On cache miss, the controller fetches the asset via `HttpClient`, validates the MIME type, optionally transforms it through `MediaTransformService`, and streams the response back with proper HTTP Range support.

```

Client → ExternalMediaController
      → verifySignature / parse query
      → cacheKey = `${proxyUrl}_${signature}_…`
      → InMemoryCoalescer.coalesce(cacheKey, async () => {
            fetchAndValidate(url)          ← HttpClient (network timeout)
            → getMimeType / validateMedia
            → if transforms → MediaTransformService
                 → FFmpegUtils (probe / thumbnail / frame extraction)
                    → execFile(..., {timeout})
                    → throws FFmpegTimeoutError on timeout
            → return {data, contentType}
         })
      → Range handling (parseRange)
      → setHeaders + ctx.body(toBodyData)

```

## Core Components

### ExternalMediaController

Located at [`packages/media_proxy/src/controllers/ExternalMediaController.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/controllers/ExternalMediaController.tsx) (lines 16-33), this controller serves as the entry point and orchestrator. It handles signature verification, query parameter parsing, and coordinates the interaction between the caching layer and transformation services. The controller also manages response headers and range-request parsing for efficient streaming.

### InMemoryCoalescer

The `InMemoryCoalescer` class ([`packages/media_proxy/src/lib/InMemoryCoalescer.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/lib/InMemoryCoalescer.tsx), lines 33-63) provides request deduplication by maintaining a map of in-flight promises keyed by deterministic cache keys. When multiple concurrent requests arrive for the same resource and transformation parameters, only one upstream fetch is initiated; subsequent requests receive the same promise. This component emits metrics for `media_proxy.cache.hit` and `media_proxy.cache.miss` to track coalescing efficiency.

### HttpClient with Timeout Protection

The `HttpClient.sendRequest` method ([`packages/media_proxy/src/controllers/ExternalMediaController.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/controllers/ExternalMediaController.tsx), lines 76-90) executes the upstream HTTP fetch. Non-200 responses are captured and converted into metric-tagged errors (`media_proxy.external.upstream_error`), allowing the system to distinguish between network failures and application-level errors.

### MediaTransformService

When transformation parameters (width, height, format, quality) are present, `MediaTransformService` ([`packages/media_proxy/src/controllers/ExternalMediaController.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/controllers/ExternalMediaController.tsx), lines 43-55) coordinates the conversion pipeline. It delegates CPU-intensive operations to `FFmpegUtils` while maintaining timeout context throughout the transformation chain.

### FFmpegUtils and Timeout Enforcement

The `FFmpegUtils` module ([`packages/media_proxy/src/lib/FFmpegUtils.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/lib/FFmpegUtils.tsx), lines 35-45 and 78-90) wraps FFmpeg and ffprobe calls using `execFile` with explicit timeout options. When an operation exceeds its allocated time, the utility throws a custom `FFmpegTimeoutError`. This error propagates to calling services like `FrameService`, which converts it into either a graceful fallback or a structured HTTP 400 response.

## Request Coalescing and Caching Strategy

Fluxer employs an **in-memory request coalescing** strategy rather than long-term caching. The cache key is constructed from:

- The original media URL
- The cryptographic signature
- Transformation parameters (width, height, format, quality, animation flag)

This deterministic key ensures that identical requests receive identical processing. The `InMemoryCoalescer` stores only the promise for the duration of processing; once resolved, the entry is immediately removed. This approach prevents stale data while eliminating redundant work for concurrent requests, significantly reducing load on upstream resources and improving latency under high concurrency.

## Timeout Management at Every Layer

### Network Fetch Timeouts

The `HttpClient` enforces network-level timeouts during the initial upstream fetch. If the external server fails to respond within the configured window, the promise rejects and the controller records a `media_proxy.external.upstream_error` metric. This prevents worker threads from hanging on slow external resources.

### FFmpeg Operation Timeouts

All FFmpeg operations—probing, thumbnail generation, and frame extraction—execute via `execFile` with per-operation timeout configurations ([`packages/media_proxy/src/lib/FFmpegUtils.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/lib/FFmpegUtils.tsx)). When the OS-level timeout is exceeded, the utility throws `FFmpegTimeoutError`. The `FrameService` catches this specifically ([`packages/media_proxy/src/services/FrameService.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/media_proxy/src/services/FrameService.tsx), lines 38-44):

```typescript
} catch (error) {
    logger.error({error, source: filename}, 'Failed to extract media frames');
    if (error instanceof FFmpegTimeoutError) {
        throw new Error(`Frame extraction timed out: ${error.operation}`);
    }
    return {frames: []};
}

```

This layered timeout approach ensures that neither network I/O nor CPU-intensive media processing can indefinitely block the request pipeline.

## Error Handling and Observability

The architecture emits structured metrics and tracing spans throughout the request lifecycle. Key metrics include:

- `media_proxy.cache.hit` and `media_proxy.cache.miss` for coalescing performance
- `media_proxy.external.upstream_error` for external fetch failures
- Custom counters for `FFmpegTimeoutError` occurrences

Tracing spans cover the signature verification, cache lookup, external fetch, and transformation phases, providing end-to-end visibility into latency bottlenecks. When timeouts occur, the system returns clear error messages to clients while logging detailed context for operators.

## Summary

- **In-memory request coalescing** via `InMemoryCoalescer` eliminates duplicate processing for concurrent identical requests, improving throughput and reducing upstream load.
- **Deterministic cache keys** incorporate the URL, signature, and all transformation parameters to ensure consistent behavior.
- **Network timeouts** enforced by `HttpClient` prevent hanging on slow external servers.
- **FFmpeg timeouts** using `execFile` with custom `FFmpegTimeoutError` handling guard against runaway media processing.
- **Comprehensive metrics** for cache hit rates, upstream errors, and timeout events enable operational monitoring and debugging.

## Frequently Asked Questions

### How does Fluxer prevent duplicate requests for the same media asset?

Fluxer uses the `InMemoryCoalescer` class to deduplicate concurrent requests. When a request arrives, the system generates a deterministic cache key and checks if an identical request is already being processed. If found, the new request receives the existing promise rather than initiating a separate fetch or transformation workflow.

### What happens when an FFmpeg operation times out?

When an FFmpeg operation exceeds its configured timeout, `FFmpegUtils` throws a custom `FFmpegTimeoutError`. This error propagates to the calling service—such as `FrameService` or `ExternalMediaController`—which either returns a graceful fallback (such as the original unmodified media) or an HTTP 400 error with a clear timeout message, depending on the operation context.

### Does Fluxer cache the actual media files in memory?

No, Fluxer does not cache the final media bytes in memory. The `InMemoryCoalescer` caches only the **promise** representing the in-flight work for a specific cache key. Once the promise resolves, the entry is removed from the coalescer. This design prevents memory bloat from large media files while still eliminating redundant processing for concurrent requests.

### How are cache keys constructed for display-media requests?

Cache keys are constructed deterministically from the original URL, the cryptographic signature, and all transformation parameters including width, height, format, quality settings, and animation flags. This ensures that requests with different transformations receive separate processing pipelines while identical requests benefit from coalescing.