Skip to main content
Version: 0.9.14

Media service operations

The Media service is a private HTTPS cache for generated TTS audio. Caddy (caddy:2-alpine) serves files on GET /media/...; media-upload (voiceai-media-server, built from Go 1.24-alpine onto alpine:3.19) handles authenticated PUT / DELETE /media/.... Data lives on a volume mounted at MEDIA_DATA_DIR (default /mnt/media-data). Static private IP 10.0.1.30.

Instance

Instance vCPU and RAM are in Provision instances.

FieldValue
NetworkPrivate only — static private IP 10.0.1.30
Block storageAttached volume at MEDIA_DATA_DIR (default /mnt/media-data)
ScalableNo — single instance

Endpoints

MethodPathBehavior
GET / HEADhttps://<host>/media/<shard>/<hash>.alaw|pcmCaddy file_server from /data/media/.... Supports HTTP Range / 206.
PUThttps://<host>/media/...Reverse-proxied to media-upload. Optional Authorization: Bearer <MEDIA_UPLOAD_TOKEN>.
DELETEhttps://<host>/media/...Same auth as PUT. Returns 404 if missing.
GEThttps://<host>/healthReturns ok.

Consumers

TelAPI and TelPhi read and write the cache via TTS_MEDIA_CACHE_BASE_URL, TTS_MEDIA_CACHE_UPLOAD_TOKEN, and TTS_MEDIA_CACHE_CA_BUNDLE.

Database metadata

Logical cache rows live in Postgres as TtsMediaCache (tts_media_cache): hash, sentence, voice, model, speed, variants (JSON array of encodings), optional ttl. Bytes stay on the media volume; Tasker can delete blobs via HTTP DELETE and drop rows by ttl.

Capacity

For typical TTS clip sizes and ~1000 concurrent HTTP connections, the reference Media instance size with SSD and raised nofile ulimits (set in the compose file) is usually sufficient. If Caddy CPU or disk I/O saturates, add another media node behind an internal load balancer and shard cache keys — avoid NFS for hot paths if latency matters.

See also