From 55360da106569f23911ffe40cac4a4916c181548 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 20 Feb 2026 15:15:37 -0500 Subject: [PATCH 1/9] feat: Add definition to the logs spec --- develop-docs/sdk/telemetry/logs.mdx | 45 ++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 6bb46e3ef9f72..f6b661c465951 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -2,7 +2,7 @@ title: Logs description: Structured logging protocol with severity levels, trace context, and batched envelope delivery. spec_id: sdk/telemetry/logs -spec_version: 1.15.0 +spec_version: 1.16.0 spec_status: stable spec_depends_on: - id: sdk/foundations/transport/envelopes @@ -10,6 +10,9 @@ spec_depends_on: - id: sdk/foundations/state-management/scopes/attributes version: ">=1.0.0" spec_changelog: + - version: 1.16.0 + date: 2026-02-06 + summary: Added sentry.log.sequence default attribute for deterministic log ordering - version: 1.15.0 date: 2026-02-03 summary: Clarified 100 logs per envelope hard limit, SDKs MAY use lower buffer limit @@ -153,6 +156,7 @@ SDKs **MUST** attach the following attributes to every log: | `sentry.sdk.name` | 1.0.0 | The name of the SDK that sent the log. | | `sentry.sdk.version` | 1.0.0 | The version of the SDK that sent the log. | | `sentry.replay_id` | 1.8.0 | The replay ID of the active replay when the log was collected. **MUST NOT** be set if no replay is active. | +| `sentry.log.sequence` | 1.16.0 | A monotonically incrementing integer counter used to determine correct ordering of logs when timestamps are identical. See [Log Ordering](#log-ordering). | For parameterized logs, SDKs **MUST** also attach: @@ -290,6 +294,27 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ +### Log Ordering + + + +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.log.sequence` integer attribute to every log. + +The sequence number **MUST**: +- Start at `0` when the SDK initializes. +- Increment by `1` for each log that is captured. +- Be scoped to the SDK instance lifetime. It resets naturally on process restart. + +The sequence number **MUST NOT**: +- Be intentionally reset during the process lifetime. +- Be used to modify or synthesize sub-millisecond timestamp precision. + +The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. + + + +### Debug Mode + ### Debug Mode @@ -563,7 +588,8 @@ A complete `log` envelope with six log entries at different severity levels: }, "sentry.message.parameter.0": { "value": 120, "type": "integer" }, "sentry.message.parameter.1": { "value": 85, "type": "integer" }, - "sentry.message.parameter.2": { "value": 60, "type": "integer" } + "sentry.message.parameter.2": { "value": 60, "type": "integer" }, + "sentry.log.sequence": { "value": 0, "type": "integer" } } }, { @@ -588,7 +614,8 @@ A complete `log` envelope with six log entries at different severity levels: "value": "ProductCard", "type": "string" }, - "sentry.message.parameter.1": { "value": 3, "type": "integer" } + "sentry.message.parameter.1": { "value": 3, "type": "integer" }, + "sentry.log.sequence": { "value": 1, "type": "integer" } } }, { @@ -613,7 +640,8 @@ A complete `log` envelope with six log entries at different severity levels: "value": "checkout_form", "type": "string" }, - "sentry.message.parameter.1": { "value": 8, "type": "integer" } + "sentry.message.parameter.1": { "value": 8, "type": "integer" }, + "sentry.log.sequence": { "value": 2, "type": "integer" } } }, { @@ -639,7 +667,8 @@ A complete `log` envelope with six log entries at different severity levels: "type": "string" }, "sentry.message.parameter.1": { "value": 2500, "type": "integer" }, - "sentry.message.parameter.2": { "value": 1000, "type": "integer" } + "sentry.message.parameter.2": { "value": 1000, "type": "integer" }, + "sentry.log.sequence": { "value": 3, "type": "integer" } } }, { @@ -666,7 +695,8 @@ A complete `log` envelope with six log entries at different severity levels: "sentry.message.parameter.0": { "value": "prod_123, prod_456", "type": "string" - } + }, + "sentry.log.sequence": { "value": 4, "type": "integer" } } }, { @@ -695,7 +725,8 @@ A complete `log` envelope with six log entries at different severity levels: "sentry.message.parameter.1": { "value": "UPDATE_CART", "type": "string" - } + }, + "sentry.log.sequence": { "value": 5, "type": "integer" } } } ] From 2689a7fa3917d53736612f583d7160b8426e6f40 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 24 Feb 2026 12:25:07 -0500 Subject: [PATCH 2/9] ref: rename the attribute --- develop-docs/sdk/telemetry/logs.mdx | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index f6b661c465951..79d255fea619f 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -12,7 +12,7 @@ spec_depends_on: spec_changelog: - version: 1.16.0 date: 2026-02-06 - summary: Added sentry.log.sequence default attribute for deterministic log ordering + summary: Added sentry.timestamp.sequence default attribute for deterministic log ordering - version: 1.15.0 date: 2026-02-03 summary: Clarified 100 logs per envelope hard limit, SDKs MAY use lower buffer limit @@ -156,7 +156,7 @@ SDKs **MUST** attach the following attributes to every log: | `sentry.sdk.name` | 1.0.0 | The name of the SDK that sent the log. | | `sentry.sdk.version` | 1.0.0 | The version of the SDK that sent the log. | | `sentry.replay_id` | 1.8.0 | The replay ID of the active replay when the log was collected. **MUST NOT** be set if no replay is active. | -| `sentry.log.sequence` | 1.16.0 | A monotonically incrementing integer counter used to determine correct ordering of logs when timestamps are identical. See [Log Ordering](#log-ordering). | +| `sentry.timestamp.sequence` | 1.16.0 | A monotonically incrementing integer counter used to determine correct ordering of logs when timestamps are identical. See [Log Ordering](#log-ordering). | For parameterized logs, SDKs **MUST** also attach: @@ -298,18 +298,16 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ -Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.log.sequence` integer attribute to every log. +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. The sequence number **MUST**: - Start at `0` when the SDK initializes. - Increment by `1` for each log that is captured. -- Be scoped to the SDK instance lifetime. It resets naturally on process restart. +- Reset to `0` when: + - The SDK is re-initialized. + - The current log's timestamp is strictly greater than the previous log's timestamp. -The sequence number **MUST NOT**: -- Be intentionally reset during the process lifetime. -- Be used to modify or synthesize sub-millisecond timestamp precision. - -The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. +The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive logs that share the same timestamp. @@ -589,7 +587,7 @@ A complete `log` envelope with six log entries at different severity levels: "sentry.message.parameter.0": { "value": 120, "type": "integer" }, "sentry.message.parameter.1": { "value": 85, "type": "integer" }, "sentry.message.parameter.2": { "value": 60, "type": "integer" }, - "sentry.log.sequence": { "value": 0, "type": "integer" } + "sentry.timestamp.sequence": { "value": 0, "type": "integer" } } }, { @@ -615,7 +613,7 @@ A complete `log` envelope with six log entries at different severity levels: "type": "string" }, "sentry.message.parameter.1": { "value": 3, "type": "integer" }, - "sentry.log.sequence": { "value": 1, "type": "integer" } + "sentry.timestamp.sequence": { "value": 1, "type": "integer" } } }, { @@ -641,7 +639,7 @@ A complete `log` envelope with six log entries at different severity levels: "type": "string" }, "sentry.message.parameter.1": { "value": 8, "type": "integer" }, - "sentry.log.sequence": { "value": 2, "type": "integer" } + "sentry.timestamp.sequence": { "value": 2, "type": "integer" } } }, { @@ -668,7 +666,7 @@ A complete `log` envelope with six log entries at different severity levels: }, "sentry.message.parameter.1": { "value": 2500, "type": "integer" }, "sentry.message.parameter.2": { "value": 1000, "type": "integer" }, - "sentry.log.sequence": { "value": 3, "type": "integer" } + "sentry.timestamp.sequence": { "value": 3, "type": "integer" } } }, { @@ -696,7 +694,7 @@ A complete `log` envelope with six log entries at different severity levels: "value": "prod_123, prod_456", "type": "string" }, - "sentry.log.sequence": { "value": 4, "type": "integer" } + "sentry.timestamp.sequence": { "value": 4, "type": "integer" } } }, { @@ -726,7 +724,7 @@ A complete `log` envelope with six log entries at different severity levels: "value": "UPDATE_CART", "type": "string" }, - "sentry.log.sequence": { "value": 5, "type": "integer" } + "sentry.timestamp.sequence": { "value": 5, "type": "integer" } } } ] From c32061bda70a6fc641491542e62f9b44ce0585a8 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 24 Feb 2026 12:27:32 -0500 Subject: [PATCH 3/9] feat: add the attribute to metrics --- develop-docs/sdk/telemetry/metrics.mdx | 40 ++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/develop-docs/sdk/telemetry/metrics.mdx b/develop-docs/sdk/telemetry/metrics.mdx index 30664770f81d3..607800908f17b 100644 --- a/develop-docs/sdk/telemetry/metrics.mdx +++ b/develop-docs/sdk/telemetry/metrics.mdx @@ -2,7 +2,7 @@ title: Metrics description: Counter, gauge, and distribution metrics sent as batched trace_metric envelope items. spec_id: sdk/telemetry/metrics -spec_version: 2.5.0 +spec_version: 2.6.0 spec_status: stable spec_depends_on: - id: sdk/foundations/transport/envelopes @@ -10,6 +10,9 @@ spec_depends_on: - id: sdk/foundations/state-management/scopes/attributes version: ">=1.0.0" spec_changelog: + - version: 2.6.0 + date: 2026-02-06 + summary: Added sentry.timestamp.sequence default attribute for deterministic metric ordering - version: 2.5.0 date: 2026-02-12 summary: Clarified sendDefaultPii gating for user attributes — allowed when user manually sets data @@ -114,6 +117,7 @@ SDKs **MUST** attach the following attributes to every metric by default: 2. `sentry.release` — the release set in the SDK, if defined. 3. `sentry.sdk.name` — the name of the SDK that sent the metric. 4. `sentry.sdk.version` — the version of the SDK that sent the metric. +5. `sentry.timestamp.sequence` — a monotonically incrementing integer counter used to determine correct ordering of metrics when timestamps are identical. See [Metric Ordering](#metric-ordering). SDKs **SHOULD** minimize the number of default attributes. Metrics cardinality can explode quickly with too many attributes. New default attributes **SHOULD** only be added after significant feedback from users and discussion internally with the SDK and ingest teams. @@ -187,6 +191,25 @@ Whenever possible, metrics **SHOULD** be linked to replays. If a metric is recor +### Metric Ordering + + + +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. + +The sequence number **MUST**: +- Start at `0` when the SDK initializes. +- Increment by `1` for each metric that is captured. +- Reset to `0` when: + - The SDK is re-initialized. + - The current metric's timestamp is strictly greater than the previous metric's timestamp. + +The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive metrics that share the same timestamp. + + + +### Data Category and Rate Limiting + ### Data Category and Rate Limiting @@ -547,7 +570,8 @@ SentrySDK.metrics() "sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" }, "sentry.sdk.version": { "value": "10.17.0", "type": "string" }, "sentry.environment": { "value": "production", "type": "string" }, - "sentry.release": { "value": "1.0.0", "type": "string" } + "sentry.release": { "value": "1.0.0", "type": "string" }, + "sentry.timestamp.sequence": { "value": 0, "type": "integer" } } }, { @@ -562,7 +586,8 @@ SentrySDK.metrics() "endpoint": { "value": "/api/users", "type": "string" }, "method": { "value": "POST", "type": "string" }, "sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" }, - "sentry.sdk.version": { "value": "10.17.0", "type": "string" } + "sentry.sdk.version": { "value": "10.17.0", "type": "string" }, + "sentry.timestamp.sequence": { "value": 1, "type": "integer" } } }, { @@ -577,7 +602,8 @@ SentrySDK.metrics() "cache_name": { "value": "user_sessions", "type": "string" }, "region": { "value": "us-west-1", "type": "string" }, "sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" }, - "sentry.sdk.version": { "value": "10.17.0", "type": "string" } + "sentry.sdk.version": { "value": "10.17.0", "type": "string" }, + "sentry.timestamp.sequence": { "value": 0, "type": "integer" } } }, { @@ -593,7 +619,8 @@ SentrySDK.metrics() "table": { "value": "users", "type": "string" }, "sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" }, "sentry.sdk.version": { "value": "10.17.0", "type": "string" }, - "sentry.origin": { "value": "auto.db.graphql", "type": "string" } + "sentry.origin": { "value": "auto.db.graphql", "type": "string" }, + "sentry.timestamp.sequence": { "value": 1, "type": "integer" } } }, { @@ -607,7 +634,8 @@ SentrySDK.metrics() "cohort": { "value": "beta", "type": "string" }, "sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" }, "sentry.sdk.version": { "value": "10.17.0", "type": "string" }, - "sentry.replay_id": { "value": "36b75d9fa11f45459412a96c41bdf691", "type": "string" } + "sentry.replay_id": { "value": "36b75d9fa11f45459412a96c41bdf691", "type": "string" }, + "sentry.timestamp.sequence": { "value": 0, "type": "integer" } } } ] From 101230f71c4a1721bb716b282b576f80580fbe5d Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 24 Feb 2026 15:46:35 -0500 Subject: [PATCH 4/9] chore: clarify reset timing --- develop-docs/sdk/telemetry/logs.mdx | 2 +- develop-docs/sdk/telemetry/metrics.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 79d255fea619f..b61e918077c2b 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -305,7 +305,7 @@ The sequence number **MUST**: - Increment by `1` for each log that is captured. - Reset to `0` when: - The SDK is re-initialized. - - The current log's timestamp is strictly greater than the previous log's timestamp. + - The current log's integer millisecond differs from the previous log's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes). The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive logs that share the same timestamp. diff --git a/develop-docs/sdk/telemetry/metrics.mdx b/develop-docs/sdk/telemetry/metrics.mdx index 607800908f17b..7130f9146db5d 100644 --- a/develop-docs/sdk/telemetry/metrics.mdx +++ b/develop-docs/sdk/telemetry/metrics.mdx @@ -202,7 +202,7 @@ The sequence number **MUST**: - Increment by `1` for each metric that is captured. - Reset to `0` when: - The SDK is re-initialized. - - The current metric's timestamp is strictly greater than the previous metric's timestamp. + - The current metric's integer millisecond differs from the previous metric's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes). The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive metrics that share the same timestamp. From 3db724fe7c7c79190ca0d5f08f1eb11b8e7b92b6 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 25 Feb 2026 12:20:34 -0500 Subject: [PATCH 5/9] docs: added a note about being able to omit it if unceessary --- develop-docs/sdk/telemetry/logs.mdx | 2 ++ develop-docs/sdk/telemetry/metrics.mdx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index b61e918077c2b..9cef33e27beea 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -307,6 +307,8 @@ The sequence number **MUST**: - The SDK is re-initialized. - The current log's integer millisecond differs from the previous log's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes). +SDKs **MAY** omit `sentry.timestamp.sequence` if the runtime provides sub-millisecond timestamp precision and does not freeze timer APIs, since ordering is already deterministic from timestamps alone. + The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive logs that share the same timestamp. diff --git a/develop-docs/sdk/telemetry/metrics.mdx b/develop-docs/sdk/telemetry/metrics.mdx index 7130f9146db5d..211c7b95fbd55 100644 --- a/develop-docs/sdk/telemetry/metrics.mdx +++ b/develop-docs/sdk/telemetry/metrics.mdx @@ -204,6 +204,8 @@ The sequence number **MUST**: - The SDK is re-initialized. - The current metric's integer millisecond differs from the previous metric's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes). +SDKs **MAY** omit `sentry.timestamp.sequence` if the runtime provides sub-millisecond timestamp precision and does not freeze timer APIs, since ordering is already deterministic from timestamps alone. + The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive metrics that share the same timestamp. From 578eb4d62b450b9ffa86629660cfae039bd510ca Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 25 Feb 2026 12:29:23 -0500 Subject: [PATCH 6/9] chore: wording --- develop-docs/sdk/telemetry/logs.mdx | 2 +- develop-docs/sdk/telemetry/metrics.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 9cef33e27beea..75b0c238766d8 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -298,7 +298,7 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ -Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. In those cases, to guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. The sequence number **MUST**: - Start at `0` when the SDK initializes. diff --git a/develop-docs/sdk/telemetry/metrics.mdx b/develop-docs/sdk/telemetry/metrics.mdx index 211c7b95fbd55..5b811d143d821 100644 --- a/develop-docs/sdk/telemetry/metrics.mdx +++ b/develop-docs/sdk/telemetry/metrics.mdx @@ -195,7 +195,7 @@ Whenever possible, metrics **SHOULD** be linked to replays. If a metric is recor -Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. In those cases, to guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. The sequence number **MUST**: - Start at `0` when the SDK initializes. From 28e1e47fe20fc67dcf3700a70e3739efa69b97c5 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 25 Feb 2026 15:06:26 -0500 Subject: [PATCH 7/9] chore: consistency in requirement --- develop-docs/sdk/telemetry/logs.mdx | 8 +++----- develop-docs/sdk/telemetry/metrics.mdx | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 75b0c238766d8..0a7b93bcffd68 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -156,7 +156,7 @@ SDKs **MUST** attach the following attributes to every log: | `sentry.sdk.name` | 1.0.0 | The name of the SDK that sent the log. | | `sentry.sdk.version` | 1.0.0 | The version of the SDK that sent the log. | | `sentry.replay_id` | 1.8.0 | The replay ID of the active replay when the log was collected. **MUST NOT** be set if no replay is active. | -| `sentry.timestamp.sequence` | 1.16.0 | A monotonically incrementing integer counter used to determine correct ordering of logs when timestamps are identical. See [Log Ordering](#log-ordering). | +| `sentry.timestamp.sequence` | 1.16.0 | A monotonically incrementing integer counter used to determine correct ordering of logs when timestamps are identical. **MUST** be sent on runtimes with frozen or low-precision timers, **MAY** be omitted otherwise. See [Log Ordering](#log-ordering). | For parameterized logs, SDKs **MUST** also attach: @@ -298,17 +298,15 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ -Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. In those cases, to guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it. -The sequence number **MUST**: +When sent, the sequence number **MUST**: - Start at `0` when the SDK initializes. - Increment by `1` for each log that is captured. - Reset to `0` when: - The SDK is re-initialized. - The current log's integer millisecond differs from the previous log's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes). -SDKs **MAY** omit `sentry.timestamp.sequence` if the runtime provides sub-millisecond timestamp precision and does not freeze timer APIs, since ordering is already deterministic from timestamps alone. - The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive logs that share the same timestamp. diff --git a/develop-docs/sdk/telemetry/metrics.mdx b/develop-docs/sdk/telemetry/metrics.mdx index 5b811d143d821..9062ef17032e1 100644 --- a/develop-docs/sdk/telemetry/metrics.mdx +++ b/develop-docs/sdk/telemetry/metrics.mdx @@ -117,7 +117,7 @@ SDKs **MUST** attach the following attributes to every metric by default: 2. `sentry.release` — the release set in the SDK, if defined. 3. `sentry.sdk.name` — the name of the SDK that sent the metric. 4. `sentry.sdk.version` — the version of the SDK that sent the metric. -5. `sentry.timestamp.sequence` — a monotonically incrementing integer counter used to determine correct ordering of metrics when timestamps are identical. See [Metric Ordering](#metric-ordering). +5. `sentry.timestamp.sequence` — a monotonically incrementing integer counter used to determine correct ordering of metrics when timestamps are identical. **MUST** be sent on runtimes with frozen or low-precision timers, **MAY** be omitted otherwise. See [Metric Ordering](#metric-ordering). SDKs **SHOULD** minimize the number of default attributes. Metrics cardinality can explode quickly with too many attributes. New default attributes **SHOULD** only be added after significant feedback from users and discussion internally with the SDK and ingest teams. @@ -195,17 +195,15 @@ Whenever possible, metrics **SHOULD** be linked to replays. If a metric is recor -Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. In those cases, to guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. +Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it. -The sequence number **MUST**: +When sent, the sequence number **MUST**: - Start at `0` when the SDK initializes. - Increment by `1` for each metric that is captured. - Reset to `0` when: - The SDK is re-initialized. - The current metric's integer millisecond differs from the previous metric's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes). -SDKs **MAY** omit `sentry.timestamp.sequence` if the runtime provides sub-millisecond timestamp precision and does not freeze timer APIs, since ordering is already deterministic from timestamps alone. - The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive metrics that share the same timestamp. From 5f550bfe086d77b3078cc94d657b7c01489ba22f Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 27 Feb 2026 17:00:10 +0100 Subject: [PATCH 8/9] docs: use more accurate type name Co-authored-by: Alex Krawiec --- develop-docs/sdk/telemetry/logs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 0a7b93bcffd68..d84543911ab91 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -300,7 +300,7 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it. -When sent, the sequence number **MUST**: +When sent, the sequence integer **MUST**: - Start at `0` when the SDK initializes. - Increment by `1` for each log that is captured. - Reset to `0` when: From f7619829f71ceca064aa591e442cebddf974c979 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 27 Feb 2026 17:00:25 +0100 Subject: [PATCH 9/9] docs: use more accurate type name Co-authored-by: Alex Krawiec --- develop-docs/sdk/telemetry/metrics.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/sdk/telemetry/metrics.mdx b/develop-docs/sdk/telemetry/metrics.mdx index 9062ef17032e1..d4c1ed870e517 100644 --- a/develop-docs/sdk/telemetry/metrics.mdx +++ b/develop-docs/sdk/telemetry/metrics.mdx @@ -197,7 +197,7 @@ Whenever possible, metrics **SHOULD** be linked to replays. If a metric is recor Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it. -When sent, the sequence number **MUST**: +When sent, the sequence integer **MUST**: - Start at `0` when the SDK initializes. - Increment by `1` for each metric that is captured. - Reset to `0` when: