In what order does helm uninstall delete a release's resources?
answer
- There is more than one table
- Think about what must not be orphaned
- Traffic-facing kinds leave first
- Roughly the install order, mirrored
- Namespace is deleted last, not first
basics
~10 sAgainst a second hard-coded table that is essentially the reverse of the install order: APIService and Ingress first, then Service, then workloads, then config and RBAC, with Namespace and PriorityClass deleted last.
solid answer
~40 sHelm keeps two kind tables, not one. Uninstall sorts the release's stored manifest against the reverse table, so traffic-facing kinds go first — `APIService`, `Ingress`, `Service` — then `CronJob`, `Job`, `StatefulSet`, `Deployment` and the rest of the workloads, then RBAC, `CustomResourceDefinition`, storage, `ConfigMap`, `Secret`, `ServiceAccount`, and finally `Namespace` and `PriorityClass`. The intent mirrors install: remove the dependants before the things they depend on, so nothing is orphaned mid-teardown and traffic stops reaching pods before the pods disappear. As on install, the deletes are *submitted* in that order — Helm does not block on each object's finalizers before issuing the next unless you ask it to wait — so the order shapes the sequence of requests, not the sequence of completions.
code
bash · 3 lines# The manifest that uninstall sorts comes from the release record, not the chart
helm get manifest checkout -n checkout | grep '^kind:'
helm uninstall checkout -n checkoutgo deeper
Recall the shape rather than the list: uninstall runs the kind ordering backwards, so the front door closes first and the namespace goes last. That is enough to reason about a teardown you are watching.
Explain the invariant behind the mirror: dependants before dependencies, so nothing is left pointing at something already gone. Note that Helm sorts the stored manifest, not the chart on disk.
Use the ordering diagnostically — a stalled uninstall is almost never Helm, it is a finalizer late in the table — and be clear that deletions are submitted, not awaited, so kinds terminate concurrently.
Own the teardown contract: decide what a release is allowed to take with it, where the boundary between a release and a namespace sits, and which state must survive an uninstall by policy rather than by luck.
### Two tables, not one reversed list Helm carries a second hard-coded kind table used when a release is torn down. It is not computed by reversing the install table at runtime; it is written out separately, and it reads as its mirror image: `APIService`, `Ingress`, `Service`, then `CronJob`, `Job`, `StatefulSet`, `HorizontalPodAutoscaler`, `Deployment`, `ReplicaSet`, `Pod`, `DaemonSet`, then RBAC (`RoleBinding`, `Role`, `ClusterRoleBinding`, `ClusterRole`), `CustomResourceDefinition`, storage (`PersistentVolumeClaim`, `PersistentVolume`, `StorageClass`), `ConfigMap`, `Secret`, `ServiceAccount`, the guardrail kinds, and finally `Namespace` and `PriorityClass`. The manifests being sorted come from the release record, not from the chart directory. Uninstall works from the manifest stored with the current revision, which is why a resource that was removed from the chart in an earlier upgrade is not deleted at uninstall time — it is no longer in the stored manifest at all, having been deleted at that earlier upgrade. ### Why reverse The install table is arranged so that a referenced object exists before the object referencing it. Teardown wants the same invariant read backwards: nothing should be left pointing at something that has already gone. Concretely, taking the Ingress out first means the platform's routing layer stops sending requests at a Service whose pods are about to vanish — you get a clean rejection at the edge instead of connections landing on terminating pods. Removing the Service before the Deployment means the endpoints disappear before the pods do, rather than an endpoint list churning as pods terminate one by one. Deleting workloads before their ServiceAccounts, ConfigMaps and RBAC means a pod is never left running with its identity or configuration pulled out from under it. And deleting the Namespace last matters most of all: a namespace deletion cascades to everything inside it, so doing it early would make the rest of the ordering meaningless. ### Submission order, again The same qualifier as install applies. Helm issues the deletions in this order without blocking on each object's disappearance before issuing the next, unless you explicitly ask the uninstall to wait. Kubernetes deletion is itself asynchronous — an object with a finalizer stays visible with a deletion timestamp until its controller clears it — so in practice several kinds are terminating concurrently and the order describes the sequence of API requests, not the sequence of things actually going away. That distinction explains most of the surprise here: teams see a StatefulSet's pods still terminating while the ConfigMap is already gone, and conclude the order is wrong. It is not; the requests went out in order and the cluster is finishing them at its own pace. ### Where it shows up in practice It shows up when a teardown seems to hang. Suppose you are decommissioning an order-checkout API installed as the same chart across a twelve-namespace fleet, and three of the twelve uninstalls sit there for minutes. The order tells you where to look: everything up to and including the workloads was submitted long ago, so a stall almost always means something later in the table — most often a namespace whose deletion is blocked by a finalizer on some object inside it — rather than Helm being stuck on the release itself. It also shapes what a partially failed uninstall looks like. Because the ordering is front-loaded with traffic-facing kinds, a teardown that dies part way through has usually already removed the Ingress and the Service, so the workload is off the network even though its pods and its ConfigMap remain. That is the right failure shape — dark rather than half-serving — and it is a consequence of the reverse ordering rather than an accident. ### What this ordering does not decide Be careful not to over-claim it. The reverse table decides only the sequence of delete requests for objects that are in the stored manifest and that Helm is going to delete at all. Whether a particular object is deleted is decided elsewhere — by the `helm.sh/resource-policy` annotation, by whether the resource came from the chart's `crds/` directory, and by what the cluster's own garbage collection does with dependants. Those are separate mechanisms; the ordering table has nothing to say about them. ### Saying it well in an interview One sentence carries it: install sorts by kind so dependencies come first, uninstall sorts by a mirrored table so dependants go first, and both are submission orders rather than completion orders.
- Which manifest does helm uninstall actually delete — the chart's templates or something else?The manifest stored with the release's current revision. Helm does not re-render the chart at uninstall time and does not need the chart to be available. A resource dropped from the chart during an earlier upgrade is not in that stored manifest, because it was already deleted when that upgrade ran.
- An uninstall appears to hang. What does the delete ordering tell you about where to look?That the traffic-facing kinds and the workloads were submitted first and are almost certainly gone, so the stall lives later in the table — most often a namespace or a claim held open by a finalizer that some controller has not cleared. Look at the objects still carrying a deletion timestamp rather than at Helm.
- Does the reverse order decide whether a given object is deleted at all?No. It decides only the sequence of delete requests among the objects Helm is going to delete. Whether an object is exempt is a separate mechanism — the `helm.sh/resource-policy` annotation, resources that came from the chart's `crds/` directory, and the cluster's own garbage collection of dependants.
Demolition follows construction backwards: you disconnect the services and strip the fittings before you knock down the walls, and the foundation goes last.
saying these in an interview costs you the question
- Says uninstall deletes in the same order as install
- Thinks the Namespace is removed first
- Believes deletions complete one kind at a time
- Claims uninstall re-renders the chart to know what to delete
- Confuses delete ordering with resource-policy exemptions