How a Photo Becomes an Immich Asset

Immich’s upload path is not a single event. It is a lifecycle that begins on a phone or another client, passes through identity and transport decisions, and then continues through background jobs that make an asset easier to view and find. This chapter follows that lifecycle to explain three practical facts: mobile backup is recurring rather than one-time, duplicate avoidance depends on content identity, and an uploaded original can exist before its search, face, or playback features are ready.

The distinction matters because “backup completed” can mean different things. A client may have sent a file successfully, while the server is still extracting metadata or creating the previews needed by later jobs. Immich treats those stages as related transitions rather than one indistinguishable operation.

Backup begins with a device policy

When mobile backup is enabled, Immich looks for new photos and videos in selected device albums when the app opens or resumes, and it can also run periodically in the background. The user chooses which albums to include and can exclude particular albums. That choice is more than a convenience setting: it defines which part of the device’s changing collection is allowed to enter the server’s archive.

The default networking policy is conservative. Immich uploads over Wi-Fi unless the user changes the backup setting. It can also synchronize the device’s album structure into server-side albums, but the documented synchronization is one-way: the device’s organization is reflected on the server, not treated as a bidirectional agreement in which changes on both sides continually rewrite one another. This protects the meaning of the backup operation. A device album can be a source of organization without becoming the only place where the server’s album state is edited.

The lifecycle starts before the network request. The mobile app must notice an asset, decide that its album is selected, check the current network and device conditions, and schedule the work. On Android, battery optimization on some devices can interfere with background work; the documentation also describes options such as running a background task only while charging or delaying upload after capture. On iOS, Background App Refresh must be enabled, and the operating system decides when the background task runs. Opening the app more often can make the task run more often, but the app cannot dictate the schedule.

This explains a common troubleshooting mistake. If a new phone photo has not appeared on the server, the server may not be the first place to investigate. The device may have excluded the album, deferred the task, required Wi-Fi, or been constrained by battery policy. A healthy API cannot upload a file it has not received. Conversely, a successful manual upload from the same phone can show that connectivity works without proving that background scheduling is configured correctly.

Cloud-backed photos add another transition. The mobile documentation notes that local albums containing iCloud assets may be pulled into the app’s cache before hashing and uploading, then removed from the temporary cache after the process. A large library can therefore consume additional device storage or mobile data even though the intended long-term destination is the Immich server. The original decision—“this album is selected”—can trigger local preparation that the user does not see in the gallery.

Album selection also resolves an ambiguity that is easy to miss on a phone. A device album is a selection boundary, not necessarily a unique storage location: an asset can belong to more than one album. Immich allows specific albums to be excluded, which is useful when an operating system groups content into broad collections that include items the user does not want backed up. The server-side album synchronization option offers a different benefit: it can mirror the device’s organization and can be used to reorganize existing uploads into corresponding albums. Because the sync is one-way, the operator should treat it as a controlled import of organization rather than as a promise that edits on the server will flow back to the device.

That distinction is valuable during a first import. A user may want to begin with a small selected album to confirm that the endpoint, account, storage, and processing pipeline work before sending the entire camera roll. Immich’s quick-start guidance notes that large uploads can take a long time and points users to the job queue while processing continues. Selective backup is therefore both a user preference and a way to reduce the size of the first operational experiment.

Content identity prevents repeated uploads

Once a selected file is ready to be considered for backup, Immich calculates a checksum based on its content. The checksum acts as an identity test for duplicate avoidance. If the same content is already on the server, Immich can skip another upload even when the existing asset arrived through a different route, such as the web interface, the CLI, or another device.

This is a small mechanism with a large practical effect. Imagine that a person imports an older camera archive through the CLI and later selects a phone album containing some of the same images. A filename comparison would be fragile: the paths or names could differ, and two different files could share a name. A content checksum gives the server a way to compare the file’s contents instead. The result is not that the two devices become one device; it is that the archive can recognize when two ingestion attempts refer to the same media content.

Checksum deduplication also makes retries safer. Mobile upload is exposed to interrupted networks and operating-system scheduling, so a client may need to attempt work again. If every retry were treated as a new asset, an unreliable connection would multiply the archive. Content identity allows the upload path to be closer to idempotent: repeating the attempt does not necessarily create another copy of the same content.

The evidence supports the content-based behavior but does not specify Immich’s exact hash algorithm or collision policy. That boundary matters. A checksum is an engineering tool for recognizing matching content; it is not a claim that the system can infer every kind of human duplicate. Two different photographs of the same scene are different files. A resized or edited derivative may also have different content even when a person considers it “the same picture.” The mechanism prevents a defined class of repeated uploads; it does not solve every question about visual similarity.

The feature table also lists support for a broad range of image and video families, including common formats such as JPEG, PNG, HEIC, RAW, MP4, MOV, and MKV. The documentation intentionally points to source code for the complete list rather than presenting the table as exhaustive. For the lifecycle, the important point is not memorizing extensions. Different originals can require different metadata extraction, preview, or transcoding work, and those differences can affect how quickly the later stages become available.

Format support should also be read as a promise about admission, not necessarily identical treatment after admission. A file can be accepted and preserved while its preview, metadata, or playback path follows a different route from another file. Video transcoding creates an additional representation for compatibility while leaving the original in place. That is useful for viewing, but it adds storage and work. The operator should ask which copy is the source of truth and which copy exists to make a particular client experience possible.

From original arrival to derived capability

After the server accepts an asset, background jobs progressively add the information that makes it useful. The documented job order begins with metadata extraction. If the storage-template engine is enabled, storage-template migration follows. Thumbnail generation then creates several kinds of previews, including large, small, blurred, and person previews. Those thumbnails become inputs for smart search, face detection, and OCR, while video transcoding can create a version that plays more broadly. Face detection in turn supplies the starting point for facial recognition.

These are not merely steps in a checklist. They are dependencies. Metadata extraction can establish facts about the file before a later view relies on them. Thumbnail generation creates a normalized, accessible representation for downstream work. Smart search and facial recognition need their own model processing and indexing; they cannot be assumed to exist simply because the original file has been written. The asset moves from “received” to “processed enough for this capability,” with different capabilities reaching readiness at different times.

The relationship can be represented as a sequence of ownership changes. The client begins with a local file and a decision to back it up. The API accepts the transfer and connects it to the server-side asset model. Redis and BullMQ hold the work that needs to happen later. A worker reads or creates media, records metadata and results in Postgres, and calls the machine-learning service when a job needs inference. The original and generated files remain on the filesystem, while the database records the relationships that let Immich find and present them.

sequenceDiagram participant C as Client (mobile, web, CLI) participant A as Immich API participant Q as Redis queue participant W as Background worker participant P as Postgres participant F as Filesystem participant L as ML service C->>A: Send asset for backup A->>P: Check or record asset identity A->>Q: Queue processing work Q->>W: Deliver dependent job W->>F: Read original or write derivative W->>P: Store metadata and processing result W->>L: Request search or face inference L-->>W: Return model output W->>P: Index derived result

The diagram’s sequence is a teaching model of the documented dependency flow, not a promise that every operation is one synchronous request or that every release exposes identical queues. The important transition is from an accepted upload to a series of recorded results. A client can finish sending before the workers finish creating those results.

That difference is visible in ordinary use. An asset can appear in a timeline while a search for its visual content returns nothing because smart search has not processed it. A face may be visible in the image while the person grouping has not been updated. A video may exist in its original format while transcoding is still pending. These are not necessarily contradictions. They are signs that the archive contains a source asset and some, but not all, of its derived capabilities.

Immich exposes administrative job status and queue controls because a lifecycle with asynchronous stages needs feedback. The operator can see processing as work rather than treating the absence of a feature as proof that the upload failed. Some jobs are also scheduled: the documentation describes nightly tasks such as memories generation, in addition to work triggered by a new asset. A large import can therefore have at least three relevant milestones: the client has sent the file, the server has created the core asset state, and the background indexes and derivatives have caught up.

The pipeline also has a resource dimension. Thumbnail generation, transcoding, OCR, contextual search, and face processing do not all cost the same amount, and the project separates heavy work from the interactive API for that reason. A backlog can be a capacity problem rather than a data-identity problem. If a worker is slow, adding another client retry may increase pressure without making the missing preview appear sooner. The useful response is to inspect the stage that is waiting and the conditions it needs.

The dependency graph also creates different meanings for “retry.” Retrying a client upload is appropriate when the file never reached the server or when a transfer was interrupted. Retrying a thumbnail job is a different action: the original may already be safely present, and the missing work is a derived transformation. Re-running facial recognition or smart search can likewise rebuild an index without changing the source media, although it consumes processing time and can be affected by model or configuration choices. Keeping those operations conceptually separate reduces the risk of responding to every visible problem by sending the original file again.

The queue view is useful precisely because it can expose this distinction. A large initial import may produce a long period in which upload activity has slowed or stopped but background work remains. A nightly job may add work that is not tied to a new upload at all. The system’s state is therefore not one progress bar. It is a set of related states: transport may be complete, metadata may be extracted, previews may exist, and learned indexes may still be pending. The documentation gives the dependency order and administrative controls, but it does not promise the same backlog behavior or completion time for every collection.

What the lifecycle preserves—and what it postpones

The lifecycle preserves the original as the anchor and postpones many ways of using it until the required derived state exists. This is a good trade when the alternative would be blocking the upload until every expensive operation completes. It also means the interface must communicate, directly or indirectly, that “present” and “fully indexed” are different states.

There are limits to what the available evidence can promise. The job documentation describes the intended order and the available administrative controls, but it does not establish one completion time, universal retry behavior, or identical performance for every library and hardware setup. The mobile documentation describes platform-specific constraints without guaranteeing that every operating-system release will schedule background work the same way. A reliable mental model therefore tracks transitions and conditions rather than expecting a fixed clock.

For an operator, the practical checks follow the lifecycle. First ask whether the client actually selected and sent the asset. Then ask whether content identity caused a legitimate duplicate skip. If the original is present, inspect which dependent job has not completed. Finally, distinguish a missing derived index from a missing original before changing storage or re-uploading files. That order avoids turning a processing delay into a duplicate archive.

A photo becomes an Immich asset gradually: first as content accepted from a client, then as a record connected to the stored original, and later as a collection of metadata, previews, searchable representations, and possible face groupings. The next question is where those layers actually live. Once the database, managed files, external libraries, and backups are compared, it becomes possible to say what a complete archive contains and what a restore can realistically recover.

References