Skip to content

Settings — Subtitle Automation

The Subtitle Automation page configures the drain worker — a background loop that picks up new library items, decides whether to extract embedded subtitles, and runs post-extract cleanup. It’s the system that takes “Sonarr just imported episode E07” all the way to “subtitle is on disk and the foreign tracks are gone”, with no manual click.

When the library scan or webhook discovers a new item, an entry is pushed onto the drain queue. The drain worker pulls items off the queue at the configured interval and runs the pipeline.

SettingDefaultValuesEffect
EnabledontoggleMaster switch for the drain worker.
Drain interval (min)51–60Minutes between drain ticks.
Auto-extract embeddedontoggleWhen the file has an embedded subtitle in the target language, extract it instead of searching providers.
Cleanup after extractofftoggleAfter successful extract, run foreign-track removal in the same pipeline.
Fallback to provider searchontoggleIf the file has no usable embedded subtitle, fall through to provider search.

For each item the worker pulls off the queue:

  1. Probe the container for embedded subtitle streams.
  2. If a stream in the target language exists and Auto-extract is on → extract.
  3. If extract fails or no embedded stream → search providers.
  4. If a provider returns a candidate that beats the cutoff → download.
  5. If Cleanup after extract is on → run foreign-track removal.
  6. If translation is enabled and the item still lacks the target language → queue translation.
  7. Write the result to the database; emit websocket event for the UI.

Each step writes to Activity → History with timing, so you can audit which step took how long.

Probing is cheap (reads the container header); extraction copies bytes. The worker probes every queued item but only extracts when the result will be used:

Probe outcomeAction
Has target-language embedded streamExtract.
Has target-language embedded stream but it’s image-based (PGS / VOBSUB)Skip extract; image subs need OCR which is a separate pipeline.
No target-language embeddedSkip extract; fall through to provider search.
Container too damaged to probeLog warning; mark item as probe_failed; skip the rest.
SettingDefaultValuesEffect
Drain workers21–8How many items can be in-flight concurrently.
Max concurrent extracts21–8Cap on parallel mkvextract invocations.

Extract is bounded by both knobs — min(drain_workers, max_concurrent_extracts) is the effective limit.

When inbound webhooks are configured (Settings → Connections → Webhooks → Auto-translate on import), the webhook receiver pushes the item directly into the drain queue, bypassing the next scheduled tick. The worker still respects the concurrency limits, but you don’t wait the full drain interval before the work starts.

The Auto-extract embedded flag can be overridden per series under Library → Series detail → Processing override. Useful for series where you specifically want provider subtitles (better translation quality, additional cues, etc.) even when an embedded track exists.

Items can be excluded from drain processing:

SurfaceEffect
Library → Series → PauseDrain queue skips this series until unpaused.
Wanted → SkipDrain queue ignores this item permanently.
Scan ignore patternsFiles matching the patterns never enter the queue.

Items that ended in failed state can be re-queued in batch:

ActionEffect
Settings → Subtitle Automation → Resurrect failedPulls every failed item back to pending and re-queues. Confirm prompt shows count.
Library → Wanted → Filter: failed → Resurrect selectedSame, scoped to selection.

When provider rate limits or hardware constraints make full-speed drain unsustainable, enable Slow Mode:

SettingDefaultEffect
Slow modeoffCaps drain to 1 worker and inserts a 30s delay between items.
Slow mode trigger threshold5 consecutive 429sAuto-engages slow mode when this many rate-limit responses arrive in a row.
Auto-disengageonReturns to normal mode after 1 hour of no 429s.

Slow mode is the difference between “drain crashes against provider rate limits” and “drain runs at provider’s preferred pace, completing eventually”.

The page header shows live drain stats:

TileCounts
QueuedItems waiting to be processed.
RunningCurrently in-flight.
Completed (24h)Successful drains in the last 24 hours.
Failed (24h)Items that ended in failed state.
Average durationMedian wall-clock time per item over the last 24h.