Understanding pod labels vs annotations
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Kubernetes labels and annotations are both key-value metadata, but they solve different problems. Labels are for identifying and selecting objects. Annotations are for attaching extra information that humans or tools may read, but that Kubernetes selectors should ignore.
Use Labels for Identity and Selection
A label describes something you want to group by. Typical examples are app name, environment, version, or component role. Because labels are queryable, many Kubernetes features rely on them:
- Services select Pods by label
- Deployments manage Pods through label selectors
- '
kubectlfilters objects with-l' - policies and monitoring tools often group resources by label
Here is a simple Pod manifest with meaningful labels:
Because those values are labels, you can select the Pod directly:
That selector behavior is the defining feature of labels.
Use Annotations for Descriptive Metadata
Annotations are also key-value pairs, but they are not intended for grouping or selection. They are better for metadata such as:
- build IDs
- Git commit hashes
- links to dashboards or runbooks
- tool-specific settings
- human-readable notes
Example:
These values are useful, but they should not decide which Pods a Service routes traffic to. That is why they belong in annotations rather than labels.
A Good Rule of Thumb
Ask one question: will software need to select or group objects by this field?
If the answer is yes, use a label. If the answer is no, and the value is mostly descriptive or tool-specific, use an annotation.
Examples:
- '
app=paymentsshould be a label' - '
tier=backendshould be a label' - '
git-sha=abc123is usually an annotation' - '
deployed-by=github-actionsis usually an annotation'
This rule keeps metadata consistent across teams and avoids selectors depending on incidental details.
Why Misusing Labels Causes Trouble
Labels participate in object relationships. A Deployment selector must match the Pod template labels it manages. A Service selector determines which Pods receive traffic. If you put unstable metadata into labels, you may accidentally change those relationships.
For example, using a commit SHA as a label can create unnecessary label churn and can complicate selectors if other resources start depending on it. The same value is often better as an annotation because it remains visible without becoming part of workload identity.
Working With Metadata From the CLI
You can manage both types from kubectl:
The commands look similar, but their purpose is not. A label changes what selectors can match. An annotation changes only attached metadata.
Common Pitfalls
- Using annotations for fields that Services, Deployments, or policies need to select.
- Storing unstable data such as timestamps or commit IDs in labels when they should be annotations.
- Designing selectors around labels that are too broad, such as only
app=myapp, when more specific identity is needed. - Treating labels and annotations as interchangeable because both are key-value maps.
- Forgetting that changing a label can affect routing, ownership, or automation behavior immediately.
Summary
- Labels identify and group Kubernetes objects.
- Annotations store extra metadata that selectors should ignore.
- If a field is part of workload identity, it should usually be a label.
- If a field is descriptive, audit-related, or tool-specific, it should usually be an annotation.
- Choosing correctly keeps selectors stable and metadata useful.

