skip to content

What does dropping a Helm release for plain kubectl apply actually cost you?

level: middleimportance: must knowfreq 61%

answer

  1. Rendering and lifecycle are two separate jobs
  2. Something stores what was actually applied
  3. Helm knows which objects belong to it
  4. Removed from the chart means removed from the cluster
  5. sh.helm.release.v1 holds manifest plus values

basics

~20 s

You lose the release record: the stored manifest and values per revision, helm history and helm rollback, membership tracking that prunes removed resources and cleans up on uninstall, hook ordering, helm test, and the wait behaviour Helm applies after writing.

solid answer

~40 s

Helm stores each revision as a Secret named `sh.helm.release.v1.<name>.v<rev>` holding the rendered manifest and the values used, which is what makes `helm history`, `helm get manifest` and `helm rollback` possible. Because Helm knows the set of objects belonging to a release, removing a resource from the chart deletes it on upgrade and `helm uninstall` removes the whole set. You also give up hook events with `helm.sh/hook-weight` ordering and `helm.sh/hook-delete-policy` cleanup, `helm test`, and Helm's post-write waiting. Applying manifests directly leaves Git as your only history: rollback becomes revert-and-reapply, which restores intent but not a record of what was live, and deleting a manifest file removes nothing from the cluster unless you delete it yourself. In exchange you never meet Helm's "another operation is in progress" release lock.

code

bash · 5 lines
bash
helm history telemetry-gateway -n telemetry
helm get manifest telemetry-gateway --revision 7 -n telemetry
helm rollback telemetry-gateway 7 -n telemetry

kubectl get secret -n telemetry -l owner=helm,name=telemetry-gateway

go deeper

for a junior

Know that Helm remembers each install as a numbered revision and that this is what makes rollback and uninstall possible. Being able to say the record lives in the cluster, not on your laptop, is the level-appropriate answer.

for a middle

Explain the mechanics: the per-revision record holding manifest and values, membership tracking that prunes removed resources, hook ordering annotations, and Helm's post-write waiting. Name what you would have to rebuild without them.

for a senior

Weigh each lost feature against what your delivery system already does. If a reconciliation agent already prunes and orders, the release record may be redundant; if nothing else records what was applied, giving it up costs you incident forensics.

for a principal

Decide where the record of applied state should live across the estate — in Helm, in a delivery system, or in an audit store — and avoid paying for three copies that disagree. Own the standard rather than letting each team choose separately.

### What a release actually is When `helm install` or `helm upgrade` succeeds, Helm writes a record into the release namespace: by default a Secret named `sh.helm.release.v1.<name>.v<rev>` (the storage backend is selectable with `HELM_DRIVER`, which accepts `secret`, `configmap`, `memory` or `sql`). That record holds the rendered manifest, the values that produced it, the chart metadata and the release status. `--history-max` bounds how many revisions are kept, defaulting to 10. Every operational Helm feature that feels like magic is reading or writing that record. ### The four things you give up **1. History and rollback.** `helm history` lists revisions with their status and chart version, `helm get manifest` prints the manifest a revision actually applied, and `helm rollback` re-applies a stored revision as a *new* revision. That is a record of what was running, which is a different artefact from what was in Git — the two disagree exactly when someone deployed from an unmerged branch, or when a template rendered differently because a subchart moved. With plain `kubectl apply`, reverting the commit and re-applying reconstructs the intent; it does not tell you what the cluster was actually given. **2. Set membership.** Helm knows which objects belong to a release, so it can compute what left the chart between revisions and delete those objects on upgrade, and remove the whole set on `helm uninstall` (minus anything annotated `helm.sh/resource-policy: keep`). A directory of manifests has no membership: delete the file and the live object stays, quietly, until someone notices. Teams applying plain YAML end up rebuilding this themselves with labels and a pruning step, and that reimplementation is the honest cost line. **3. Ordering and lifecycle extension.** Hooks give you manifests that run at defined points around install, upgrade, rollback and delete, ordered by `helm.sh/hook-weight` and cleaned up per `helm.sh/hook-delete-policy`. `helm test` runs test manifests against a real installed release. None of that exists for a bare apply; ordering becomes a shell script with sleeps, or a controller's job. **4. Waiting.** Helm can block until the objects it wrote settle. In Helm 4 `--wait` is strategy-valued — `watcher`, `legacy` or `hookOnly` — and omitting it means `hookOnly`, so Helm 4 does not wait on workloads unless you ask. In Helm 3 `--wait` was a boolean polling waiter. Either way, that is behaviour you write yourself once the release is gone. ### Ownership metadata is part of the deal Helm marks what it manages with the `app.kubernetes.io/managed-by: Helm` label plus the `meta.helm.sh/release-name` and `meta.helm.sh/release-namespace` annotations, and refuses to overwrite an object claimed by something else. Dropping Helm drops that guardrail — nothing stops two directories of manifests from fighting over the same object — but it also drops the class of errors where Helm declines to adopt an object it did not create. ### What you gain by leaving An honest answer names the upside. There is no release lock, so you never see the pessimistic "another operation (install/upgrade/rollback) is in progress" state that a killed CI job leaves behind and that no command cleanly recovers. There is no rendered-versus-live divergence to reason about, and no revision history to prune. The applied artefact is the reviewed artefact. ### The halfway house `helm template ./chart | kubectl apply -f -` keeps the chart as a renderer and discards the release layer entirely: no record Secret, no history, no hooks executed, no uninstall tracking, no waiting. Teams reach for it when a continuous-reconciliation agent already owns applying and pruning and they only wanted Helm's templating. It is a coherent choice, but be explicit that it is a choice — the resulting objects are not a Helm release at all, and `helm list` will not show them. ### Answering well Separate rendering from lifecycle in your first sentence. Candidates who cannot make that separation tend to argue that dropping Helm means losing templating, which is wrong; and candidates who make it easily can then price each lifecycle feature against what their delivery system already provides.

  • You delete a resource's template from a chart and run helm upgrade. What happens to the live object, and how does that differ from deleting a file in a manifests directory?
    Helm compares the new revision's manifest with the stored previous one, sees the object is gone, and deletes it from the cluster — unless it carries `helm.sh/resource-policy: keep`. Deleting a file from a manifests directory does nothing to the cluster: `kubectl apply -f` only creates and updates what it is given, so the orphan keeps running until someone deletes it explicitly or a pruning mechanism you built notices.
  • If Git already holds every manifest version, why is the release record still worth anything?
    Git holds intent; the release record holds what was actually applied. They diverge when a deploy ran from an unmerged branch, when values came from a `-f` file or `--set` that was never committed, or when a subchart version resolved differently at package time. `helm get manifest --revision N` answers "what did we give the cluster", which is the question you have during an incident.
  • Is there anything you are glad to be rid of when you stop using Helm releases?
    The release lock. Helm marks a release pending while an operation runs, and a CI job killed mid-upgrade leaves it stuck with "another operation (install/upgrade/rollback) is in progress"; no command cleanly recovers that state, so teams end up deleting the pending revision record by hand. Plain applies have no such state machine to get wedged.

saying these in an interview costs you the question

  • Thinking dropping Helm means losing templating too
  • Believing kubectl apply deletes objects whose files were removed
  • Saying helm rollback restores data or reverses migrations
  • Calling the release record just a copy of values.yaml
  • Assuming helm template output still appears in helm list
  • Claiming Helm 4 waits for workloads by default

context