A wide event is a single structured record that captures every known attribute about one unit of work — one request, one transaction, one span — in a single row. Instead of scattering context across dozens of narrow log lines or pre-aggregated metrics, a wide event packs service metadata, user context, infrastructure details, timing breakdowns, error codes, feature flags, and business identifiers into one coherent record. Charity Majors popularized the term and the practice, framing it as the foundational primitive of structured observability: emit one event per request, make it as rich as possible, and let your query engine do the slicing.
Organizations care because modern distributed systems generate context that pre-aggregated metrics cannot capture. When an incident surfaces in production, engineers need to filter by combinations of attributes — customer tier, feature flag variant, upstream dependency, geographic region — that nobody anticipated at instrumentation time. Metrics stores require you to decide which dimensions matter before the incident happens. Wide events record everything and let you ask questions later. That shift from "what did we predict we would need" to "what actually happened" explains why the pattern has spread from observability tooling into CDN logging, security auditing, LLM inference tracking, and SaaS billing pipelines.
Key Takeaways
- A wide event captures all attributes of one unit of work in a single record, enabling arbitrary post-hoc analysis without re-instrumentation.
- OpenTelemetry spans are wide events by design, carrying resource attributes, span attributes, events, and timing in one structured record.
- Columnar storage formats handle wide, sparse schemas efficiently because absent columns cost near-zero storage through dictionary and run-length encoding.
Prometheus and similar metric stores create a new time series for every unique combination of label values, which means high-cardinality fields like user IDs or request IDs cause cardinality explosions. Wide events sidestep this entirely. An analytical query engine scans raw column values and filters at read time, so a field with ten million distinct values costs nothing extra at write time. This is the architectural divide that matters: metric stores require cardinality decisions at instrumentation time; wide event stores defer those decisions to query time.
A narrow log line records that an error occurred. A wide event records that the error occurred on behalf of user u-8821, during a canary deployment of version 2.4.1-rc3, on a host in us-east-1c, while the new-checkout-flow flag was enabled, with a downstream latency spike of 340ms from the payments service. Correlating that picture from separate logs, metrics, and trace backends takes minutes. Reading it from a single row takes milliseconds.
Wide event schemas grow over time as teams add instrumentation. Apache Iceberg supports adding columns without rewriting existing data files, and columnar formats like Parquet handle sparse columns gracefully. New attributes appended to future events appear as nulls in older partitions. Teams can extend their schema the moment a new dimension becomes relevant, not on a migration schedule.
Late materialization in columnar engines means a query that touches four columns out of three hundred reads only those four columns from disk. Width does not equal cost. The ClickBench benchmark tests queries against a 105-column web analytics table — a realistic wide event schema — and columnar engines consistently outperform row-oriented alternatives precisely because they skip irrelevant columns entirely.
OpenTelemetry Semantic Conventions define hundreds of standardized attribute names covering HTTP, databases, messaging, cloud providers, and more. Teams do not need to invent their own wide event schemas from scratch. Adopting semantic conventions means your wide events are immediately compatible with dashboards, alerting rules, and analysis tools built by the broader community. The W3C Trace Context specification further standardizes how traceparent and tracestate headers correlate wide events across service boundaries.
Wide does not mean unlimited. Emitting every possible attribute unconditionally inflates event size and may expose sensitive data. The practical discipline is to include anything that could distinguish one request from another in a debugging scenario: identifiers, categorical dimensions, timing breakdowns, and error context. PII fields require redaction or hashing before emission. Start with OpenTelemetry Semantic Conventions as a baseline and extend deliberately.
Wide events belong in analytical or log analytics backends, not in time-series databases or full-text search engines. Engineers accustomed to Elasticsearch or Prometheus sometimes route OTel data to those systems by default and then hit cardinality or performance walls. The correct backend is a columnar analytical store designed for high-cardinality, high-throughput telemetry workloads. Matching the data shape to the storage architecture is the single most impactful infrastructure decision when adopting wide events.
At high request rates, storing every wide event unsampled becomes expensive. Head-based sampling (decide at the trace root) and tail-based sampling (decide after seeing the full trace) both work, but tail-based sampling is operationally complex. Teams should plan their sampling strategy before wide events reach production scale. Storing sampled wide events with a sample_rate attribute lets downstream queries adjust aggregations to account for the sampling ratio.
1. Pick one high-value request type — an API endpoint, a background job, a CDN access log — and emit a structured JSON record for each execution.
2. Start with the relevant OpenTelemetry Semantic Conventions attributes for your domain, then append service-specific fields as needed.
3. Ship those records to a columnar analytical backend. Verify that you can filter by any single field and by arbitrary combinations of fields without pre-defining indexes.
4. Run a real incident or postmortem against the data. The test of a wide event schema is whether you can answer a question you did not anticipate when you wrote the instrumentation.
5. Extend the schema additively. Add new fields as new dimensions become relevant. Never rename existing fields in place — deprecate and replace with a versioned transition window.
For a practical worked example, CDN monitoring use cases show wide event schemas in production, and the OpenTelemetry and Grafana integration guide walks through an end-to-end OTel pipeline.
What column count makes an event “wide”?
No official threshold exists. Traditional log lines carry 5 to 20 fields; wide events typically carry 50 to 1,000-plus attributes. The term is qualitative: the intent is to capture all available context about one unit of work, not to hit a specific number. OpenTelemetry spans in complex services routinely exceed 100 attributes when semantic conventions are fully applied.
Won’t hundreds of columns waste storage?
Columnar formats store each column separately and compress independently. Parquet's dictionary and run-length encodings make sparse columns — those that are null or absent for most rows — cost near-zero. Repeated low-cardinality values like service name or region compress to almost nothing across millions of rows. Wide columnar tables are frequently more storage-efficient than equivalent narrow row-oriented schemas.
Are OpenTelemetry spans and wide events the same thing?
OTel spans are wide events by design — each span is one record for one operation, carrying resource attributes, span attributes, events, and timing. OTel log records similarly support an open-ended attributes map. Wide events are the conceptual pattern; OTel is the standardized implementation. Not all wide events use OTel — CDN access logs and custom application events follow the same pattern without the OTel SDK.
How do wide events affect my existing observability costs?
Consolidating context into fewer, richer records can reduce total event volume compared to emitting many narrow log lines for the same operation, which matters if current billing is per-event or per-GB ingested. However, richer data tends to invite more analysis, and Jevons Paradox applies: more efficient storage and querying often increases total data volume over time as teams instrument more aggressively because the cost per query drops.
How should I handle schema changes when new attributes appear?
Use additive-only evolution: append new fields, never rename or remove existing ones without a deprecation window. Apache Iceberg supports column additions without rewriting data files, and columnar query engines return null for columns absent in older partitions. Write queries that handle missing columns gracefully rather than assuming every column exists in every partition.