Skip to content

Jobs and queues

Almost everything Frameleaf does with a new photo or video happens in the background as jobs: reading its details, making thumbnails, finding faces, indexing it for search, transcoding videos and more. Jobs wait in queues, and the server works through them as fast as its settings allow.

Open Settings, then Compute & jobs to see every queue. For each one you can see how many jobs are active, waiting and failed, and which account and worker each job belongs to. You can:

  • Pause and Resume a queue. Active jobs finish even when their queue is paused; it just stops taking new work. A few essential background queues can’t be paused.
  • Run missing (or Scan missing) to queue only the items that haven’t been processed yet.
  • Reprocess all to run the queue again for every item. For faces, Refresh faces updates results without a full reset, while Reset & reprocess clears generated face results first.
  • Retry failed to put failed jobs back with their saved inputs. Read the error and fix the cause first.
  • Remove failed records or Clear waiting jobs. Neither deletes any original file.
  • Change each queue’s concurrency. See Concurrency below.
  • Create job to start a maintenance task, such as Back up the database, the integrity checks, Generate memories, Clean up unused people or Collect library analytics.

Server-wide actions ask you to review the effect on every account before they run. Filtering the page by account changes only what you see, not what a queue command affects.

The classic Administration, then Job Queues page offers the same queues with All and Missing buttons.

Queues are grouped as Media, Intelligence, Maintenance and System.

Queue What it does Default concurrency
Metadata Reads capture dates, camera details, location and embedded metadata 5
Storage organization Moves files according to the storage template
Thumbnails Makes image previews and thumbnails 3
Playback videos Makes compatible playback copies of original videos 1
Visual search Indexes visual content for smart search 2
Face detection Finds faces before they’re matched to people 2
Face recognition Matches detected faces to people
Text recognition Extracts searchable text from images 1
Photo duplicates Finds visually similar photos
Video duplicates Compares sampled video frames to find duplicate videos 1
Enrichment coordinator Schedules descriptions and Locked-content analysis 2
Descriptions & tags Describes photos and suggests tags 2
Locked-content detection Identifies images to keep Locked 2
Pet recognition Suggests which of your pets appear in photos 1
Media edits Renders saved photo and video edits 2
Media health Inspects missing or damaged files 2
Integrity checks Checks files exist, are known and match their checksums 1
External libraries Rescans your external libraries 5
Metadata sidecars Finds sidecar files or syncs their metadata 5
File migration Moves generated files into their current layout 5
Search maintenance Maintains search records 5
Workflows Runs your workflow actions after library events 5
Notifications Delivers notifications and messages 5
Background tasks Clean-up, coordination and follow-up tasks 5
Database backup Backs up the database

A blank concurrency means the queue has no setting of its own; some queues are fixed at one job at a time to keep operations in order.

Each new upload sets off a chain of jobs:

  1. Metadata is read.
  2. Storage organization moves the file, if the storage template is on.
  3. Thumbnails are made: large, small, blurred and face thumbnails.
  4. Then, in parallel:
    • Visual search indexing, followed by duplicate detection
    • Face detection, followed by face recognition
    • Text recognition
    • Video transcoding, for videos
    • Image enrichment: descriptions, tags and Locked-content detection

Locked-content detection and Descriptions & tags have separate queues, so you can run them independently. For example, classify Locked content first, review the results, then fill in descriptions and tags, without changing settings in between.

  • When both are on, a new upload queues one description job after its thumbnails. That job runs Locked-content detection first if there’s no saved result, then passes the result to the description model.
  • When only Locked-content detection is on, uploads queue it directly.
  • Backfill jobs process images that have previews, and skip deleted, hidden and Locked items. A normal run skips items that already have a result; reprocessing recalculates them, but never adds duplicate AI description: blocks or repeated tags.

See AI descriptions and smart albums.

Some jobs run on a schedule. Set them in Administration, then Settings, then Nightly Tasks Settings:

Setting What it does Default
Start time When the nightly tasks start 00:00
Database cleanup tasks Clean up old, expired data from the database On
Generate missing thumbnails Queue items without thumbnails for thumbnail generation On
Cluster new faces Run face recognition on newly detected faces On
Generate memories Create new memories On
Sync quota usage Update each person’s storage quota usage from what they actually use On

Other scheduled jobs have their own settings: database backups (2:00 AM), integrity checks (3:00 AM) and external library scans (midnight).

Concurrency is how many jobs of a kind each server worker runs at once. Higher values can finish a backlog sooner, but compete for CPU, GPU memory and disk bandwidth, and for machine learning jobs they use more video memory.

  • Concurrency changes join the same Review changes draft as other settings.
  • A new limit applies to the next jobs to start. Lowering it doesn’t cancel active jobs.
  • Values from 1 to 1,000 are accepted.
  • If you add GPUs or split work across containers, raise the machine learning concurrencies to keep them busy.

Restorations aren’t in these queues and never take a queue’s slot. See Workers and where jobs run.

The immich-server container runs several workers:

Worker What it does
api Answers requests from the web and the apps
microservices Runs jobs: thumbnails, video encoding and most other background work
edge Serves remote access and passes requests to api. It does nothing until remote access is on for a linked server

Machine learning runs in its own container, or on other computers; see Workers and where jobs run.

When the container stops (docker compose stop, an upgrade or a NAS package restart), each worker stops taking new work. Running jobs and requests get a grace period to finish. A job still running after that goes back to waiting, so it runs again as soon as the server is back. Jobs that could repeat a side effect, such as sending an email or a push notification, are marked failed instead.

Variable What it sets Default
FRAMELEAF_SHUTDOWN_GRACE_SECONDS How long running work gets to finish 5
FRAMELEAF_SHUTDOWN_DEADLINE_SECONDS When the server exits, whatever is still running 9

The grace period must be shorter than the deadline. Docker kills the container when its own stop timeout ends, so it must be longer than the deadline. The provided Compose files and NAS packages set stop_grace_period: 10s on the server (Unraid: --stop-timeout=10). Keep it if you write your own Compose file, and raise it if you raise the deadline.

If the server is killed or crashes, jobs that were running are picked up again about a minute after the next start.

You can run the workers in separate containers, for example one for the web and API and one for background jobs, by choosing which workers each container runs:

Variable What it does
FRAMELEAF_WORKERS_INCLUDE Run only these workers, comma-separated
FRAMELEAF_WORKERS_EXCLUDE Run every worker except these
  1. Copy the whole immich-server block in docker-compose.yml as a new service. In the copy, change the service and container name and remove the ports section:
immich-server:
container_name: frameleaf_server
ports:
- 2283:2283
frameleaf-microservices:
container_name: frameleaf_microservices
  1. Give each service its workers:
services:
immich-server:
# ...
environment:
FRAMELEAF_WORKERS_INCLUDE: 'api,edge'
frameleaf-microservices:
# ...
environment:
FRAMELEAF_WORKERS_EXCLUDE: 'api'

By default edge runs wherever api runs. When you name workers in FRAMELEAF_WORKERS_INCLUDE, only those run, so include edge alongside api if you use remote access. A container that excludes api doesn’t run edge unless FRAMELEAF_WORKERS_INCLUDE names it. If you run edge in a different container from api, give both containers the same FRAMELEAF_EDGE_SECRET (at least 16 characters).

To spread work across several machines, see Scaling.