From 4aa9e959202ca8e40251ef0dd67cb38143856cf3 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 30 Oct 2026 12:55:46 +0100 Subject: [PATCH 1/3] ref(profiling): Remove transaction-based profiling The SDK runs with span streaming (trace_lifecycle="stream"), which only drives the continuous profiler. Transaction-based profiling is never started for streamed spans, so profiles_sampler and SENTRY_PROFILING_ENABLED no longer had any effect. Remove the transaction profiling path and its settings, leaving SENTRY_CONTINUOUS_PROFILING_ENABLED as the only switch. Continuous profiling keeps reading SENTRY_PROFILES_SAMPLE_RATE, so deployments need no config changes. Drop the unused SENTRY_PROFILE_SESSION_SAMPLE_RATE setting. --- src/sentry/conf/server.py | 28 ++++------------------------ src/sentry/conf/types/sdk_config.py | 2 -- src/sentry/utils/sdk.py | 18 ------------------ 3 files changed, 4 insertions(+), 44 deletions(-) diff --git a/src/sentry/conf/server.py b/src/sentry/conf/server.py index 5c1a38304a36..dd5c746d2b69 100644 --- a/src/sentry/conf/server.py +++ b/src/sentry/conf/server.py @@ -11,7 +11,7 @@ import sys from collections.abc import Callable, Mapping, MutableSequence from datetime import datetime, timedelta -from typing import Any, Final, Literal, Union, overload +from typing import Any, Literal, Union, overload from urllib.parse import urlparse import orjson @@ -2620,37 +2620,17 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]: SENTRY_SDK_THREADING_INTEGRATION = os.environ.get("SENTRY_SDK_DISABLE_THREADING") != "1" -# The sample rate to use for profiles. This is conditional on the usage of -# traces_sample_rate. So that means the true sample rate will be approximately -# traces_sample_rate * profiles_sample_rate -# (subject to things like the traces_sampler) -SENTRY_PROFILES_SAMPLE_RATE = 1 if DEBUG else 0 - -# We want to test a few schedulers possible in the profiler. Some are platform -# specific, and each have their own pros/cons. See the sdk for more details. -SENTRY_PROFILER_MODE: Final = "sleep" - -# To have finer control over which process will have profiling enabled, this -# environment variable will be required to enable profiling. +# To have finer control over which process will have continuous profiling enabled, +# this environment variable will be required to enable continuous profiling. # # This is because profiling requires that we run some stuff globally, and we # are not ready to run this on the more critical parts of the codebase such as # the ingest workers yet. -# -# This will allow us to have finer control over where we are running the -# profiler. For example, only on the web server. -SENTRY_PROFILING_ENABLED = os.environ.get("SENTRY_PROFILING_ENABLED", SPOTLIGHT) - -# To have finer control over which process will have continuous profiling enabled, -# this environment variable will be required to enable continuous profiling. -# -# This setting takes precedence over `SENTRY_PROFILING_ENABLED` forcing the SDK -# to operate under the continuous profiling model. SENTRY_CONTINUOUS_PROFILING_ENABLED = os.environ.get("SENTRY_CONTINUOUS_PROFILING_ENABLED", False) # The sample rate to use for continuous profile sessions. This sample rate is # evaluated once per process and the decision is used for the remainer of the session. -SENTRY_PROFILE_SESSION_SAMPLE_RATE = 1 if DEBUG else 0 +SENTRY_PROFILES_SAMPLE_RATE = 1 if DEBUG else 0 # Tells the sentry sdk to run under the trace lifecycle mode which # ensures the profiler is running whenever there is an active trace. diff --git a/src/sentry/conf/types/sdk_config.py b/src/sentry/conf/types/sdk_config.py index 098146bd4e7a..d2eb35ddf294 100644 --- a/src/sentry/conf/types/sdk_config.py +++ b/src/sentry/conf/types/sdk_config.py @@ -27,8 +27,6 @@ class SdkConfig(TypedDict): before_send_transaction: NotRequired[Callable[[Event, Hint], Event | None]] before_send_log: NotRequired[Callable[[Log, Hint], Log | None]] profiles_sample_rate: NotRequired[float] - profiles_sampler: NotRequired[Callable[[dict[str, Any]], float]] - profiler_mode: NotRequired[Literal["sleep", "thread", "gevent", "unknown"]] profile_session_sample_rate: NotRequired[float] profile_lifecycle: NotRequired[Literal["manual", "trace"]] enable_db_query_source: NotRequired[bool] diff --git a/src/sentry/utils/sdk.py b/src/sentry/utils/sdk.py index 20249aebffb1..d589b477dead 100644 --- a/src/sentry/utils/sdk.py +++ b/src/sentry/utils/sdk.py @@ -224,21 +224,6 @@ def traces_sampler(sampling_context): return float(settings.SENTRY_BACKEND_APM_SAMPLING or 0) -def profiles_sampler(sampling_context): - PROFILES_SAMPLING_RATE = { - "consumer.join": options.get("consumer.join.profiling.rate"), - "spans.process.process_message": options.get("spans.process-spans.profiling.rate"), - } - if "transaction_context" in sampling_context: - transaction_name = sampling_context["transaction_context"].get("name") - - if transaction_name in PROFILES_SAMPLING_RATE: - return PROFILES_SAMPLING_RATE[transaction_name] - - # Default to the sampling rate in settings - return float(settings.SENTRY_PROFILES_SAMPLE_RATE or 0) - - def before_send_transaction(event: Event, _: Hint) -> Event | None: # Discard generic redirects. # This condition can be removed once https://github.com/getsentry/team-sdks/issues/48 is fixed. @@ -362,9 +347,6 @@ def configure_sdk(): settings.SENTRY_PROFILES_SAMPLE_RATE or 0 ) sdk_options["profile_lifecycle"] = settings.SENTRY_PROFILE_LIFECYCLE - elif settings.SENTRY_PROFILING_ENABLED: - sdk_options["profiles_sampler"] = profiles_sampler - sdk_options["profiler_mode"] = settings.SENTRY_PROFILER_MODE from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.logging import LoggingIntegration From 75568ce5a2d5a444eea78b3d367b6e9bbc373b3e Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 30 Oct 2026 13:04:36 +0100 Subject: [PATCH 2/3] ref(profiling): Read session sample rate from SENTRY_PROFILE_SESSION_SAMPLE_RATE Use the existing (previously unread) SENTRY_PROFILE_SESSION_SAMPLE_RATE setting for the continuous profiler's session sample rate instead of SENTRY_PROFILES_SAMPLE_RATE, and remove SENTRY_PROFILES_SAMPLE_RATE. --- src/sentry/conf/server.py | 2 +- src/sentry/utils/sdk.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/conf/server.py b/src/sentry/conf/server.py index dd5c746d2b69..a1db31a21a49 100644 --- a/src/sentry/conf/server.py +++ b/src/sentry/conf/server.py @@ -2630,7 +2630,7 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]: # The sample rate to use for continuous profile sessions. This sample rate is # evaluated once per process and the decision is used for the remainer of the session. -SENTRY_PROFILES_SAMPLE_RATE = 1 if DEBUG else 0 +SENTRY_PROFILE_SESSION_SAMPLE_RATE = 1 if DEBUG else 0 # Tells the sentry sdk to run under the trace lifecycle mode which # ensures the profiler is running whenever there is an active trace. diff --git a/src/sentry/utils/sdk.py b/src/sentry/utils/sdk.py index d589b477dead..3ed477ec2351 100644 --- a/src/sentry/utils/sdk.py +++ b/src/sentry/utils/sdk.py @@ -344,7 +344,7 @@ def configure_sdk(): if settings.SENTRY_CONTINUOUS_PROFILING_ENABLED: sdk_options["profile_session_sample_rate"] = float( - settings.SENTRY_PROFILES_SAMPLE_RATE or 0 + settings.SENTRY_PROFILE_SESSION_SAMPLE_RATE or 0 ) sdk_options["profile_lifecycle"] = settings.SENTRY_PROFILE_LIFECYCLE From 5b62d552042e0df42ad9a3942bb12473173919dd Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 30 Oct 2026 13:33:16 +0100 Subject: [PATCH 3/3] ref(profiling): Remove profiles_sample_rate from SdkConfig The option only applies to transaction-based profiling, which is no longer configured. --- src/sentry/conf/types/sdk_config.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sentry/conf/types/sdk_config.py b/src/sentry/conf/types/sdk_config.py index d2eb35ddf294..7fbb52ee7f97 100644 --- a/src/sentry/conf/types/sdk_config.py +++ b/src/sentry/conf/types/sdk_config.py @@ -26,7 +26,6 @@ class SdkConfig(TypedDict): before_send: NotRequired[Callable[[Event, Hint], Event | None]] before_send_transaction: NotRequired[Callable[[Event, Hint], Event | None]] before_send_log: NotRequired[Callable[[Log, Hint], Log | None]] - profiles_sample_rate: NotRequired[float] profile_session_sample_rate: NotRequired[float] profile_lifecycle: NotRequired[Literal["manual", "trace"]] enable_db_query_source: NotRequired[bool]