> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devhelm.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Drift Detection and Locking

> How DevHelm handles configuration drift, deploy locks, and source-of-truth conflicts

DevHelm detects when resources managed by code are modified through the dashboard or API. Deploy locks prevent concurrent modifications.

## Drift detection

Every time you run `devhelm plan` or `devhelm deploy`, the CLI:

1. Loads your YAML configuration
2. Fetches the current state of each resource from the API
3. Compares the **desired state** (YAML) against the **current state** (API)
4. Reports differences as create, update, or delete operations

The API is always the source of truth for current *values* — drift comparison runs against live data, never a cached copy. Separately, the CLI keeps a local state file at `.devhelm/state.json` that records *which* resources this config manages (name → API ID). It scopes `--prune` to this config's resources, disambiguates renames (via `moved` blocks), and lets you adopt existing resources with `devhelm import`. Inspect it with `devhelm state show`, or rebuild it from the API with `devhelm state pull`.

### What drift looks like

If someone changes a monitor's frequency in the dashboard from `60` to `30`, the next plan shows:

```
~ monitors/API Health
  frequencySeconds: 30 → 60
```

Running `deploy` reverts the dashboard change back to what's defined in YAML.

### Special handling

| Resource           | Drift comparison                                         |
| ------------------ | -------------------------------------------------------- |
| **Secrets**        | Compared by SHA-256 hash (values are write-only)         |
| **Alert channels** | Compared by config hash (sensitive fields not read back) |
| **Dependencies**   | Compared by alert sensitivity and component              |
| **All others**     | Full field-by-field comparison                           |

## Deploy locking

Only one deploy can run at a time per organization. The lock prevents race conditions when multiple CI jobs or team members deploy concurrently.

### How locks work

1. Before applying changes, the CLI acquires a lock via `POST /api/v1/deploy/lock`
2. The lock includes the deployer identity and a 30-minute TTL
3. After the deploy completes (or fails), the lock is released
4. If the lock is held by another session, the CLI exits immediately with exit code `11` (unless `--lock-timeout` is set)

### Waiting for a lock

Use `--lock-timeout` to wait instead of failing immediately:

```bash theme={null}
devhelm deploy -f devhelm.yml --yes --lock-timeout 60
```

The CLI retries every 5 seconds until the timeout expires.

### Skipping the lock

For development or testing, skip locking entirely:

```bash theme={null}
devhelm deploy -f devhelm.yml --yes --no-lock
```

<Warning>
  Skipping locks in shared environments can cause inconsistent state if two deploys run simultaneously.
</Warning>

### Force-unlocking

If a deploy crashes without releasing its lock, force-unlock it:

```bash theme={null}
devhelm deploy force-unlock --yes
```

Only use this when you're certain no other deploy is running. Locks also expire automatically after 30 minutes.

## Avoiding conflicts

### YAML + dashboard

If your team uses both YAML config and the dashboard:

* Resources in YAML are managed by the CLI. Dashboard changes will be overwritten on the next deploy.
* Resources not in YAML are left untouched by default. `--prune` deletes only resources tracked in this config's `.devhelm/state.json`; `--prune-org-cli` widens that to all CLI-managed resources in the org; `--prune-all` also deletes dashboard- and Terraform-managed resources.

### YAML + Terraform

Don't manage the same resource with both tools. Each resource should have a single source of truth:

| Resource                | Managed by                           |
| ----------------------- | ------------------------------------ |
| API monitors            | `devhelm.yml`                        |
| Infrastructure monitors | `devhelm_monitor` Terraform resource |

### Plan as a safety net

Always run `devhelm plan` before deploying to catch unexpected changes:

```bash theme={null}
devhelm plan -f devhelm.yml
```

In CI, use `--dry-run --detailed-exitcode` to gate merges.

## Next steps

<CardGroup cols={2}>
  <Card title="Deploy workflow" icon="rocket" href="/mac/yaml/workflow">
    The validate-plan-deploy lifecycle.
  </Card>

  <Card title="CI/CD patterns" icon="rotate" href="/mac/ci-cd/overview">
    Automate deploys and drift checks in CI.
  </Card>
</CardGroup>
