For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/feature_flags/guide/server_flag_evaluation_metrics.md. A documentation index is available at /llms.txt.

Set Up Server-Side Flag Evaluation Metrics

This product is not supported for your selected Datadog site. ().

Overview

Flag evaluation metrics let you measure how often each variant of a feature flag is returned by your server-side application. Use these metrics to track flag adoption over time, verify targeting rules are working as expected, and graph flag evaluation data on dashboards.

The feature_flag.evaluations metric is experimental and may change or be removed in a future release.

Prerequisites

Before setting up flag evaluation metrics, confirm the following:

  • Server-side feature flags are already configured.
  • Datadog Agent 7.32.0 or later is running.
  • DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true is set on your application.
  • Your server-side tracer meets the minimum version for flag evaluation metrics support:
LanguageMinimum tracer version
.NET3.44.0
Go2.8.0
Java1.62.0
Node.js5.99.0
PHP1.21.1
Python4.7.0
Ruby2.32.0

Step 1: Enable the Agent OTLP receiver

Flag evaluation metrics are emitted over OpenTelemetry (OTLP). The Datadog Agent includes an OTLP receiver that is off by default. For setup instructions, see OTLP Ingestion by the Datadog Agent.

You only need to enable the protocol your application uses (gRPC on port 4317, or HTTP on port 4318).

If you are running Agent v7.61.0 or later in Docker, set HOST_PROC=/proc on the Agent container to work around a known issue with the OTLP pipeline.

Step 2: Configure your application

For all tracers except Java, set the following environment variable in addition to the standard server-side feature flag configuration. For Java, DD_METRICS_OTEL_ENABLED has no effect; see the Java: Add the OpenTelemetry SDK dependencies section instead.

# Enable flag evaluation metrics
DD_METRICS_OTEL_ENABLED=true

Java: Add the OpenTelemetry SDK dependencies

The Java provider records feature_flag.evaluations through the OpenTelemetry SDK and exports it over OTLP, so the opentelemetry-sdk-metrics and opentelemetry-exporter-otlp dependencies must be on your application’s classpath. Add them alongside your Java feature flag dependencies. Import the OpenTelemetry BOM so the OpenTelemetry API and SDK stay on the same version:

build.gradle

dependencies {
    implementation platform('io.opentelemetry:opentelemetry-bom:1.47.0')
    implementation 'io.opentelemetry:opentelemetry-sdk-metrics'
    implementation 'io.opentelemetry:opentelemetry-exporter-otlp'
}

build.gradle.kts

dependencies {
    implementation(platform("io.opentelemetry:opentelemetry-bom:1.47.0"))
    implementation("io.opentelemetry:opentelemetry-sdk-metrics")
    implementation("io.opentelemetry:opentelemetry-exporter-otlp")
}

pom.xml

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.47.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-metrics</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-otlp</artifactId>
    </dependency>
</dependencies>

On the Java tracer, the provider starts its OTLP metrics exporter automatically when the OpenTelemetry SDK is on the classpath. If the dependencies are missing, no metrics are emitted and the tracer logs OpenTelemetry SDK is not on the classpath.

In Spring Boot applications, Spring Boot's OpenTelemetry autoconfiguration also creates an OpenTelemetrySdk bean. If the OpenTelemetry SDK version it resolves does not match the OpenTelemetry API version on the classpath, startup fails with a BeanCreationException for the openTelemetry bean and NoClassDefFoundError: io/opentelemetry/sdk/internal/ScopeConfigurator. Importing the opentelemetry-bom as shown above keeps the API and SDK on the same version and resolves the error.

Ruby: Add the OpenTelemetry metrics gems

For Ruby applications, add the OpenTelemetry metrics SDK and OTLP metrics exporter gems to your application bundle:

Gemfile

gem "opentelemetry-metrics-sdk", ">= 0.8"
gem "opentelemetry-exporter-otlp-metrics", ">= 0.4"

Install the gems with bundle install. These gems provide the OpenTelemetry meter provider and OTLP metrics exporter. The Ruby tracer uses them when DD_METRICS_OTEL_ENABLED=true is set. If the gems are missing, the Ruby tracer does not emit feature_flag.evaluations metrics and logs Failed to load OpenTelemetry metrics gems.

Endpoint configuration

By default, most tracers send OTLP metrics to the Agent at DD_AGENT_HOST on port 4318 (HTTP). If your application already sets DD_AGENT_HOST to reach the Agent, no endpoint configuration is required.

Set an OTLP endpoint explicitly in any of these cases:

  • The Agent is not reachable at DD_AGENT_HOST on the default OTLP port (for example, a remote Agent or a non-default port).
  • You use the Java tracer. Its flag evaluation metrics exporter supports OTLP/HTTP only (gRPC is not supported) on port 4318. The Java tracer does not derive the endpoint from DD_AGENT_HOST and defaults to http://localhost:4318. Set OTEL_EXPORTER_OTLP_ENDPOINT to the Agent’s HTTP endpoint when the Agent is not on localhost.
  • You use the Python tracer. The Python tracer defaults to gRPC on port 4317, not HTTP. Enable the gRPC OTLP receiver on the Agent, or override the protocol to use HTTP instead:
OTEL_EXPORTER_OTLP_ENDPOINT=http://<AGENT_HOST>:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

To set the endpoint, use the standard OpenTelemetry variable:

# Point OTLP data at the Datadog Agent (HTTP, port 4318)
OTEL_EXPORTER_OTLP_ENDPOINT=http://<AGENT_HOST>:4318

# Or use gRPC (port 4317). For most tracers, the default protocol is http/protobuf,
# so set the protocol explicitly when switching to gRPC:
# OTEL_EXPORTER_OTLP_ENDPOINT=http://<AGENT_HOST>:4317
# OTEL_EXPORTER_OTLP_PROTOCOL=grpc

Replace <AGENT_HOST> with the hostname or IP address of your Datadog Agent.

Docker Compose example:

docker-compose.yml

services:
  datadog-agent:
    environment:
      - DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_GRPC_ENDPOINT=0.0.0.0:4317
      - DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_HTTP_ENDPOINT=0.0.0.0:4318
      - HOST_PROC=/proc  # If running Agent v7.61.0+ in Docker

  app-go:
    environment:
      - DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true
      - DD_METRICS_OTEL_ENABLED=true
      - OTEL_EXPORTER_OTLP_ENDPOINT=http://datadog-agent:4318
    depends_on:
      datadog-agent:
        condition: service_healthy

Step 3: Verify metrics are flowing

After deploying, confirm metrics are reaching Datadog:

  1. Go to Metrics Explorer and search for feature_flag.evaluations.
  2. If the metric does not appear within a few minutes of your application evaluating flags, check:
    • The Agent OTLP receiver is enabled and the correct port is exposed.
    • OTEL_EXPORTER_OTLP_ENDPOINT points to the Agent, not a separate collector.
    • Your application is actively evaluating flags with a server SDK at runtime (the code path is being executed).

Step 4: Enable metric retention

By default, feature_flag.evaluations retains only one hour of data. To retain a longer history:

  1. Go to Metrics Summary and search for feature_flag.evaluations.
  2. Select the metric and enable Historical Metrics.

This is an opt-in setting and is not enabled automatically for OTLP metrics.

Graph flag evaluations on a dashboard

Use the following query to graph flag evaluations by flag key and variant on a dashboard:

sum:feature_flag.evaluations{*} by {feature_flag.key,feature_flag.result.variant}

The feature_flag.evaluations metric is a counter with the following tags:

TagDescription
feature_flag.keyThe flag key being evaluated
feature_flag.result.variantThe variant returned by the evaluation
feature_flag.result.reasonThe reason for the evaluation result
feature_flag.result.allocation_keyThe identifier for the evaluated targeting rules (emitted only when present)
error.typeThe error type (emitted only on error evaluations)

Further reading