Benchmarking the stack turned up two Sentry settings that cost measurable RPS and are only reachable today by hand-building sentry_integrations or by stuffing sentry_additional_params.
1. SentryLogsHandler formats every log record for nothing
LoggingIntegration defaults to sentry_logs_level=INFO, which installs SentryLogsHandler. Its emit() calls self.format(record) before checking has_logs_enabled(client.options). lite-bootstrap never sets enable_logs, so for every lite-bootstrap service that handler formats every INFO+ record and then throws the result away.
This is amplified by LoggingInstrument: structlog is wired through structlog.stdlib.BoundLogger, so every structlog call goes through the patched logging.Logger.callHandlers and hits both Sentry handlers.
Measured on an endpoint emitting three structlog records per request (in-process, Apple M2, CPython 3.14.7, sentry-sdk 2.67.1):
| config |
+µs/req |
| defaults |
+99.7 |
LoggingIntegration(sentry_logs_level=None) |
+92.9 |
LoggingIntegration(level=None, sentry_logs_level=None) |
+73.3 |
The first delta is free - nothing is lost while Sentry Logs is disabled. The second costs you log breadcrumbs on error events, which is a real trade-off.
I have filed the format-before-check as an upstream bug against sentry-python (getsentry/sentry-python#7402). Even if it lands, passing sentry_logs_level=None while lite-bootstrap does not support Sentry Logs is the correct configuration.
2. auto_session_tracking is not exposed
SentryConfig does not surface it, so it defaults to True and every request starts and ends a Session (a uuid4, a lock acquisition, an aggregate update). Measured at ~7 µs/request. Services that do not use Sentry release health pay it silently.
Proposal
- Default
sentry_integrations to include LoggingIntegration(sentry_logs_level=None) when the user has not supplied their own logging integration. Behaviour-preserving.
- Add
sentry_auto_session_tracking: bool = True to SentryConfig, passed through to sentry_sdk.init. Default unchanged, knob documented.
- Optionally
sentry_logging_breadcrumb_level: int | None = logging.INFO for the breadcrumb handler, since that is the larger of the two costs for chatty services.
Context
For the whole picture: on a trivial endpoint through uvicorn, enabling Sentry at lite-bootstrap defaults costs 39% of throughput (7952 → 4850 RPS), and essentially all of it is the Starlette/FastAPI ASGI integration, not the knobs people normally reach for. attach_stacktrace, max_breadcrumbs and dropping the default integrations all measured as no-ops on the request path. Details in the sibling docs issue.
Benchmarking the stack turned up two Sentry settings that cost measurable RPS and are only reachable today by hand-building
sentry_integrationsor by stuffingsentry_additional_params.1.
SentryLogsHandlerformats every log record for nothingLoggingIntegrationdefaults tosentry_logs_level=INFO, which installsSentryLogsHandler. Itsemit()callsself.format(record)before checkinghas_logs_enabled(client.options). lite-bootstrap never setsenable_logs, so for every lite-bootstrap service that handler formats every INFO+ record and then throws the result away.This is amplified by
LoggingInstrument: structlog is wired throughstructlog.stdlib.BoundLogger, so every structlog call goes through the patchedlogging.Logger.callHandlersand hits both Sentry handlers.Measured on an endpoint emitting three structlog records per request (in-process, Apple M2, CPython 3.14.7, sentry-sdk 2.67.1):
LoggingIntegration(sentry_logs_level=None)LoggingIntegration(level=None, sentry_logs_level=None)The first delta is free - nothing is lost while Sentry Logs is disabled. The second costs you log breadcrumbs on error events, which is a real trade-off.
I have filed the format-before-check as an upstream bug against sentry-python (getsentry/sentry-python#7402). Even if it lands, passing
sentry_logs_level=Nonewhile lite-bootstrap does not support Sentry Logs is the correct configuration.2.
auto_session_trackingis not exposedSentryConfigdoes not surface it, so it defaults toTrueand every request starts and ends aSession(auuid4, a lock acquisition, an aggregate update). Measured at ~7 µs/request. Services that do not use Sentry release health pay it silently.Proposal
sentry_integrationsto includeLoggingIntegration(sentry_logs_level=None)when the user has not supplied their own logging integration. Behaviour-preserving.sentry_auto_session_tracking: bool = TruetoSentryConfig, passed through tosentry_sdk.init. Default unchanged, knob documented.sentry_logging_breadcrumb_level: int | None = logging.INFOfor the breadcrumb handler, since that is the larger of the two costs for chatty services.Context
For the whole picture: on a trivial endpoint through uvicorn, enabling Sentry at lite-bootstrap defaults costs 39% of throughput (7952 → 4850 RPS), and essentially all of it is the Starlette/FastAPI ASGI integration, not the knobs people normally reach for.
attach_stacktrace,max_breadcrumbsand dropping the default integrations all measured as no-ops on the request path. Details in the sibling docs issue.