# Session sampling

Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Frum%2Fsdk-installation%2Fflutter%2Fmobile%2Fconfiguration%2Fsession-sampling.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Frum%2Fsdk-installation%2Fflutter%2Fmobile%2Fconfiguration%2Fsession-sampling.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

### Exclude instrumentations from session sampling[​](#exclude-instrumentations-from-session-sampling "Direct link to Exclude instrumentations from session sampling")

`sdkSampler` (alias `sessionSampleRate`) gates the *entire* SDK by default. Use `excludeFromSampling` to keep specific instrumentation categories emitting events even when the session is sampled out — useful when you want to ship `sdkSampler: 0` (or a low rate) for cost control but still capture all errors and logs.

```
import 'package:cx_flutter_plugin/cx_excludable_instrumentation.dart';



var options = CXExporterOptions(

  // ...other options...

  sdkSampler: 0,

  excludeFromSampling: const [

    CXExcludableInstrumentation.errors,

    CXExcludableInstrumentation.logs,

  ],

);
```

Supported categories: `errors`, `logs`, `network`, `userInteractions`, `mobileVitals`, `customSpan`, `customMeasurement`. Defaults to an empty list — the sampler gates everything exactly as before. Requires iOS SDK ≥ 3.8.0 and Android SDK ≥ 2.12.0.

#### Telling excluded events apart in `beforeSend`[​](#telling-excluded-events-apart-in-beforesend "Direct link to telling-excluded-events-apart-in-beforesend")

Every event carries `isSessionSampledIn` (read-only). `false` means the event reached export only because its category is listed in `excludeFromSampling` — the session itself was sampled out. Use it in `beforeSend` to apply your own filtering on top of the exclude list, e.g. keep only errors from sampled-out sessions:

```
var options = CXExporterOptions(

  // ...other options...

  sdkSampler: 5,

  excludeFromSampling: const [

    CXExcludableInstrumentation.errors,

    CXExcludableInstrumentation.logs,

  ],

  beforeSend: (event) {

    // Session sampled out: forward only error-severity events, drop the rest.

    if (!event.isSessionSampledIn &&

        event.eventContext?.severity != CxLogSeverity.error) {

      return null;

    }

    return event;

  },

);
```

`event.isSessionSampledIn` is a convenience accessor over `event.sessionContext?.isSessionSampledIn`, and defaults to `true` when the event carries no session context. The flag is also mirrored on `instrumentation_data.otelSpan.attributes` as `cx_rum.session_context.isSessionSampledIn`.

Session identity is read-only in `beforeSend`: `isSessionSampledIn`, `session_id` and `session_creation_date` are restored from the SDK's own values after your callback returns, and clearing `sessionContext` entirely restores it whole. Writing to them has no effect. The user identity fields (`user_id`, `user_name`, `user_email`, `user_metadata`) remain editable, so redacting user data in `beforeSend` works as before.

> **Crash events do not reach `beforeSend`.** On both iOS and Android, crash events are uploaded directly by the native SDK rather than taking the round trip to Dart and back, so a dying process is not racing the extra hop. A `beforeSend` callback therefore never sees them: filtering, redaction, or label edits you apply there do **not** apply to crashes. If you need to keep data out of crash payloads, keep it out of the values you pass to the SDK (`setLabels`, `setUserContext`, `reportError` data) rather than relying on `beforeSend`.

Requires the native SDKs bundled with plugin ≥ 0.11.0 (iOS 2.13.1 / Android 2.19.1). Against older natives the flag is absent and reads as `true`.
