Skip to main content
Sync hooks control the order and lifecycle of resources applied by Argo CD during a synchronization. They let you run Jobs and other resources at specific points in the synchronization process (for example, to run database migrations before deploying an application or to clean up temporary resources afterward). Common hook phases:
  • PreSync — run before the main sync step.
  • Sync — the normal synchronization of non-hooked resources.
  • PostSync — run after a successful sync.
  • SyncFail — run when a sync fails.
  • PreDelete / PostDelete — run during deletion lifecycles.
The typical sync flow looks like this: the operation begins with PreSync; if PreSync succeeds it proceeds to Sync; if Sync fails, SyncFail hooks run; if Sync succeeds it proceeds to PostSync. Hook cleanup lifecycles (how and when hook resources are removed) are configurable and will be covered elsewhere.
Hook PhaseWhen it runsTypical use case
PreSyncBefore regular resources are appliedRun migrations or prepare state required by other resources
SyncRegular resource application phaseDeploy Deployments, Services, etc.
PostSyncAfter a successful syncRun cleanup tasks or post-deploy verification
SyncFailAfter a sync failureRollback-related tasks or notifications
PreDelete / PostDeleteDuring resource deletionCleanup external state or revoke credentials
A screenshot of an Argo CD documentation page showing a flowchart of sync phases: PreSync -> Sync -> PostSync with success arrows. If Sync fails, an arrow points downward to a red "SyncFail" box.
Example scenario In my GitOps Argo CD Kappa project I have a repository path synchronization/hooks containing three Kubernetes manifests:
  • An Nginx Deployment
  • A database migration Job
  • A cleanup Job
Below is the db-migration Job manifest used in this demo:
# db-migration-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration-job
spec:
  template:
    spec:
      containers:
      - name: db-migration
        image: alpine:3.12
        command:
        - /bin/sh
        - -c
        - |
          echo 'Running Database Migration...' \
          && sleep 15 \
          && echo 'Database Migration Complete.'
      restartPolicy: Never
  backoffLimit: 2
(Note: the cleanup Job in the repository initially had an incomplete annotation; I fixed that and committed the changes.) Application configuration used to deploy these manifests (example settings):
FieldValue (example)
Application namesyncHooks0
Projectdefault
Sync policyAutomatic
Auto-create namespaceEnabled
Repository URL(my repo URL)
Path./synchronization/hooks
Destination clusterhttps://kubernetes.default.svc
Destination namespacesync-hooks-0
When I created the Application, Argo CD started applying the manifests. Because none of the resources had hook annotations initially, Argo CD applied the three manifests concurrently. The result was that the cleanup Job, the migration Job, and the Nginx deployment were all created at the same time.
A screenshot of the Argo CD web UI showing the application "sync-hooks-0" marked Healthy and Synced, with a resource tree displaying components like nginx, cleanup-job, and db-migration-job. The top toolbar shows actions such as Details, Diff, Sync, History and Rollback.
Desired ordering for this demo:
  1. Run the migration Job first.
  2. When the migration Job completes successfully, create the Nginx Deployment.
  3. After the Deployment is ready, run the cleanup Job.
To enforce this ordering, add Argo CD hook annotations to the manifests so that Argo CD executes Jobs at the appropriate sync phases (for example, marking the migration Job as PreSync and the cleanup Job as PostSync). Hooks control execution timing and can also be configured with deletion/cleanup policies. Example annotations you can add to achieve the ordering:
  • Mark the migration Job as PreSync:
metadata:
  annotations:
    argocd.argoproj.io/hook: PreSync
  • Leave the Nginx Deployment as a regular resource (applied during Sync).
  • Mark the cleanup Job as PostSync:
metadata:
  annotations:
    argocd.argoproj.io/hook: PostSync
You can also control hook deletion behavior with annotations such as:
metadata:
  annotations:
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
(See the Argo CD docs for other deletion-policy options.)
By default, Argo CD applies resources concurrently. Use hook annotations (for example, argocd.argoproj.io/hook: PreSync or PostSync) to enforce ordering for tasks like database migrations or cleanup. For full details and advanced hook lifecycle options, refer to the Argo CD Sync Hooks documentation: https://argo-cd.readthedocs.io/en/stable/user-guide/hooks/

Watch Video