Semantic Convention Stability Guarantees in OpenTelemetry: What Is Promised and What Is Not
OpenTelemetry gives every piece of telemetry a standard name. But what happens when a name needs to change? This guide explains, from zero, the stability levels, the promises attached to them, the loopholes to watch for, and how to upgrade without breaking a single dashboard.
Imagine you wrote a recipe book for your family, and every recipe says “add one cup of flour”. One day a relative decides that “flour” should now be called “powder”, and quietly edits half the recipes. Nothing is technically wrong with the new word. But anyone following an old note, a shopping list, or a kitchen label that says “flour” is suddenly confused. Telemetry has the same problem on a much larger scale. Thousands of dashboards, alerts and queries across the world refer to attribute names such as the HTTP status code or the service name. If the standard body renames those names at will, the monitoring of every company that follows the standard breaks overnight.
That is why OpenTelemetry attaches stability guarantees to its semantic conventions. A guarantee is a promise about what will not change, what may change, and how any change will be announced and softened. This article walks through those promises in plain English. You will learn what each stability level means, what the project commits to, what it explicitly does not commit to, and how to design your own telemetry, dashboards and upgrade process so that a rename never ruins your weekend.
1Why Names Need Promises
Before any definitions, let us see why a naming standard without a stability promise would be almost useless.
The problem with moving names
Telemetry is only useful if somebody, or something, reads it later. A person types a query such as “show me all requests where the status code is 500”. An alert rule watches “the error rate of the checkout service”. A cost report groups spans by “the database system in use”. Every one of those readers depends on names: the label for the status code, the label for the service, the label for the database. The reader and the writer of telemetry are usually different teams, different tools and different companies, separated by months or years. The only thing connecting them is an agreement about names.
If the agreement changes without warning, readers silently see empty graphs. Worse, the failure is quiet. An alert that looks for an old name does not crash. It simply never fires, because the thing it watches no longer exists under that name. People discover the gap during the next outage, which is the most expensive moment to discover anything.
What a promise buys you
A stability guarantee turns the naming agreement from a friendly suggestion into a contract. It lets library authors write instrumentation once and know it will stay correct. It lets vendors build features, such as a built-in “web requests” screen, on top of those names without fear of them shifting. It lets your own platform team write dashboards that survive an upgrade of the whole company’s tracing libraries. And it gives everyone a shared vocabulary for talking about risk: “this name is stable, so we can depend on it; that one is still in development, so we should isolate it.”
Think of road signs. Drivers rely on the meaning of a red octagon saying STOP. The road authority may add new signs, but it will not suddenly change what the stop sign looks like, because millions of drivers would be at risk. A stability guarantee is the road authority saying which signs are final and which are still being tested on one test road.
Keep this single idea through the whole article: a stability level is a statement about how risky it is to depend on a name. It is not a statement about how good, useful or widely used the name is.
2The Building Blocks in Plain English
A handful of terms appear everywhere in this topic. Learn them once and the rest of the guide reads smoothly.
Telemetry and its three signals
Telemetry is the data software produces to describe itself. It comes in three main signals. Traces record the journey of a single request through many services, like the tracking page of a parcel. Metrics are numbers measured over time, such as requests per second. Logs are timestamped text records. OpenTelemetry, often written OTel, is the open-source project that standardises how all three are produced and shipped.
Spans, attributes and resources
A span is one timed step inside a trace, such as “handle this web request” or “run this database query”. Each span carries attributes, which are labelled facts attached to it, like a sticky note saying “status code: 200” or “database: PostgreSQL”. A resource is a special set of attributes describing the thing that produced the telemetry, such as the service name, its version, the cloud region and the container. Metric data points and log records can carry attributes too.
Semantic conventions
Semantic conventions are the agreed dictionary of names and meanings for those attributes, and also for span names, metric names, units and event names. They say, for example, that the HTTP method of a request is stored under one specific attribute name, with values like GET and POST, and that a request-duration metric has a particular name, unit and set of labels. The word “semantic” means “about meaning”: two programs written in different languages by different people attach the same meaning to the same name.
The registry and the schema
The full set of attributes is kept in a central registry, a machine-readable catalogue. Each entry records the name, type, description, allowed values, examples and, importantly, the stability level. A schema, in this context, is a versioned description of how names changed between convention versions, so a tool can translate old names into new ones. We return to both later.
Instrumentation, SDK, Collector and backend
Instrumentation is code that makes an application produce telemetry. The SDK is the machinery that collects and exports it. The Collector is a separate program that receives, processes and forwards telemetry. The backend is the system that stores and displays it. Semantic conventions touch every one of these, because the producer chooses the names, the pipeline may rewrite them, and the backend and its users query them.
| Term | Simple meaning | Why stability matters to it |
|---|---|---|
| Attribute | A labelled fact on a span, metric or log | Queries and alerts depend on its exact name |
| Resource | Facts about the producer, like service name | Used to group and filter all telemetry |
| Semantic convention | Agreed names and meanings | The thing the guarantee protects |
| Registry | Catalogue of all conventions | Records each name’s stability level |
| Schema | Versioned record of renames | Lets tools translate between versions |
| Instrumentation | Code producing telemetry | Emits the names, so upgrades can change them |
| Collector | Pipeline program | Can map old names to new ones |
| Backend | Storage and screens | Where broken names become broken dashboards |
3What Is Inside a Semantic Convention
To understand what can be promised, we must first see what a convention is made of. Each part is a candidate for change, and the guarantees treat the parts differently.
The anatomy of one attribute
Name
A dotted, lowercase label such as a group name followed by a specific field. The dots form namespaces that organise related names.
Type
Whether the value is text, a whole number, a decimal, a true or false flag, or a list of these.
Meaning
A written description of what the value represents and how it should be measured or captured.
Allowed values
For some attributes, a fixed list of members, such as the standard HTTP methods or the names of common database systems.
Requirement level
How strongly instrumentation is told to provide it: required, conditionally required, recommended or opt-in.
Stability level
The promise level: development, stable, or deprecated, with details to follow.
Conventions are more than attributes
Beyond attributes, conventions cover several other things. They define span names and how to build them, for example a method plus a low-variety route pattern. They define span kinds, such as whether a span represents a client making a call or a server handling one. They define metrics: the metric name, the type of instrument (counter, histogram, gauge), the unit, and which attributes it carries. They define events, such as the record of an exception. And they define resource groupings. Each of these is a separate surface that can be stable or in development, and a change to any one of them can break a query.
Requirement levels in plain words
Required means instrumentation must always supply it. Conditionally required means it must be supplied whenever a stated condition holds, for example “if the request failed”. Recommended means supply it unless there is a good reason not to. Opt-in means leave it off by default and enable only when the user asks, usually because it is expensive or sensitive. Requirement levels interact with stability: a stable convention can usually grow new recommended or opt-in attributes, but it should not suddenly demand new required ones.
Naming rules
Names follow house rules: lowercase letters, words separated by underscores inside a segment, dots separating namespaces, no vendor brand names in the shared namespaces, and no names that mix up what and how. Good names describe the thing being measured, not the tool that measured it. These rules exist so that names stay readable and so that custom names written by users never accidentally collide with future standard ones, a point we will return to.
Example values in the documentation are illustrations, not promises. A stability guarantee covers the structure of the convention, not whether a particular sample value shown in a table will stay the same.
4The Stability Levels Explained
OpenTelemetry marks each convention with a level that says how much weight you can put on it. Here is the ladder, from newest to oldest.
Development
Development is where new conventions begin. The older documents called this level experimental, and you may still see that word in older material, issues and package names. A development convention is a proposal that has been written down and may be implemented, but it has not been proven or agreed as final. It may be renamed, split, merged, retyped or removed in any release without special ceremony. You are welcome to use it to experiment, but you should not build long-lived dashboards on it without a plan for change.
Release candidate
Some parts of the project use an intermediate release candidate stage for conventions that are close to final, in which the maintainers invite wide testing before declaring stability. Changes are expected to be small and are made only to fix problems found during that final testing. Treat release candidates as nearly stable but still not covered by the full promise. Not every area uses this stage, and the exact naming of stages has evolved, so always check the current documentation for the area you care about.
Stable
Stable is the level that carries the real guarantee. Once a convention is marked stable, the project commits that it will not be changed in a breaking way. Names, types, units and meanings are frozen. New things may be added around them, but existing things are not moved. This is the level you can safely build dashboards, alerts, parsing rules and vendor features upon.
Deprecated
Deprecated means “do not use for new work, and expect this to disappear.” A deprecated entry normally stays in the registry with a note pointing to its replacement, such as “renamed to this other name” or “removed with no replacement”. Deprecation is the gentle exit door: it lets the project retire a name over a long period instead of deleting it suddenly.
Development
New idea. Free to change. Use for experiments and keep it isolated from critical alerts.
Release candidate (where used)
Nearly final. Only small fixes expected. Good time for broad testing.
Stable
Frozen. Safe to depend on for years. Only additive changes allowed.
Deprecated
Being retired. A replacement is named. Plan to migrate off it.
| Level | Can it change? | Safe for critical alerts? | Typical action for you |
|---|---|---|---|
| Development | Yes, freely | No, not without a safety net | Experiment, isolate, track changes |
| Release candidate | Only small fixes | Cautiously | Test and give feedback |
| Stable | Only additive changes | Yes | Build on it |
| Deprecated | Will be removed over time | Not for new work | Migrate to the replacement |
Stability is decided per convention, not per project. One attribute can be stable while its neighbour in the same document is still in development. Always check the level of each name you depend on, not just the page heading.
5The Promise Itself: What Stable Guarantees
Now the heart of the topic. When a convention is stable, what exactly may and may not happen to it?
What will not happen to a stable convention
- It will not be renamed. The attribute, metric or span naming rule keeps its name.
- Its type will not change. A text attribute does not become a number.
- Its unit will not change. A duration measured in seconds does not later switch to milliseconds.
- Its meaning will not be reinterpreted in a way that makes old data mean something else.
- It will not be removed while it remains stable.
- A metric’s instrument type will not change, for example from a histogram to a counter.
- A span’s kind will not flip from client to server.
What may happen to a stable convention
- New attributes may be added, typically at the recommended or opt-in level, so existing readers keep working and newcomers get extra detail.
- New allowed values may be added to an attribute that has a list of members, which is why readers should tolerate values they do not recognise.
- Descriptions may be clarified without changing the underlying meaning.
- A convention may be deprecated, which marks the start of an orderly retirement and does not instantly remove it.
- Documentation, examples and non-normative guidance may be reorganised.
How a true breaking change would be handled
If a stable convention ever had to change in a breaking way, the project’s position is that this would need a new major version of the conventions as a whole, with a long and clearly communicated transition. The conventions are currently versioned in the one-point-something range, and a major-version change is treated as a rare and heavy event, not a routine release. Always check current project statements for the exact wording and any updates, because the governance details are refined over time.
A stable convention is like the shape of a standard electrical plug. The country may allow new adapters, new safety features and new socket designs alongside it, but the existing plug will keep fitting existing sockets. Redesigning the plug itself is something you only do with decades of notice, if ever.
| Kind of change | Allowed on a stable convention? | Why |
|---|---|---|
| Rename an attribute | No | Breaks every query using the name |
| Change a type or unit | No | Corrupts comparisons and maths on old data |
| Remove while stable | No | Readers would lose data |
| Add a recommended or opt-in attribute | Yes | Existing readers ignore it |
| Add a new enum member | Yes | Readers should tolerate unknown values |
| Clarify documentation | Yes | Meaning is unchanged |
| Mark deprecated | Yes | Starts a gentle retirement |
6Deep Dive: Requirement Levels, Enumerations and Room to Grow
Two details of how conventions are written decide how safely they can grow: the requirement level of each attribute and the way lists of allowed values are handled.
Why requirement levels interact with stability
When a convention is stable, instrumentation authors and backend builders make assumptions based on its requirement levels. A backend may assume that a required attribute is always present and write code that fails when it is missing. If a stable convention suddenly added a new required attribute, every existing library would instantly be non-compliant, which would be a breaking change in practice even though no name changed. That is why stable conventions grow mainly through recommended and opt-in additions, which no reader can rely on being present.
Conditional requirements
Some attributes are required only when a condition holds, for example when an operation fails. These are called conditionally required. The condition is part of the contract. A backend can rely on it: “if this request failed, the error type will be present.” Changing the condition would change what readers can assume, so the promise covers the condition too.
Lists of allowed values
Many attributes take one value from a named list: the HTTP method, the type of messaging operation, the database system. These lists are called enumerations. The members of a stable enumeration will not be renamed or removed. But new members can be added over time, such as a newly popular database. For that reason the guidance asks instrumentation to use a custom value when none of the listed values fits, and asks readers to tolerate values they have never seen.
Tolerate unknown values
Do not crash or drop data because an enum value is new. Group it under “other” if you must.
Use a custom value if nothing fits
Do not force a wrong listed value just to stay on the list.
Never rely on a closed list
A hard-coded list of all values will go out of date.
Keep values low cardinality
A list of members is only helpful if the set stays small.
Room to grow, by design
Because of these rules, a stable convention can still improve over time. New optional details appear, new members join lists, and descriptions improve. The structure that existing readers rely on stays fixed. This is the central design idea: make the promise about what readers can rely on, and keep everything else free to grow.
A restaurant menu can add new dishes every season without ever changing the price or recipe of the classic dish that regulars order. The regulars’ expectations are the stable part. The seasonal additions are the room to grow.
7What Is Not Guaranteed
The promise is strong but narrow. Most surprises in real life come from assuming it covers more than it does.
Development conventions
Anything not marked stable can change without the full ceremony. Whole areas of OpenTelemetry remain in development, and some, such as conventions for newer fields like generative AI, have seen names change several times while the community learns what works. If a critical alert depends on such a name, expect to revisit it.
The version of the library you run
A stable convention does not mean every instrumentation library emits it. Libraries have their own versions and their own timelines for adopting a new convention version. Upgrading a library can therefore change which names appear, even though the convention itself never broke its promise. The promise protects the definition, not your upgrade path.
Cardinality, volume and cost
Stability says nothing about how many distinct values an attribute will have or how much it will cost to store. A stable name can still produce enormous cardinality if you attach it to a metric with a free-form value. Naming a thing and bounding it are different jobs.
Behaviour of backends
A vendor may transform, rename or drop attributes after receiving them. A stable name in your telemetry is not guaranteed to appear under the same name on a vendor’s screens. The guarantee ends where OpenTelemetry’s responsibility ends, at the wire format and the registry.
Sample values and wording
Descriptions, examples and notes may be edited. The exact allowed values for open-ended fields may grow. Do not hard-code assumptions about the complete list of values.
Other kinds of stability
The stability of semantic conventions is separate from the stability of the OpenTelemetry API, the SDK, the wire protocol and Collector components. Each has its own rules. A stable SDK can emit development-level conventions, and a development-level instrumentation library can emit stable conventions. Chapter 17 untangles this.
Development names
May change at any release with limited ceremony.
Which names your library emits
Depends on the library version and settings.
Cost and cardinality
Your choices and your data decide these.
Backend display names
Vendors may rename on their side.
8Architecture: How Conventions Reach Your Dashboards
A convention is born in a document and ends up on a screen. Following that path shows where stability is enforced and where it can leak.
flowchart LR
SPEC["Semantic conventions repository and registry"] --> GEN["Generated code and documentation"]
GEN --> LIB["Instrumentation libraries"]
LIB --> SDK["SDK in your application"]
SDK -->|"OTLP with schema URL"| COL["Collector with optional rename processors"]
COL --> BE["Backend storage"]
BE --> DASH["Dashboards alerts and queries"]
Walking the path
It starts at the registry, the machine-readable catalogue in the semantic conventions repository, where each name is recorded with its stability level. From that registry, tools generate documentation pages and code constants for each programming language, so that developers can refer to a name through a code constant instead of typing a string. Instrumentation libraries, for web frameworks, database clients and so on, use those constants to label their telemetry. The SDK inside your application batches and exports it using the OpenTelemetry Protocol, and can attach a schema URL that records which version of the conventions the data follows. A Collector may sit in the middle and rewrite names if needed. Finally, the backend stores everything and your dashboards and alerts query it.
Where the guarantee bites
The stability promise lives at the very first box. It says the registry entry will not change in a breaking way. Every later box is under the control of some team: the library authors choose which convention version they follow, your platform team chooses which library versions to deploy, your pipeline team chooses what to rewrite, and your dashboard authors choose which names to query. A break can enter at any of those points even though the registry itself never broke its promise.
Production example: the HTTP conventions reaching real dashboards
When the web request conventions were declared stable, instrumentation libraries across many languages gradually moved to the new names, and observability vendors updated their built-in web service screens to understand them. Teams with their own dashboards had to update queries, and the project provided an opt-in setting to let both old and new names flow at once during the transition. We examine this in detail in a later chapter.
9Inside the Registry: How Stability Is Recorded and Enforced
Promises are only believable if they are checked by machines, not just remembered by people. Here is how the project does that.
The registry as source of truth
Each convention is described in a structured text file, in a form that tools can read. The entry includes the name, type, description, examples, requirement level and a stability field. Because the registry is structured, the same facts feed the website documentation, the language-specific code constants and the checking tools. This avoids the classic problem of documentation saying one thing while code says another.
Generation of language packages
The code constants for each language are generated automatically. Many languages split them into two sets: one for stable conventions and another, with a name that includes a word such as “incubating” or “experimental”, for conventions still in development. This split is a guard rail. It is a deliberate nudge: if you import the stable package, you cannot accidentally depend on something that may vanish, and if you reach for the incubating package, the name of the package itself tells reviewers that you accepted a risk.
Tooling that checks changes
The project maintains tooling for working with the registry, including a tool called Weaver, which can validate registry files, generate documentation and code, and compare two versions of the registry to flag differences. Rules can be written as automated policies, for example “a stable attribute must not be renamed”, so that a proposed change that violates the promise fails review automatically instead of depending on a reviewer’s memory. The exact feature set of the tooling continues to evolve, so check its current documentation if you want to use it for your own custom conventions.
Releases and version numbers
The registry is released in numbered versions. Each release lists what was added, what moved from development to stable, and what was deprecated. The release notes are the best single place to see upcoming risk. Reading them before upgrading libraries is one of the cheapest habits a platform team can build.
flowchart TD
PR["Proposed change to registry"] --> CHECK{"Does it break a stable convention?"}
CHECK -->|"Yes"| REJECT["Rejected or reworked as deprecation plus new name"]
CHECK -->|"No"| REVIEW["Human review by maintainers"]
REVIEW --> MERGE["Merged into the registry"]
MERGE --> RELEASE["Released in a numbered version with notes"]
RELEASE --> GENERATE["Docs and language packages regenerated"]
If you maintain your own company-wide attribute standard, borrow this design. Keep it in a structured file in version control, generate documentation and constants from it, and add an automated check that blocks renames of anything marked stable.
10Stability for Metrics: Names, Units, Instruments and Labels
Metrics have more moving parts than a single attribute, and each part can break a query in its own way.
The parts of a metric convention
- The name. A dotted lowercase label describing what is measured.
- The instrument type. Counter (only goes up), up-down counter, histogram (distribution of values) or gauge (current reading).
- The unit. Written in a standard notation, such as seconds, bytes or a dimensionless count.
- The attributes. The labels attached to each data point, each with its own requirement level.
- The recommended histogram boundaries. Suggested bucket edges that make percentile estimates reasonable.
What a stable metric promises
A stable metric keeps its name, its instrument type, its unit and its meaning. If a duration histogram is stable in seconds, it stays a histogram in seconds. Existing attributes stay with the same meaning, and any new labels are added at a level that readers can ignore. This allows people to write queries, such as “ninety-fifth percentile by route”, and expect them to keep working.
The hidden parts
Two details are easy to miss. First, advisory bucket boundaries are guidance, not part of the promise. Two libraries following the same stable convention may use different buckets and therefore produce slightly different percentile estimates. Second, temporality, whether values are reported as running totals or as changes since the last report, is a choice made by the exporter and the backend, not by the convention. Comparing a total from one source with a change from another will give nonsense, even though the metric name and unit are identical.
Cardinality: the other kind of stability
A metric can have a stable name and still behave unstably in your system if one of its labels has unbounded values. The conventions therefore recommend low-cardinality label values, such as route templates instead of raw paths, and status classes or codes instead of free text. When you add your own labels to a stable metric, you are responsible for keeping them bounded.
| Part of a metric | Covered by the promise? | Notes |
|---|---|---|
| Name | Yes | Frozen while stable |
| Instrument type | Yes | A histogram will not become a counter |
| Unit | Yes | Seconds stay seconds |
| Existing labels | Yes | Meaning and names frozen |
| New labels | Added at optional levels | Readers should ignore unknown labels |
| Advised bucket boundaries | No | Guidance that may be refined |
| Temporality | No | Configured in the exporter and backend |
| Your own labels | No | Your responsibility |
11Stability for Logs, Events and Resources
The same ideas apply to the other signals, with a few differences worth knowing.
Resource attributes
Resource attributes describe the producer: the service name, version and instance, the cloud provider and region, the host, the container, the process. Some of these are the most widely used names in all of OpenTelemetry, because every dashboard groups by service name. Where they are stable, their stability is especially valuable, since a rename here would affect every query in a company. Resource names are also commonly set outside application code, in environment variables or deployment configuration, so a stable name saves you from hunting through manifests.
Logs
Logs are a mix of free text and structured fields. The conventions describe a small set of standard fields and a body that is often unstructured. Because most log content is application-specific, there is far more scope for custom names, and the same rules apply: use your own prefix, and keep a registry. Standard fields such as the severity and the trace identifiers that link a log to a trace are the parts you can rely on most.
Events
An event is a named, timestamped occurrence, such as an exception or a user action. The event name is part of the convention and the attributes that go with it are covered by the same stability levels. Because the event model has been evolving, check how a particular event is represented in the version you use, since the way events are carried inside logs or spans has shifted in the project’s history.
Span names
Span names are part of the contract too. A stable convention describes how to build the name, usually a short operation label plus a low-variety identifier. Dashboards that group by span name rely on this. Changing the way names are built, for example to include the full path, would fragment those groups, so it is treated as a breaking change.
When you review a conventions release, look at all four surfaces for every area you use: attributes, span names, metric definitions and events. A rename in any of them can break a different part of your monitoring.
12Schemas and Transformations: Translating Between Versions
Even with strong promises, names do change over the life of a standard, especially in the development stage. OpenTelemetry therefore provides a way to describe changes in a form that machines can read.
The schema URL
Telemetry can carry a small label called a schema URL. It is a web address that identifies which version of the semantic conventions the data follows. In the wire format used to ship OpenTelemetry data, there is a place for this label on the resource and on each instrumentation scope. Think of it as a version stamp on a packet of data, saying “the names inside follow the dictionary edition of this particular year”.
The schema file
For each convention release, the project publishes a schema file. A schema file lists, version by version, what changed: which attributes were renamed, which metrics were renamed, and similar transformations. It does not contain the data itself. It is a translation table. A tool that holds the schema file can take telemetry stamped with an older version and convert its names to a newer version, or the other way round, by applying the listed renames one after another.
Imagine a travel phrasebook that, instead of listing phrases, lists every spelling reform of a language: “in this year, this word became that word”. With the phrasebook you can read a letter written in any past decade and rewrite it in today’s spelling. The schema file is that phrasebook for telemetry names.
What schemas can and cannot do
Schema transformations are great for simple one-to-one changes, such as renaming an attribute or a metric. They are weaker for complex changes that are not a plain rename: splitting one attribute into two, merging two into one, changing a unit that requires arithmetic, or changing the meaning of a value. For those cases, you may need custom logic in a Collector processor or in the backend. Support for applying schema transformations automatically is still maturing in the wider ecosystem: the Collector community has a schema-aware processor that has been at an early maturity level, and few backends apply schemas automatically. Treat schemas as a helpful building block and a strong source of truth for the translation table, not as a button that makes version differences vanish.
| Type of change | Easy to describe in a schema? | Typical handling |
|---|---|---|
| Rename an attribute | Yes | Schema rename or Collector attribute rename |
| Rename a metric | Yes | Schema rename or Collector metric rename |
| Change a unit | Partly | Needs a calculation, so a transform processor |
| Split one attribute into two | No | Custom parsing logic |
| Change what a value means | No | Re-instrument and document the cut-over date |
Even if nobody in your pipeline reads schema URLs today, keep them on your telemetry. They cost almost nothing and give your future self a precise answer to the question “which dictionary was this data written in?”
13The Lifecycle of a Convention
A convention does not appear stable overnight. It travels through a process that is deliberately slow, and understanding that process tells you when to trust a name.
flowchart LR
IDEA["Idea or gap noticed"] --> PROP["Proposal written"]
PROP --> DEV["Development level in registry"]
DEV --> TRY["Implemented in libraries and used by early adopters"]
TRY --> RC["Release candidate or final review"]
RC --> STABLE["Stable"]
STABLE --> DEPR["Deprecated when replaced"]
DEPR --> GONE["Eventually removed in a major version"]
Stage one: noticing a gap
Someone notices that a common thing has no standard name. Maybe a new kind of database becomes popular, or a messaging system is widely used but described differently by each library. A person or a working group writes a proposal explaining what to name, why, and how the values should be captured.
Stage two: development
The proposal is added to the registry at the development level. Instrumentation authors can implement it, and early adopters can try it. During this stage, feedback arrives: names are awkward, some values are missing, a unit is wrong, the same fact can be derived from another attribute. Changes are cheap, and are expected.
Stage three: evidence and review
Before stability is declared, the maintainers want evidence that the design works in practice. Typically that means working implementations in several languages, real use by more than one organisation, and an effort to answer the open questions raised in the earlier stage. The project also checks that the convention fits with its neighbours: that names follow the naming rules, that the same idea is not spelled two ways, and that cardinality has been considered. The exact criteria are written down by the working groups and may be refined, so consult the current process documents for specifics.
Stage four: stable
When the review is satisfied, the convention is marked stable in a numbered release. From that moment the promise from chapter 5 applies. Instrumentation libraries can then plan to emit the stable form by default in a future major release, and vendors can safely build features against it.
Stage five: deprecation and removal
When a better design is found, or when a stable convention is superseded, it is marked deprecated, with a pointer to its replacement. It stays visible for a long period so that readers can migrate. Removal from the registry is reserved for a major version change, not an ordinary release.
You can influence this process. If you use a development convention in production and find a problem, report it. Early feedback is the cheapest moment to change a name, and real-world evidence is what moves a convention towards stable.
14Case Study: The HTTP Conventions Become Stable
The web request conventions are the best-known example of a convention moving from experimental to stable, and they show both the benefit and the pain of the process.
What happened
For years, the HTTP conventions were in the earlier, experimental state, and widely used. Over time the community realised that several names could be clearer and more consistent with other areas, for instance that “client” and “server” addresses should use a common naming scheme across protocols, and that URL parts deserve their own dedicated namespace. In a release in late 2023, the HTTP and related network conventions were declared stable with a refreshed set of names. The renames were done in one deliberate step so that, from then on, the promise could apply.
Examples of renames
| Older name | Stable name | What it means |
|---|---|---|
| http.method | http.request.method | The HTTP verb of the request |
| http.status_code | http.response.status_code | The numeric status the server returned |
| http.url | url.full | The complete web address requested |
| http.scheme | url.scheme | The protocol part of the address |
| http.user_agent | user_agent.original | The client’s self-description header |
| net.peer.name | server.address | The host name of the server being called |
| net.peer.port | server.port | The port of the server being called |
| http.server.duration (metric) | http.server.request.duration | How long the server took to handle requests |
A unit change
One change deserves special attention: the request duration metrics moved from milliseconds to seconds, aligning with common practice in other monitoring ecosystems and with the unit guidance in the specification. A change of unit is exactly the kind of change that cannot be undone silently. If a dashboard still draws the old metric’s numbers on the same axis as the new metric’s numbers, one will look a thousand times larger than the other. This is why such changes were bundled into the single stabilisation step, and why the stable promise now forbids unit changes.
Span naming and cardinality
The stable conventions also describe how to name HTTP spans: a short combination of the method and a low-variety route template, such as the pattern of a path with placeholders for identifiers, not the raw path. Using raw paths would create a different span name for every user id, ruining grouping and exploding storage. Stability here protects not only names but a design principle: keep the number of distinct values small.
Lessons from this case
- Stabilisation can mean one last painful rename. The pain bought a long period of calm afterwards.
- The ecosystem needs time. Instrumentation libraries, vendors and users migrate at different speeds, so a transition mechanism is essential.
- Units and cardinality rules are part of the contract, not footnotes.
Production example: vendor screens following the standard
Observability vendors that offer built-in web service views have had to decide whether to understand the old names, the new names or both. Many accept both for a period and are encouraging users toward the stable names, which is a good example of how a stability promise gives the whole industry a single target to aim at.
15The Opt-In Migration Mechanism
Because millions of dashboards depend on old names, the project does not flip every library to the new names on the same day. It gives you a controlled switch.
The default: do not surprise anyone
The guidance for instrumentation libraries is that an existing library that already emits an older version of a convention should keep emitting it by default until its own next major version, so that simply upgrading a patch or minor version does not rename your data. New names are enabled by an explicit choice.
The setting
The choice is made through a standard environment variable named OTEL_SEMCONV_STABILITY_OPT_IN. Its value is a comma-separated list of keywords, each naming an area of conventions and a mode. For the web request conventions, one keyword means “emit only the new stable names”, and another keyword means “emit both the old and the new names at the same time”, called dual emission. Similar keywords exist for other areas as they stabilise. Libraries that support the setting read it at startup and shape their output accordingly. Check each library’s documentation, because support is gradual and the available keywords differ by area.
The three-step migration
flowchart LR
A["Step 1 Old names only default"] --> B["Step 2 Dual emission old and new"]
B --> C["Step 3 New names only"]
B -.->|"During step 2 update dashboards and alerts"| B
C -.->|"Later library major version removes old option"| D["Old names gone"]
Inventory what depends on old names
Search dashboards, alerts, saved queries, log parsing rules and scripts for the old names.
Turn on dual emission in a pilot
Set the opt-in value for a small set of services, so both name sets appear in the backend.
Update consumers to the new names
Rewrite dashboards and alerts, and verify them against the old ones while both exist.
Roll dual emission out widely
Extend to all services, watching cost and payload size as both name sets add volume.
Switch to new names only
Change the setting so only the stable names are emitted, and watch for anything that still queries old names.
Clean up
Remove old queries, rename-mapping rules and temporary dashboards, and record the cut-over date.
Dual emission increases the size of every affected span and the number of metric series. It is a bridge, not a destination. Plan an end date, because leaving it on for months quietly raises your bill.
16Data Flow: What Really Happens During an Upgrade
Let us follow one metric through a library upgrade, to see precisely where the break can appear and where a stability promise helps.
Before the upgrade
Your web service uses an instrumentation library that records a histogram of request durations under the older metric name, in milliseconds, carrying the older attribute names. Your backend stores it. A dashboard chart plots the ninety-fifth percentile from that metric, and an alert fires when it exceeds 800.
The upgrade
The platform team upgrades the library to a new major version. That version, following the project’s guidance, now emits the stable metric name, in seconds, with the stable attribute names. The service keeps working perfectly. Requests succeed. Nothing crashes.
After the upgrade
In the backend, the old metric stops receiving data from that service, and a new metric begins receiving it. The dashboard chart, which queries the old name, flatlines. The alert, which watches for values above 800 on the old name, sees no data. Depending on how the alert treats missing data, it may silently stay quiet. The new metric, even if someone looked at it, has values like 0.4 instead of 400, because the unit changed.
Where the promise helped, and where it did not
The stable promise means that this rename and unit change happened exactly once, in a documented release, and will not happen again. It also means the project provided a migration path, namely dual emission, and the means to describe the change in a schema. What it did not do is update your dashboards. That step belongs to you, which is why the earlier migration steps place so much emphasis on inventory and parallel running.
Flat chart
Old metric name receives no data from upgraded services.
Silent alert
A missing-data rule treats absence as “fine”.
Wrong magnitude
Unit change makes numbers look a thousand times smaller.
Split groups
Old and new attribute names produce two groups for one thing.
Make your important alerts treat “no data” as a problem, not as a pass. Many stability-related incidents are quiet alerts that nobody noticed had stopped working.
17Many Kinds of Stability: Untangling the Layers
The single word “stable” is used for five different things in OpenTelemetry. Mixing them up is the number one source of confusion.
| Layer | What “stable” means here | Who decides |
|---|---|---|
| Semantic conventions | Names, types, units and meanings will not change in breaking ways | Semantic conventions working groups |
| Specification | The rules for APIs, SDKs and the protocol will not change in breaking ways | Specification maintainers |
| API and SDK for a language | Public code interfaces keep working across minor releases, with a long support window after a major version change | Language SIGs |
| Instrumentation library | The library’s own code interface, and the telemetry it emits, follow its own versioning policy | Library maintainers |
| Collector component | Configuration options and behaviour of a component follow its stability level, such as alpha, beta or stable | Collector maintainers |
Why these layers do not line up
Each layer moves at its own speed. A semantic convention may be stable while the library that implements it is still in early versions. A Collector component may be in beta and use stable conventions. An SDK may be stable and happily export development-level attributes. Because the layers are independent, you must check each one separately for each thing you depend on.
The telemetry itself
There is a subtle point worth stating. The telemetry that an instrumentation library produces is a kind of public interface, because other people’s queries depend on it. The project’s guidance is that stable instrumentation should treat changes to its emitted names as seriously as changes to code interfaces, and should introduce them through the opt-in mechanism or in a major version, not slip them into a minor release. Library maintainers vary in how strictly they follow this, so read release notes.
flowchart TD
Q["You depend on a name in a dashboard"] --> A{"Is the convention stable?"}
A -->|"No"| R1["Expect change and isolate this dashboard"]
A -->|"Yes"| B{"Does your library version emit it by default?"}
B -->|"No"| R2["Use the opt-in setting or upgrade the library"]
B -->|"Yes"| C{"Does your pipeline or backend rename it?"}
C -->|"Yes"| R3["Document the mapping and test it on upgrades"]
C -->|"No"| R4["Safe to depend on"]
“The SDK is stable” does not mean “my attribute names are stable”. Always ask about the convention separately from the code.
18How Languages Package Stable and Unstable Names
The policy about stability becomes practical when it shows up in the packages you import. The exact names differ per language, and they change as ecosystems mature, so treat this chapter as a pattern guide and check your language’s documentation.
The common pattern
Language projects generate code constants from the registry. The typical arrangement is two sets: one set containing only stable names, and a second set, with a name containing a word like “incubating” or “experimental”, containing the development ones. In some languages the second set is a separate package or artifact. In others it is a separate module or an additional import path inside the same package. The effect is the same everywhere: the type of import tells the reader what promise stands behind the name.
Why use constants instead of typing strings
If you write the name of an attribute as a raw string in your code, nothing warns you when it becomes deprecated or renamed. If you use the generated constant, your compiler or your tools can flag deprecation, and a search for uses of the constant finds every place affected. In languages that mark deprecated constants, an upgrade can show you warnings that point at exactly the names you must change. That is cheaper than discovering the rename in production.
Versioning of the constants
The constants are tied to a specific version of the conventions. Some languages encode the version in the import path or package name, so that you consciously choose which edition of the names you are importing. Upgrading to a newer edition is then an explicit edit in your code, which is the safest possible model: nothing changes until a human decides to change it.
| Practice | Benefit | Risk if ignored |
|---|---|---|
| Import from the stable set | Visible promise in the import | Accidental dependence on development names |
| Import from the incubating set deliberately | Reviewers see the risk accepted | Unnoticed breakage on upgrade |
| Use constants, not raw strings | Deprecation warnings and searchability | Hidden stale names |
| Pin the conventions edition | Predictable upgrades | Surprise changes from floating versions |
Package names and layouts differ by language and have been reorganised over time. Do not copy a pattern from one language into another without checking current documentation for the language you use.
19Protecting Dashboards, Alerts and SLOs
Consumers of telemetry carry the most risk. A few habits turn stability levels into an everyday safety system.
Classify every name you depend on
Build a simple dependency list. For each important dashboard and alert, list the attribute and metric names it queries, and record each name’s current stability level. Names that are stable need no special treatment. Names in development get a flag and a named owner who checks the release notes of every new conventions release. Names that are deprecated get a migration ticket.
Prefer stable names in the critical path
For alerts that wake people at night and service level objectives that commit your company to customers, use only stable names wherever an option exists. If the only available signal uses a development name, wrap it in an indirection: derive a recording rule or a derived metric under a name that you own, so only one place needs editing when the source name changes.
Alert on silence
Configure critical alerts so that missing data counts as a failure. Add separate “data freshness” alerts that fire if a service that normally reports has not reported for several minutes. These catch both outages and silent renames.
Dashboards as code
Keep dashboards and alert rules in version control. Then a rename becomes a searchable, reviewable change instead of a hunt through a graphical interface. A single search for the old attribute name across the repository shows every place to fix.
Test with a canary
Before changing library versions everywhere, upgrade a single low-risk service, then compare its data in the backend against a similar un-upgraded neighbour. Look for new names, missing names and changed magnitudes, and check that dashboards still show it.
| Dependency | Risk level | Protection |
|---|---|---|
| Stable name in a paging alert | Low | Alert on missing data and test after library upgrades |
| Development name in a paging alert | High | Wrap in your own derived name, assign an owner |
| Deprecated name anywhere | Medium and rising | Migrate on a ticket with a date |
| Custom name in your own namespace | Low, you control it | Document it in your own registry |
| Vendor-renamed name | Depends on vendor | Record the mapping and recheck on vendor changes |
Production example: derived metrics as a shock absorber
Mature platform teams often define a small set of company-owned “golden signal” metrics, such as requests, errors and latency per service, computed from whichever source names are current. Dashboards and alerts read only those. When a convention name changes, one transformation is edited, and hundreds of consumers are untouched.
20The Backend and Vendor Perspective
Observability vendors sit on the receiving end of every renamed attribute. Stability guarantees shape what they can safely build.
Why vendors love stable names
A vendor wants to offer ready-made screens: a list of your web services with their error rates, a map showing which service calls which database, an automatic breakdown of slow requests. These screens work by looking for specific attribute names in incoming data. If the names might change next month, the vendor must constantly rewrite and re-test those screens. A stability promise lets the vendor write the feature once. It also makes data portable between vendors, because they all look for the same names, which is the foundation of the migration strategies many teams pursue.
What vendors do in practice
Most vendors support the stable names and keep supporting older names for a period, so that customers upgrading on different schedules still see sensible screens. Some translate incoming names into their own internal names at the edge, which means the name you see on a vendor’s screen may be neither the old nor the new OpenTelemetry name. Others display OpenTelemetry names directly. When comparing vendors, ask them how they treat stable conventions, how they handle development ones, and how quickly they follow new releases.
Alignment with other standards
The project has worked to align its conventions with other widely used schemas to reduce the number of competing vocabularies. A notable example is the Elastic Common Schema, which Elastic contributed to the OpenTelemetry project so that the two could be merged into one shared set of names, rather than leaving users to translate between them. Efforts like this reduce the number of times a team must rename things across tools, and they are part of why stable names matter beyond OpenTelemetry’s own libraries.
Questions to ask a vendor
- Which stable conventions do your built-in screens depend on?
- Do you accept both old and new names during a transition, and for how long?
- Do you rename or drop any attributes on ingestion?
- How do you treat unknown values of an attribute that has a list of members?
- How soon after a conventions release do you support its changes?
Vendor behaviour changes over time, and vendors differ. Treat the answers to these questions as inputs to a proof of concept, not as permanent facts.
21The Collector as a Shock Absorber
The Collector sits between your applications and your backend, which makes it the perfect place to soften the effects of any naming change.
Why do this in the Collector
If names are rewritten in the Collector, you change one configuration instead of hundreds of applications. The applications can follow the newest instrumentation, and the backend can still receive the names it expects. Or you can do the reverse: keep applications on older names while the backend already expects the new ones. In both cases the Collector is a translator and a buffer between two groups that move at different speeds.
The tools it offers
Attributes processor
Simple actions on attributes: add, update, rename by copying and deleting, or remove. Good for straightforward one-to-one renames.
Transform processor
A small expression language to change names, values and units in flight, including metric names and arithmetic for unit conversion.
Schema-aware processor
Applies the published schema transformations based on the schema URL. Its maturity has been early, so evaluate before depending on it.
Filter processor
Drops items matching rules, which helps remove duplicate old or new names when you no longer need both.
Two translation strategies
Upgrade at the edge means the Collector rewrites old names to the new stable names, so everything downstream sees only new names. Applications that have not yet upgraded their libraries still look modern to the backend. This lets dashboards be rewritten once, ahead of time. Downgrade at the edge means the Collector rewrites new names back to old ones, protecting old dashboards from upgraded applications. This buys time, but it should be temporary, since you are carrying old names forward.
Unit conversions
A rename is easy. A unit change is harder, because values must be multiplied or divided and histogram boundaries must be adjusted along with the values. If you must convert, test with a known input and compare the output with data from a service that emits the new unit natively. Where possible, prefer letting both versions flow through dual emission for a while instead of converting in flight, because a conversion bug can corrupt data without warning.
flowchart LR
OLD["Services on older library emitting old names"] --> COL["Collector with rename and unit rules"]
NEW["Services on newer library emitting stable names"] --> COL
COL --> BE["Backend sees one consistent set of names"]
BE --> DASH["One set of dashboards and alerts"]
Every rename rule you add is a piece of hidden logic that future engineers must understand. Keep a short table of all active rules with the reason and an end date, and remove rules when the last old producer is gone.
22The Cost of Dual Emission: A Worked Example
Dual emission is the safest bridge, but it is not free. A small calculation shows how much it can cost. The figures are invented for illustration, so replace them with your own measurements.
Extra bytes in traces
Suppose a typical web request span carries nine attributes whose names change in the new stable conventions. When dual emission is on, each of those is written twice, once under the old name and once under the new one. Assume each attribute, name and value together, takes about 35 bytes once encoded. The extra weight per span is 9 times 35, which is 315 bytes. A busy service producing 50,000 such spans per second therefore adds 50,000 times 315, which is 15.75 million bytes per second, or about 15.75 megabytes per second. Over a day, that is about 15.75 times 86,400 megabytes, or roughly 1.36 terabytes of extra data before compression.
Compression softens it
Repeated names and values compress well. If compression shrinks the extra weight to a fifth, a plausible but unverified guess, the extra traffic falls to about 270 gigabytes per day. Still, if your vendor charges by volume, that is real money, and if your network charges for cross-zone transfer, it adds to that bill too.
Extra metric series
For metrics, the cost comes from series counts. Suppose the request duration histogram has 2,000 distinct series, one for each combination of service, route, method and status class. With dual emission both the old and new metric exist, so you hold 4,000 series. If a vendor charges, for illustration, ten cents per series per month, the extra cost is 2,000 times 0.10, which is 200 dollars per month for this one metric. Multiply by the number of metrics that change names, and the figure grows.
| Item | Illustrative value | How it is worked out |
|---|---|---|
| Extra bytes per span | 315 bytes | 9 attributes times 35 bytes |
| Extra throughput | about 15.75 MB per second | 50,000 spans times 315 bytes |
| Extra per day, uncompressed | about 1.36 TB | 15.75 MB times 86,400 seconds |
| Extra per day, compressed one in five | about 270 GB | 1.36 TB divided by 5 |
| Extra metric series | 2,000 | Old and new copies of 2,000 series |
| Extra monthly metric cost | about 200 dollars | 2,000 times 0.10 dollars |
Ways to keep the bill small
- Enable dual emission only for a pilot subset of services, long enough to verify dashboards, then roll forward.
- Use sampling on traces so fewer spans carry the doubled attributes.
- Drop the old names at the Collector as soon as dashboards are verified, even if applications still emit both.
- Set an end date for dual emission before you start and put it on the project calendar.
Dual emission is like keeping both the old and new phone numbers active when you move to a new city. It lets everyone reach you during the transition, but you pay two phone bills until you cancel the old line.
23Naming Your Own Attributes Safely
Stability guarantees apply to OpenTelemetry’s names. Your company’s custom attributes need their own care, and one trap in particular catches many teams.
Why you will need custom names
The standard cannot know your business. Facts like the customer tier, the shopping cart size, the feature flag in effect or the owning team are specific to you. You will add attributes for them, and those attributes become part of your own dashboards and alerts, so they deserve the same stability discipline.
The collision trap
Suppose you invent a custom attribute named with the database namespace, for example a field you add to describe the replica a query used. A year later, OpenTelemetry adds its own attribute under a similar name with a different meaning. Now two meanings share one name, your data is ambiguous, and an upgrade of a library may start writing the standard attribute on top of your custom one. This is the reason the project advises that custom attributes should not be placed inside the standard namespaces.
The safe pattern
Use a namespace that belongs to your organisation, such as a reversed domain name, for example a prefix like com.yourcompany followed by a short product or team area and then the field. The project’s guidance recommends such company-specific prefixes. It makes collisions with future standard names impossible, makes the owner obvious to anyone reading the data, and lets you filter all of your custom attributes with one pattern.
Treat your own names as a contract
- Keep a registry. A simple file listing each custom attribute, its type, meaning, owner and stability.
- Mark stability yourself. Use the same levels: development, stable, deprecated.
- Deprecate before you delete. Keep emitting the old name next to the new one for a stated period.
- Review additions. New attributes pass through a short review to catch collisions, high cardinality and sensitive content.
- Promote to standard when possible. If a custom attribute turns out to be broadly useful, propose it to the community.
| Approach | Example idea | Verdict |
|---|---|---|
| Custom field in a standard namespace | Adding your own field under the database group | Avoid, may collide later |
| Short invented prefix with no owner | A made-up two-letter prefix | Risky, unclear ownership |
| Reversed domain prefix | Your company’s reversed domain, then area, then field | Recommended |
| Vendor brand as prefix | Naming after the monitoring vendor | Avoid, re-creates lock-in |
24Building Your Own Company Convention Registry, Step by Step
Borrow the design that makes OpenTelemetry’s promises believable, and apply it at the scale of your own organisation.
Choose your prefix
Pick one reversed-domain prefix that every custom attribute will use, and publish it so nobody invents another.
List what you already have
Sample real telemetry and list every custom name in use, with the services and teams that emit it.
Describe each entry
For each name, record the type, meaning, allowed values, example, owner, requirement level and stability level.
Keep it as a file in version control
Use a simple structured file. Changes go through review, like code.
Add automated checks
Reject renames of anything marked stable, reject names outside your prefix or the standard namespaces, and flag missing descriptions.
Generate documentation and constants
Produce a documentation page and code constants for your main languages, so developers use the registry instead of typing strings.
Run a deprecation process
When a name must change, mark it deprecated with its replacement, emit both for a stated period, then remove the old one on a known date.
What an entry should say
A good entry is short. It names the attribute, says in one sentence what it means, gives its type, lists allowed values if it has any, shows an example, states who owns it, and states its level. If another engineer cannot tell from the entry how to fill the attribute in correctly, the entry is not finished. The same entry is what you will translate in a future vendor migration, so the time you spend writing it is repaid several times over.
Keeping it light
A registry that is too heavy will be ignored. Start with the fifty or so attributes that appear in your most important dashboards and alerts. Grow it only as teams need to add names. The goal is a living reference, not a bureaucracy.
Production example: a platform team’s registry as a migration asset
Organisations that maintain a small internal registry find that vendor changes and library upgrades become far cheaper. When a convention changes, they update one file, regenerate documentation and constants, and use the diff as a checklist of dashboards and alerts to touch. Without that file, the same work begins with weeks of archaeology.
25Governance: Who Decides and How
Promises are only as good as the process behind them. Here is how decisions about conventions are made, in outline.
Open working groups
Semantic conventions are developed in the open by working groups made up of maintainers, library authors, vendors and users. Proposals are public. Discussions happen in issues, pull requests and regular public meetings. This openness is part of the guarantee, since changes cannot be slipped in privately.
Area owners
Large areas, such as web, databases, messaging, cloud and generative AI, tend to have dedicated groups with domain experts. They decide how their area’s conventions should look and when they are ready for stability. Because each group moves at its own speed, the stability levels vary by area, which is why you may see stable web conventions next to still-evolving ones in other fields.
Cross-cutting rules
A central group maintains the naming rules, the requirement level definitions, the stability policy and the tooling. Their job is to make sure every area follows the same principles, so a developer who has learned one area can guess the shape of another.
Why stability moves slowly
Because a stable convention is expensive to change, the project is careful. It prefers to leave a convention in development a little too long rather than stabilise too early and be stuck with a poor design. This can frustrate teams that want certainty sooner, but the slowness is a feature: it is the price of a promise that holds.
If your business depends on a convention that is still in development, join the relevant working group meeting or comment on the proposals. A few real-world examples from production are some of the most valuable inputs the group can receive.
26Advantages, Disadvantages and Trade-offs
The stability model is a series of deliberate trade-offs. Seeing both sides helps you work with it rather than against it.
Advantages
- Dashboards and alerts survive for years
- Vendors can build features on stable names
- Data stays portable between tools
- Clear levels make risk visible
- Migration tools such as opt-in and schemas reduce pain
- Open process lets everyone influence outcomes
Disadvantages
- Stability arrives slowly, leaving areas in development for long
- A stable mistake is hard to fix
- Transition periods cost extra data and effort
- Different layers with different stability confuse newcomers
- Tooling for automatic translation is still maturing
- Teams must still manage their own upgrades
The central tension
There is a basic tug of war. Moving fast means new technologies get conventions quickly and mistakes are corrected cheaply. Moving carefully means users get a dependable foundation. OpenTelemetry resolves the tug by labelling instead of choosing: new things are born in development where speed is allowed, and only proven things graduate to stable where care is required. The cost is that users must read the labels.
| Choice | Benefit | Cost |
|---|---|---|
| Depend only on stable names | Maximum safety | Some useful signals are unavailable until they stabilise |
| Use development names with isolation | Early access to new signals | Ongoing maintenance when names change |
| Rewrite names in the Collector | One place to manage change | Hidden logic that must be documented |
| Enable dual emission for a period | Safe, reversible migration | Extra data and cost until it ends |
27Security and Privacy: Stable Names Are Not Safe Values
A reliable name tells you where a value is stored. It tells you nothing about whether the value is safe to store.
Sensitive attributes
Some standard attributes naturally capture sensitive content. The full web address of a request can include tokens, session identifiers or personal details in its query string. The text of a database query can contain customer names or card numbers if the application builds statements by joining strings. User agent strings, client addresses and user identifiers can all be personal data under privacy laws. The conventions mark certain attributes as opt-in or add guidance about sanitising for this reason.
What stability changes about security
Stability makes it easier to write reliable redaction rules, because the names where sensitive data may appear are predictable and will not move. A rule that scrubs the query string from the full-address attribute will keep working across years. That is a real benefit. But it also means a rule written against an old name will miss data when a library switches to the new name. During a migration, check that every redaction rule covers both old and new names, or sensitive data may leak under the new name even though your rules still run.
Defensive habits
- Redact at the Collector gateway so one rule protects every producer.
- Keep opt-in sensitive attributes off unless you have a defined need and a sanitising step.
- Test redaction after every upgrade by sending a known fake secret and confirming it never arrives.
- Review new stable names in each conventions release for fields that may hold personal data.
When names change, redaction rules are the easiest thing to forget. Add “check redaction rules” to the checklist for every convention migration.
28Monitoring Your Own Conformance
You cannot manage what you cannot see. A few checks keep your telemetry aligned with the conventions you think you follow.
Know which names are actually flowing
Produce a periodic report listing every distinct attribute name and metric name that appears in your telemetry, how often, and from which services. Compare it against the registry: which names are stable, which are development, which are deprecated, and which are unknown to the registry because they are custom or mistyped. Unknown names inside standard namespaces are often typos or accidental collisions and deserve a review.
Validate against the registry
The project’s tooling can compare telemetry against the registry, checking names, types and requirement levels, and can be run in a test environment or continuous integration pipeline for your own services. Running such a check on a staging service after each library upgrade catches a changed name before production does. Because tooling is evolving, review its current capabilities before building a process around it.
Track the migration state
Services emitting old names
How many still emit the old names, by team. This is your migration progress bar.
Services in dual emission
The number currently doubling their data and the age of each exception.
Queries using old names
Dashboards and alerts that still reference old names, found by searching your repositories.
Unknown names seen
Names not in any registry. A rising count suggests drift or collisions.
Freshness alerts
For each critical service, alert if a key metric has not been received for a few minutes. This single rule catches silent renames, outages and broken pipelines alike, and costs almost nothing to maintain.
29Design Patterns and Anti-Patterns
Teams that have lived through a few convention migrations converge on the same few habits, and the same few mistakes.
Pattern: golden signal layer
Define a small set of company-owned metrics for each service (traffic, errors, latency and saturation), computed from whichever source names are current. Everything above that layer reads only your names.
Pattern: stable by default, development by exception
Allow stable conventions anywhere, and require a short written justification and an owner for any development convention used in production dashboards or alerts.
Pattern: scheduled upgrade windows
Upgrade instrumentation libraries on a regular cadence, such as quarterly, with a standard checklist, rather than whenever a developer happens to bump a version. Predictability reduces surprise.
The mistake
Building paging alerts directly on development-level names because they were the only available signal.
Why it hurts
A routine release renames the name, the alert goes silent, and the first sign of trouble is an unreported outage.
The better way
Wrap the signal in a derived metric you own, add a freshness alert, and name an owner who reviews each release.
The mistake
Leaving dual emission on indefinitely because nobody owns turning it off.
Why it hurts
Data volume and series counts stay doubled, quietly inflating costs, and old dashboards never get fixed.
The better way
Set an end date up front, track it as a project milestone, and drop the old names at the Collector once dashboards are verified.
The mistake
Inventing custom attributes inside the standard namespaces.
Why it hurts
A future standard name may collide with yours, silently corrupting your data and confusing every reader.
The better way
Use a company-owned reversed-domain prefix and keep a small registry of your own names.
The mistake
Assuming that a stable SDK means stable attribute names across every library upgrade.
Why it hurts
The API may be stable while the telemetry it emits changes in a major release, breaking consumers that never saw a code change.
The better way
Treat library upgrades as potential naming changes: read release notes, canary one service, and compare data before and after.
30Best Practices and Common Mistakes
A compact checklist drawn from everything above.
Do these things
- Know the level of every name you depend on. Stable, development or deprecated, recorded next to each dashboard and alert.
- Prefer stable names in critical alerts and service level objectives.
- Read the conventions release notes before every library upgrade wave.
- Use the opt-in setting and dual emission as a bridge, with an end date.
- Make “no data” an alerting condition for anything important.
- Keep dashboards and alerts as code, so renames are searchable and reviewable.
- Canary every library upgrade on one service and compare before and after.
- Normalise names in the Collector while estates are mixed, and document each rule.
- Use your own reversed-domain prefix for custom attributes, and keep a registry.
- Keep schema URLs on your telemetry so you can always tell which edition of the names it follows.
- Re-check redaction rules whenever names change.
Common mistakes
| Mistake | What happens | Fix |
|---|---|---|
| Treating all “OpenTelemetry names” as equally safe | Alerts built on development names go silent after a release | Check the level of each name |
| Confusing SDK stability with convention stability | Surprise renames after a library upgrade | Read emitted-name notes in each library’s release |
| Ignoring unit changes | Dashboards off by a factor of a thousand | Compare magnitudes during dual emission |
| Forgetting freshness alerts | Silent failures stay hidden | Alert on missing data |
| Leaving dual emission on forever | Doubled data and cost | Set and enforce an end date |
| Hard-coding lists of allowed values | Breaks when new values are added | Handle unknown values gracefully |
| Redaction rules left on old names | Sensitive data leaks under new names | Cover both names during migration |
| Custom attributes inside standard namespaces | Future collisions | Use your own prefix |
| Rewriting names in many places | Nobody knows what transforms the data | Centralise in the gateway and document |
31A Worked Scenario: The Quarterly Upgrade That Went Quiet
Let us follow a made-up company through a convention migration, first the careless way and then the careful way. Everything here is invented for teaching.
The company
“ParcelPilot” runs a delivery-tracking platform with 80 services written in Java and Node.js on Kubernetes. It has 150 dashboards and 70 alerts that all rely on the older web request attribute names and metric names. A platform team of four manages shared libraries and the Collector.
The careless version
A developer notices the new major version of the Java instrumentation agent and bumps it across the shared base image on a Friday. By Monday morning, forty Java services emit the new stable names. The request latency dashboard shows flat lines for those services. Three paging alerts that watch error rates by status code never fire during a database incident on Tuesday, because they query the old status code attribute and the new data uses the new name. The outage runs for forty minutes before a customer reports it. Engineers spend two days rewriting queries in panic, and discover that the latency metric moved from milliseconds to seconds, so some rewritten alerts fire constantly.
The careful version
Now replay the story with the habits from this guide. In week one, the platform team reads the release notes of the new agent and sees the convention changes. They search the dashboard repository for the old names and find 62 dashboards and 19 alerts using them. In week two, a canary service is moved to dual emission, and the team compares old and new data, finding the unit change and one metric whose label set changed. In weeks three and four, owners update the 62 dashboards and 19 alerts, running old and new alerts in parallel, with freshness alerts added to the top ten services. In week five, dual emission is enabled for all Java services during a quiet week. In week seven, the Collector drops the old names and the dual setting is replaced by new-only. A calendar entry makes the end of dual emission an explicit milestone. Nobody is paged at night, and the only visible change is a slightly larger data bill for four weeks.
What made the difference
| Step | Careless | Careful |
|---|---|---|
| Read release notes | No | Yes, before any change |
| Search for old names | After the break | Before the upgrade |
| Canary service | None | One service, dual emission |
| Check units | Discovered by accident | Compared systematically |
| Alerts on missing data | No | Yes |
| End date for dual emission | Not applicable | Calendar milestone |
| Impact on customers | 40-minute silent outage | None |
The careful version did not need extra tools, only extra attention at the start. A single hour of searching and reading release notes saved days of firefighting.
32Real-World Patterns and Industry Signals
The details of individual migrations are rarely public, but the overall shape is visible across the industry.
Stable HTTP conventions as the first big migration
The web request conventions were the first widely used area to go through the full journey from experimental to stable, and they became the template for how later areas handle the same transition: a single deliberate renaming step, the opt-in setting, dual emission, and a long period during which both names are understood. Teams that handled that migration well now have a reusable internal playbook for the next area.
Consolidation of competing vocabularies
The contribution of Elastic’s common schema into OpenTelemetry’s conventions illustrates how stable shared names reduce duplication. When two vocabularies with overlapping meaning merge, users of both gain a single set of names and tools gain a single target, even though the merge itself requires a careful transition for existing users.
Language packages that separate stable from experimental
Several language ecosystems for OpenTelemetry publish stable convention constants separately from the ones still in development, often under a name containing “incubating” or “experimental”. This simple packaging decision turns an abstract policy into something a code reviewer can see in an import statement.
Fast-moving areas such as generative AI
Newer areas, including conventions for generative AI workloads, are intentionally in development while the community learns what matters. Teams adopting them early accept renames as a normal cost and isolate those names behind derived metrics, which is the pattern recommended throughout this guide.
Cloud and vendor documentation
Cloud providers and observability vendors increasingly document which semantic convention versions their products understand, and some publish upgrade guides for customers moving between versions. When evaluating a vendor, those documents are as informative as any feature list.
Stability levels of specific areas change with each release. Before relying on any of the examples above, check the current registry for the present status of the names you use.
33Decision Guide: How Much Risk Should You Take?
Use these questions to decide how to handle any given convention in your own systems.
flowchart TD
S["A convention you want to use"] --> L{"What is its level?"}
L -->|"Stable"| U1["Use freely and build dashboards on it"]
L -->|"Release candidate"| U2["Use with a derived metric and test closely"]
L -->|"Development"| C{"Is it critical to paging or SLOs?"}
C -->|"Yes"| U3["Wrap it in your own names and assign an owner"]
C -->|"No"| U4["Use for exploration and expect to revisit"]
L -->|"Deprecated"| U5["Migrate to the replacement on a ticket with a date"]
When to adopt the stable names now
- You are starting a new service or a new platform, so there is no old data to protect.
- Your vendor’s built-in screens already expect the stable names.
- You plan to change vendors and want the most portable names.
- You are about to upgrade libraries anyway and can fold the migration into that work.
When to wait
- You have large numbers of old dashboards and no capacity to rewrite them this quarter.
- Your key libraries do not yet support the opt-in setting for that area.
- Your vendor does not yet understand the new names.
Waiting is acceptable only if it is a decision with a date. “We will migrate later” without a date becomes a permanent state, and the gap between the standard and your systems grows.
34Troubleshooting Playbook
When data looks strange after an upgrade, work from the symptom to the likely cause.
| Symptom | Likely cause | First check |
|---|---|---|
| Dashboard chart goes flat after an upgrade | Metric renamed by the new library version | Search the backend for the new metric name |
| Alert stopped firing | Attribute it filters on was renamed | Query the alert’s attribute names against recent data |
| Numbers a thousand times smaller or larger | Unit change between versions | Compare the old and new metric’s unit and values |
| One service shows up twice | Old and new names create separate groups | Check the group-by attributes |
| Data volume jumped | Dual emission is on | Check the opt-in setting on the service |
| Library ignores the opt-in setting | That library or area does not support it yet | Read the library’s documentation and release notes |
| Filter on an attribute value finds nothing | New allowed values or different value format | List actual values seen in data |
| Vendor screen empty for new services | Vendor expects old names only | Ask the vendor, or translate in the Collector |
| Sensitive data appearing | Redaction rule covers only old names | Update rules to the new names |
| Unknown names appearing in reports | Typos or collision with a standard name | Compare against the registry |
A reliable order of investigation
Which versions changed?
List library, agent and Collector versions before and after. Most mysteries start with a version bump.
Which names are present?
List the names now arriving from the affected service and compare with the names the dashboard queries.
What do the release notes say?
Check both the library and the conventions release notes for renames, unit changes and new defaults.
Can a setting restore the old names?
Use dual emission or the old-names setting as a temporary fix while you update consumers.
Fix the consumer
Update dashboards and alerts to the new names, and remember the freshness alert so the next change is caught early.
35Myths and Misconceptions
A few ideas about stability sound sensible and are wrong.
The claim
If a convention is stable, upgrading libraries can never change my data.
The reality
Stable conventions do not change, but libraries can move from older names to stable ones in a new version. The promise covers the dictionary, not which edition a library uses.
The claim
Stable means complete, so nothing will ever be added.
The reality
New attributes and new allowed values may be added. Stable only means existing things will not change in breaking ways.
The claim
Development conventions are low quality and should be avoided.
The reality
Many are well designed and widely used. Development means the promise is weaker, not that the design is poor. Use them with isolation.
The claim
Schema files automatically fix everything when names change.
The reality
Schemas describe renames well but cannot handle every kind of change, and few tools apply them automatically yet. They are a blueprint more than a repair tool.
The claim
My vendor will handle all the renaming for me.
The reality
Vendors handle their own built-in screens. Your custom dashboards, alerts, parsing rules and scripts remain your responsibility.
The claim
A stable name guarantees the data under it is safe and cheap.
The reality
Names say where data lives, not what it contains or how many distinct values it has. Privacy and cardinality remain your job.
36Frequently Asked Questions
37Summary and Key Takeaways
What to remember
- Stability is a promise about names. Stable conventions will not be renamed, retyped, reinterpreted or removed in breaking ways. Only additions, clarifications and orderly deprecation are allowed.
- Levels tell you how much to trust. Development may change freely, release candidates are nearly final, stable is a long-term contract, and deprecated is on its way out. The level belongs to each convention, not to a whole project.
- The promise protects the dictionary, not your upgrade path. Libraries move to new names on their own schedule, so a library upgrade can still change your data.
- Use the bridges the project provides. The opt-in setting, dual emission and schema files exist to let you migrate in steps, but dual emission costs data and must have an end date.
- Protect consumers. Classify each name you depend on, prefer stable names in critical alerts, wrap development names in your own derived metrics, keep dashboards as code and alert on missing data.
- Own your custom names. Use a company-owned prefix, keep a small registry and apply the same levels to your own attributes.
- Watch the layers. Convention, specification, SDK, library and Collector stability are separate, and privacy, cardinality and vendor behaviour remain your responsibility.