Documentation for automated readers
A curated documentation index is available at: https://grafana.com/llms.txt
A complete documentation index is available at: https://grafana.com/llms-full.txt
These indexes can help with page discovery before fetching individual documents.
This page is also available in Markdown, which may be easier for automated readers and AI tools to parse than HTML. The Markdown version is available at https://grafana.com/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sampling.md, or by sending Accept: text/markdown to https://grafana.com/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sampling/. For broader documentation discovery, the curated index is available at https://grafana.com/llms.txt and the complete index is available at https://grafana.com/llms-full.txt.
How to configure sampling in Faro
Faro makes sampling decisions on a per user-session basis. For sampled sessions, Faro samples and transmits every signal. Faro discards signals from un-sampled sessions.
Faro uses the configured sampling rate or a custom sampling function to determine what to sample. The sampling rate and sampling function need to set or return a sampling rate between 0 and 1. Where 0 is no signals sent and 1 is all. By default, Faro uses a sampling rate of 1.
The sampling function computes a sampling decision based on other properties for customer sampling needs. It gets contextual information injected, including multiple Faro Metadata objects.
Faro calculates a sampling decision:
- On page load, when Faro initializes and finds an invalid session in web-storage
- On session extend, when Faro auto-creates a new session or when you manually call
setSession(...)
Note
Faro uses a session-based sampling configured within the session configuration object. Consult the session tracking documentation to understand how Faro tracks and handles sessions and how to configure the session manager.
How to ensure sampling consistency between frontend and backend
Faro uses a head based sampling approach based on sessions. If a session isn’t part of a sample, Faro doesn’t send any data for that specific session, see the preceding section.
To ensure consistency between the sampled frontend and backend data it’s recommended to configure your backends to use parent-based sampling.
Note
Parent-based sampling is a technique to control sampling in a way that’s consistent across the different components of a distributed system. It ensures that a sampling decision propagates to all subsequent components that are part of the journey of a request.
If you use Faro’s web-tracing instrumentation, Faro tells the underlying tracing instrumentation the sampling result which sets the W3C sampled flag to inform subsequent instruments to record spans.
If you use OpenTelemetry for your backend instrumentation, you should set a parent-based sampler. For more information, refer to OpenTelemetry docs for the parent-based sampler.
Be aware of the consequence of this consistency. A parent-based sampler follows the decision it receives, so when a session isn’t part of the sample, your backend joins the trace but doesn’t record the server span. As a result, lowering the Faro sampling rate therefore reduces backend traces as well as frontend ones. If that isn’t what you want, refer to the following section.
How to keep backend sampling independent of the frontend
Use this approach when your backend services apply their own sampling, for example tail sampling in a collector, and you don’t want the frontend sampling rate to reduce backend traces.
For an un-sampled session, Faro’s web-tracing instrumentation still adds a traceparent header to outgoing fetch and XMLHttpRequest requests. The header carries a sampled flag of 00 (not sampled).
Backend OpenTelemetry SDKs use a parent-based sampler by default, so they honor that flag and don’t record the span.
Set omitTraceContextForUnsampledSessions on the tracing instrumentation to leave the header out entirely for un-sampled sessions. Each backend service then applies its own sampling rules to those requests.
import { getWebInstrumentations, initializeFaro } from '@grafana/faro-web-sdk';
import { TracingInstrumentation } from '@grafana/faro-web-tracing';
initializeFaro({
...
sessionTracking: {
samplingRate: 0.1,
},
instrumentations: [
...getWebInstrumentations(),
new TracingInstrumentation({ omitTraceContextForUnsampledSessions: true }),
],
});Sampled sessions are unaffected. They continue to send a traceparent with a sampled flag of 01, and your backend joins and records the frontend trace.
The following table summarizes the behavior:
| Session | Option | traceparent sent | Backend result |
|---|---|---|---|
| Sampled | Either value | Sampled flag 01 | Joins the trace and records the span |
| Un-sampled | false (default) | Sampled flag 00 | Joins the trace but records nothing |
| Un-sampled | true | Not sent | Records the request as a new trace |
Consider the following before you enable this option:
- Requests from un-sampled sessions start a new trace at your backend instead of continuing the frontend trace, so you can’t navigate from those traces back to a browser session. Faro already discarded every frontend span for an un-sampled session, so the frontend end of that link would hold no data.
- If you supply your own
propagator, this option withholds everything that propagator writes for un-sampled sessions, includingtracestateandbaggage, not onlytraceparent. - Requests from un-sampled sessions are sampled by your backend services, so they contribute to backend trace volume at whatever rate those services use.
Set a sampling rate
Sets the sampling rate to 80% of sessions.
initializeFaro({
...
sessionTracking?: {
samplingRate: 0.8,
}Use the sampler function to calculate custom sampling rates
Use a custom sampler function to calculate a tailored sampling decision. In this case different sampling decisions based on the planet name.
Note
Defining sampling rates based on metadata or other properties can introduce bias in the sampling decisions. A custom sampler function is commonly used when running experiments in production or when there is an interest on specific types of traffic.
initializeFaro({
...
sessionTracking?: {
sampler(context) {
const planet = context.metas.user?.attributes?.['planet'];
if (!planet) {
return 0; // 0%
}
if (planet === 'mars') {
return 0.8; // 80%
}
if (planet === 'moon') {
return 0.3; // 30%
}
if (planet === 'earth') {
return 0.1; // 10%
}
return 1;
},
};
});Was this page helpful?
Related resources from Grafana Labs


