Prevent duplicate Immich jobs or imports by first separating two different symptoms: the same background work appearing to run again, and the same photo becoming more than one asset. Then identify which client, importer, library scan, path change, or retry produced the second event before deleting anything.
The safest design gives each asset cohort one canonical ingestion path. A historical cloud archive, an external library, and an active phone backup can all be valid, but overlapping ownership of the same files can create duplicate records or re-upload loops that no amount of post-import cleanup fixes reliably.
Identify Whether You Have Repeated Work or Duplicate Assets
For repeated jobs, capture the queue name, asset ID, start time, completion/failure state, and the event that preceded the new job. A legitimate downstream job created after metadata work is different from the same failed job retrying forever. Do not clear all queues until you know which pattern is present.
For duplicate assets, compare source library, original path, checksum behavior where available, device backup state, capture time, and file size. The same visible picture can exist as two different files after cloud export, metadata edits, transcoding, or path-based external-library handling, while byte-identical files can also exist in different Immich library sources.
If ordinary uploads start producing repeated checksum or unique-constraint errors, preserve the database and inspect migration/schema state before treating the symptom as an import-source problem. Duplicate assets across two legitimate source types and a database constraint failure are different branches and should not share the same cleanup.
The ZimaSpace guide to phone backup state and mobile scheduling is useful because a mobile client has its own view of what still needs backup. Server-side cleanup that ignores the client state can cause the next phone session to send files again.
Use One Canonical Ingestion Path for Each Existing Photo Cohort
Choose how old photos enter Immich before enabling continuous phone backup: for example, import the historical archive once, verify it, then let the phone contribute only new captures. If the same historical files are both mounted as an external library and uploaded through the normal upload library, do not assume global deduplication will reconcile the two sources.
An Immich cross-source duplicate report documents identical content coexisting when it comes from an external library and the upload library. Treat that as a project-behavior boundary: source ownership matters, so prevention is more reliable than expecting a later duplicate utility to infer your preferred copy.
Avoid moving files that Immich uploaded internally into an external library behind its back while the phone still considers them part of its backup set. If the storage architecture must change, migrate through a documented path with backups and a small test cohort, then confirm the mobile app and server agree before deleting the old copy.
Control Retries and Client State Before Scaling the Import
Use a staging manifest for a large manual import: record source path, file count, total bytes, and a stable checksum or importer result where practical. If an import is interrupted, resume through the same tool and destination rather than launching a second independent importer against the same source while the first job state is uncertain.
A recent Immich repeated-upload report showed a mobile client continually retrying assets that the server already had, with unique-constraint errors on the server. Treat it as version-scoped evidence that client backup state can be the loop owner; do not generalize it into a universal mobile-app behavior. Path changes remain a separate risk. Keep container-visible external-library paths stable during a large import, and if a storage move is necessary, migrate a small cohort first. If the second copy appears only after a path change, follow the path-identity branch rather than resetting phone backup state.
Test Interruption, Retry, and a Truly New Asset
Create a small representative cohort that includes ordinary photos, videos, an edited image, and at least one file that already exists in the destination path. Import it once, record asset counts and IDs, then interrupt a second controlled attempt or rescan according to the workflow you plan to use in production.
A pass has no unexplained second asset for the same intended source object, retries settle without a permanently growing queue, and a genuinely new photo still imports successfully. Also reopen the mobile client after the test so its backup state does not silently disagree with the server.
If duplicates return only across upload and external-library sources, redesign the ownership boundary instead of repeatedly merging them. If the same asset ID receives an endless failed job, isolate that job and file. Escalate with source type, paths, hashes where relevant, versions, client backup state, and the smallest reproducible cohort.
Support & Tips
More to Read

How to Optimize Immich Database Connections for Concurrent Containers
Do not raise max_connections first. Measure Immich sessions, total every container's demand, preserve admin headroom, and tune only the proven bottleneck.

How to Repair Immich After Its Database Volume Fills Up
Never delete PostgreSQL WAL to free space. Stop Immich writes, preserve database state, add safe capacity, recover PostgreSQL, then prevent recurrence.

Why Does Immich Recreate Missing Files With the Wrong Owner?
Immich should not silently recreate missing source originals. Identify the regenerated file type and writer, then fix the creation identity.

