In Argo CD, what does a sync window configured on an AppProject do, and what happens when an allow window and a deny window overlap?
answer
- a schedule plus a duration, not a range
- deny always wins
- adding an allow window forbids everything else
- manual sync is the emergency exit
basics
~20 sAn Argo CD sync window is a recurring time range on an AppProject during which syncing its matching applications is allowed or denied. Deny windows take precedence, so an overlapping deny blocks the sync even while an allow window is active.
solid answer
~40 sSync windows live in an AppProject's `spec.syncWindows`. Each entry has a `kind` of `allow` or `deny`, a cron `schedule`, a `duration`, an optional `timeZone`, and selectors — `applications`, `namespaces`, `clusters` — that decide which of the project's applications it covers. The semantics are worth stating precisely: once any allow window exists for an application, syncing is blocked outside it; and an active deny window always wins over an active allow window. That combination is how you express a change freeze. Each window also carries `manualSync`, which when true still permits a human-initiated sync during a deny period while automated syncs stay suppressed — the usual setting for an emergency fix during a freeze. Windows can be managed with `argocd proj windows add` as well as by editing the project YAML.
code
bash · 8 linesargocd proj windows add team-a \
--kind deny \
--schedule '0 22 * * *' \
--duration 10h \
--applications 'prod-*' \
--manual-sync
argocd proj windows list team-ago deeper
Know that Argo CD can restrict when an application is allowed to sync, and that the setting lives on the AppProject rather than on each Application.
Explain the field set — kind, schedule, duration, selectors, manualSync — and state both precedence rules: deny wins, and defining an allow window blocks all other times.
Bring the operational consequence: during a freeze, self-heal is suspended too, so drift accumulates visibly as OutOfSync applications that someone must watch and clear afterwards.
Own whether time-based freezes are the right control at all versus progressive delivery and fast rollback, and how exceptions during a freeze are authorised rather than improvised.
## What the feature is for GitOps reconciliation is continuous by design: merge a change and the agent applies it. Sync windows are the pressure valve on that — a project-level statement that syncing may only happen at certain times, or must not happen at certain times, without anyone disabling automation or reverting Git. The typical uses are a nightly or weekend freeze, a business-hours-only policy for a regulated environment, and a scheduled maintenance window during which a batch platform is allowed to change. ## The shape of a window ```yaml apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: team-a namespace: argocd spec: syncWindows: - kind: deny schedule: '0 22 * * *' duration: 10h timeZone: Europe/Berlin applications: - 'prod-*' manualSync: true ``` The fields: - **`kind`** — `allow` or `deny`. - **`schedule`** — a cron expression giving the moments the window *opens*. It is a start time, not a range. - **`duration`** — how long the window stays open from each start, written like `10h` or `30m`. Together, schedule plus duration define the range; a window that should cover a whole weekend is one start with a long duration, not a cron trying to express a span. - **`timeZone`** — evaluates the schedule in a named zone. Omit it and the controller's zone applies, which is a classic source of "the freeze started an hour late" during daylight-saving shifts. - **`applications`, `namespaces`, `clusters`** — selectors, with globs, matching which of the project's applications the window covers. An application is in scope if it matches any selector on the window. - **`manualSync`** — permits a user-triggered sync while the window would otherwise block it. ## The precedence rules Two rules do all the work, and interviewers ask about them because people guess wrong: 1. **Deny beats allow.** If any deny window covering the application is currently active, the sync is blocked, no matter how many allow windows are also active. 2. **Allow windows are exclusive.** If at least one allow window covers an application, then syncing outside every allow window is blocked. Defining an allow window is therefore not a permissive act — it converts "always allowed" into "allowed only then". That second rule is the one that surprises teams: adding a friendly-looking allow window for the deploy hours silently forbids everything else, including the automated sync that was previously reconciling drift around the clock. ## What is actually blocked A blocked window stops the sync operation, both the automated one and, unless `manualSync` is set, the operator-initiated one. It does not stop Argo CD from noticing drift: the application still refreshes and still reports `OutOfSync`, so what you see during a freeze is a growing set of applications correctly showing pending changes. The UI and `argocd app get` surface the active window and why syncing is prevented. Self-healing behaves the same way — during a deny window, drift introduced directly in the cluster stays until the window closes. That is a genuine tradeoff to name in an answer: a freeze on deployment is also a freeze on automatic correction. ## Managing them Beyond editing the project, the CLI has direct support: ```bash argocd proj windows add team-a \ --kind deny --schedule '0 22 * * *' --duration 10h \ --applications 'prod-*' --manual-sync argocd proj windows list team-a ``` ## Where the boundary sits Sync windows are a mechanism, not a release policy. Deciding whether your organisation should freeze deployment at all, and what the exception process looks like, is an operations decision; the interview question here is whether you know what the object does, that deny wins, and that a lone allow window is restrictive rather than permissive.
- During an Argo CD deny window, what does an application with automated self-heal enabled actually do if someone edits a resource directly in the cluster?Nothing corrective. The application still refreshes and reports OutOfSync, and the UI shows the active window as the reason no sync is running, but self-heal cannot apply until the window closes. That is the real cost of a freeze: you also freeze automatic drift correction, so a freeze period needs someone watching the OutOfSync list.
- Why is timeZone worth setting explicitly on a sync window?Without it the cron schedule is evaluated in the controller's own zone, which is frequently UTC while the freeze was written in local business hours. The mismatch shows up as a window starting an hour early or late, and it moves twice a year with daylight saving. Naming an IANA zone such as Europe/Berlin makes the window mean what the policy document says.
saying these in an interview costs you the question
- Thinks an allow window merely permits and changes nothing else
- Believes an allow window overrides an overlapping deny window
- Reads schedule as a time range instead of a start time
- Assumes a deny window stops drift detection, not just syncing
- Expects manual sync to work during a freeze without enabling it