OpenTelemetry semantic conventions reference
OpenTelemetry semantic conventions define the canonical names and value formats for attributes attached to spans, metrics, and logs. Using them means a query like db.system = postgresql works the same whether the data came from a Java, Go, or Python service. This reference lists common attribute keys, the namespace they belong to, their value type, and stability status.
Filter by key or namespace below to find the right attribute name for your instrumentation.
How it works
Attributes are namespaced dotted keys (http., db., rpc., messaging., network., server.). The OpenTelemetry specification fixes both the name and the expected value — for instance http.request.method must be an uppercase token like GET, and db.system uses a known identifier like postgresql or mysql. Each attribute carries a stability marker: Stable keys are frozen, Experimental keys may still change, and Deprecated keys point to a replacement.
Exceptions are modeled as a span event named exception carrying exception.type, exception.message, and exception.stacktrace. Resource attributes (service.name, service.version, telemetry.sdk.name) describe the producing entity and apply to every signal it emits. Following the conventions is what makes vendor-neutral dashboards and alerting possible.
Key attribute namespaces at a glance
HTTP attributes (stable)
| Attribute | Type | Example value |
|---|---|---|
http.request.method | string | "GET", "POST" (uppercase) |
http.response.status_code | int | 200, 404 |
url.full | string | "https://api.example.com/v1/orders" |
url.path | string | "/v1/orders" |
url.scheme | string | "https" |
server.address | string | "api.example.com" |
server.port | int | 443 |
network.protocol.version | string | "1.1", "2" |
Database attributes
| Attribute | Type | Example value |
|---|---|---|
db.system | string | "postgresql", "mysql", "redis" |
db.name | string | "orders_db" |
db.operation | string | "SELECT", "INSERT" |
db.statement | string | "SELECT * FROM orders WHERE id = ?" |
db.user | string | "app_user" |
server.address | string | Database host |
server.port | int | 5432 (PostgreSQL default) |
RPC attributes
| Attribute | Type | Example value |
|---|---|---|
rpc.system | string | "grpc", "jsonrpc", "dotnet_wcf" |
rpc.service | string | "OrderService" |
rpc.method | string | "GetOrder" |
rpc.grpc.status_code | int | 0 (OK), 14 (UNAVAILABLE) |
Exception event attributes
event name: "exception"
exception.type = "java.lang.NullPointerException"
exception.message = "Cannot invoke method getId() on null"
exception.stacktrace = "<full stack trace string>"
Migration: old vs new HTTP keys
Many codebases still use the pre-stable HTTP convention names. These are now deprecated:
| Deprecated | Current stable equivalent |
|---|---|
http.method | http.request.method |
http.status_code | http.response.status_code |
http.url | url.full |
http.host | server.address |
http.flavor | network.protocol.version |
During migration, emit both old and new keys for one release cycle so existing dashboards and alerts keep working while you update queries.
Tips and examples
A typical HTTP server span carries:
http.request.method = "GET"
url.path = "/api/orders"
http.response.status_code = 200
server.address = "api.example.com"
network.protocol.version = "1.1"
Prefer the SDK’s helper methods (setAttribute, recordException) over hand-writing keys to avoid typos. Stick to Stable attributes for production alerting; treat Experimental ones as best-effort. Always set service.name as a resource attribute so every signal from your service is correctly identified in your observability backend.