Analytics Exporter
Understand how the Analytics Exporter sends product telemetry data from your Self-Managed Orchestration Cluster to Camunda, how to enable and configure it, and exactly what data it sends.
About
The Analytics Exporter sends product telemetry from your Orchestration Cluster to a Camunda-operated analytics endpoint over OTLP/HTTP.
Camunda uses this data to verify contractual usage, understand how the product is used, and support your deployment. For what Camunda collects and why across all products, see data collection.
The exporter is disabled by default. No data leaves your cluster until you add the exporter to your broker configuration.
The exporter sends process metadata only. It never sends process variables, payloads, message contents, job variables, incident error messages, or BPMN, DMN, and form resources.
How it works
The exporter reads records from the Zeebe log stream, keeps a fixed set of event types, converts each one into an OpenTelemetry log record, and pushes it to the configured endpoint in batches.
Three properties are worth understanding before you enable it:
- It is designed not to slow down your brokers. The exporter is fire-and-forget. Records are handed to a background thread and the broker acknowledges the log position immediately. If the queue fills or the endpoint is unreachable, records are dropped rather than back-pressuring the engine.
- Delivery is best effort. Records can be dropped if the endpoint is unreachable or a broker restarts, so the data is not guaranteed to be complete. Camunda uses the contractual signals to verify usage against your agreement, not to calculate charges: billing and overage charges are based on usage metrics. Do not rely on the exporter for audit or anything that depends on a complete record.
- It runs on the partition leader only. No additional high-availability setup is required.
Enable the exporter
Add an analytics exporter to your broker configuration. To disable it again, remove the declaration and restart the brokers.
camunda:
data:
exporters:
analytics:
class-name: io.camunda.exporter.analytics.AnalyticsExporter
args:
categories:
- contractual
- optional
These are the equivalent environment variables:
CAMUNDA_DATA_EXPORTERS_ANALYTICS_CLASSNAME=io.camunda.exporter.analytics.AnalyticsExporter
CAMUNDA_DATA_EXPORTERS_ANALYTICS_ARGS_CATEGORIES_0=contractual
CAMUNDA_DATA_EXPORTERS_ANALYTICS_ARGS_CATEGORIES_1=optional
No further setup is required. The exporter resolves your cluster ID and license key from the broker automatically.
Network requirements
The exporter makes outbound HTTPS requests to telemetry.camunda.io, the Camunda analytics endpoint. Allowlist this host in your egress firewall rules on every broker.
If the endpoint is unreachable, the exporter fails silently. No incident is raised, no error is surfaced to operators, and the brokers continue running normally. You will not be told if the exporter stops reaching the endpoint.
Authentication
The exporter authenticates using your Camunda 8 Self-Managed license key.
There is nothing extra to configure. The exporter derives everything it needs from the license key already set on the cluster, and computes the credentials itself on startup.
The raw license key is never transmitted. The exporter sends a SHA-256 fingerprint of the key in the x-camunda-fingerprint header, and uses the key as an HMAC secret to sign each batch. Camunda maps the fingerprint to your organization.
If you rotate your license key, the exporter picks up the new key the next time the broker starts.
Verify the exporter is running
When the exporter starts on a partition leader, look for the following log line:
Analytics exporter configured: endpoint=<endpoint>, clusterId=<cluster-id>, partitionId=<partition-id>, exporterDigest=<digest>, activeCategories=<categories>
activeCategories shows which categories the exporter is sending. This line confirms the exporter loaded its configuration; it does not confirm that the endpoint is reachable.
Choose what is sent
The categories option controls which signals are exported:
| Category | What it contains | Why Camunda collects it |
|---|---|---|
| contractual | Root process instance starts, decision evaluations, user task assignments, and tenant creation and deletion. | To verify usage against the metrics in your agreement. |
| optional | Process, decision, and form definition deployments and deletions; incidents raised and resolved; user task creation; and agent instance starts and completions. | To understand how the product is used, prioritize improvements, and support your deployment. |
Every signal in each category, with its attributes, is listed in what data is sent.
Both categories are active by default. Narrow the set by removing entries. For example, to send contractual signals only:
camunda:
data:
exporters:
analytics:
class-name: io.camunda.exporter.analytics.AnalyticsExporter
args:
categories:
- contractual
Explicitly setting categories: [] disables data-category telemetry entirely. Only the heartbeat and export-window signals below continue to be sent.
The camunda.telemetry.heartbeat event and the camunda.metric.export_window metric are sent whenever the exporter runs, regardless of the categories you select. Camunda uses them to detect data gaps and offline clusters.
What data is sent
Each signal is an OpenTelemetry log record identified by its event.name.
Resource attributes
Attached to every record, metric point, and heartbeat:
| Attribute | Type | Description |
|---|---|---|
camunda.cluster.id | string | Cluster identifier. |
camunda.partition.id | long | Partition ID. |
camunda.tenant.physical_id | string | Physical tenant of the broker instance that produced the signal. |
service.name | string | Always camunda-zeebe. |
Common event attributes
Set on every event record:
| Attribute | Type | Description |
|---|---|---|
event.name | string | Signal identifier. |
camunda.log.position | long | Log stream position. Used for deduplication. |
camunda.event.sequence_number | long | Monotonic per-partition counter, used for ordering and gap detection. |
Contractual signals
camunda.process.instance.activated: a root process instance was activated.
| Attribute | Type | Description |
|---|---|---|
camunda.process.id | string | BPMN process ID. |
camunda.process.version | long | Deployed process version. |
camunda.process.definition_key | long | Process definition key. |
camunda.process.instance_key | long | Process instance key. |
camunda.process.root_instance_key | long | Root process instance key. |
camunda.tenant.id | string | Tenant ID. |
Taken from activation of the root process element, the single point every process instance passes through however it was started: client API, message, timer, signal, or conditional start event. Instances started by a call activity are excluded, so this counts root instances only.
camunda.user_task.assigned: a user task was assigned to a user. This signal carries no assignee-derived data; it only counts assignment events.
| Attribute | Type | Description |
|---|---|---|
camunda.user_task.key | long | User task key. |
camunda.process.instance_key | long | Process instance key. |
camunda.tenant.id | string | Tenant ID. |
Assignments with an empty assignee produce no event.
camunda.tenant.created and camunda.tenant.deleted
| Attribute | Type | Description |
|---|---|---|
camunda.tenant.id | string | Tenant ID. |
The tenant name, description, and associated entity are not exported.
camunda.decision.instance.evaluated (counter metric): pre-aggregated count of evaluated decision instances, dimensioned by camunda.tenant.id.
Counts evaluation records rather than the decisions inside them: a decision requiring sub-decisions counts once, and failed evaluations are not counted. This matches the counting rule for the decision instance usage metric.
Optional signals
camunda.user_task.created: a user task was created.
| Attribute | Type | Description |
|---|---|---|
camunda.process.id | string | BPMN process ID. |
camunda.process.definition_key | long | Process definition key. |
camunda.process.instance_key | long | Process instance key. |
camunda.element.id | string | BPMN element ID of the user task. |
camunda.tenant.id | string | Tenant ID. |
camunda.process.incident.created and camunda.process.incident.resolved
| Attribute | Type | Description |
|---|---|---|
camunda.incident.key | long | Incident key. |
camunda.process.id | string | BPMN process ID. |
camunda.process.definition_key | long | Process definition key. |
camunda.process.instance_key | long | Process instance key. |
camunda.tenant.id | string | Tenant ID. |
The incident error message is not exported, because it can quote expressions and variable values.
camunda.process.definition.created and camunda.process.definition.deleted
| Attribute | Type | Description |
|---|---|---|
camunda.process.id | string | BPMN process ID. |
camunda.process.version | long | Process version. |
camunda.process.definition_key | long | Process definition key. |
camunda.tenant.id | string | Tenant ID. |
The BPMN resource, resource name, and version tag are not exported.
camunda.decision.definition.created and camunda.decision.definition.deleted
| Attribute | Type | Description |
|---|---|---|
camunda.decision.id | string | Decision ID from the DMN. |
camunda.decision.key | long | Decision key. |
camunda.decision.version | long | Decision version. |
camunda.tenant.id | string | Tenant ID. |
The decision name and version tag are not exported.
camunda.form.definition.created and camunda.form.definition.deleted
| Attribute | Type | Description |
|---|---|---|
camunda.form.id | string | Form ID. |
camunda.form.key | long | Form key. |
camunda.form.version | long | Form version. |
camunda.tenant.id | string | Tenant ID. |
The form resource, resource name, and version tag are not exported.
camunda.agent.instance.created and camunda.agent.instance.completed
| Attribute | Type | Description |
|---|---|---|
camunda.agent.instance_key | long | Agent instance key. |
camunda.agent.definition_key | long | Agent definition key. |
camunda.agent.status | string | Agent instance status, for example INITIALIZING or COMPLETED. |
camunda.process.id | string | BPMN process ID. |
camunda.process.definition_key | long | Process definition key. |
camunda.process.instance_key | long | Process instance key. |
camunda.process.root_instance_key | long | Root process instance key. |
camunda.tenant.id | string | Tenant ID. |
The agent definition (model, provider, system prompt), its tools, its token counts and other collected metrics, and its configured limits are not exported.
Always-on signals
Together with the resource attributes attached to every record, these signals make up the environment data described on the data collection page.
camunda.telemetry.heartbeat: periodic liveness signal from the partition leader.
| Attribute | Type | Description |
|---|---|---|
event.name | string | Always camunda.telemetry.heartbeat. |
camunda.telemetry.heartbeat.broker_version | string | Broker version. |
camunda.telemetry.heartbeat.exporter_version | string | Analytics Exporter version. |
camunda.metric.export_window (gauge metric): accompanies every metrics export, carrying the window total and log position range. Camunda uses it for deduplication and gap detection.
What is never sent
Regardless of configuration, the exporter never sends:
- Process variables, job variables, or any payload
- Message contents or correlation keys
- Incident error messages
- BPMN, DMN, and form resources, resource names, or version tags
- Tenant names and descriptions
- Agent system prompts, tool definitions, model configuration, or token counts
- Raw user names, email addresses, assignee data, or your license key
Configuration reference
All options live under args. The defaults suit typical Self-Managed deployments and rarely need changing.
| Option | Type | Description | Default |
|---|---|---|---|
endpoint | string | OTLP/HTTP base URL for the analytics endpoint. The path /v1/logs is appended automatically. | https://telemetry.camunda.io |
categories | list | Signal categories to export: contractual, optional. Omitted enables both (the default); an explicit empty list ([]) disables both. | [contractual, optional] |
push-interval | duration | Maximum time between batch pushes, as an ISO 8601 duration. | PT5M |
heartbeat-interval | duration | Interval between heartbeat events carrying the broker and exporter versions. | PT10M |
max-queue-size | int | Maximum number of records buffered in memory before new records are dropped. | 2048 |
max-batch-size | int | Maximum number of records per OTLP request. Must not exceed max-queue-size. | 512 |
sampling-rate | double | Sampling rate applied to all signals, including contractual signals, between 0.0 and 1.0. | 1.0 |
http-connect-timeout | duration | Maximum time to establish a connection to the endpoint. | PT3S |
http-request-timeout | duration | Maximum time for a single export request to complete. | PT3S |
http-max-retry-attempts | int | Maximum number of attempts per export request, including the first attempt. | 3 |
A sampling-rate below 1.0 also samples contractual signals, so they undercount your actual usage. Keep the default of 1.0 unless Camunda asks you to change it.
Failure behavior
The exporter is designed so that failures do not affect broker throughput. Records may be dropped without notice. Records are lost when:
- The in-memory queue is full, typically because the endpoint is slow or unreachable. New records are dropped without retry.
- A broker crashes or restarts. The queue is not persisted.
- The endpoint returns an error. For transient errors, the exporter makes up to
http-max-retry-attemptsattempts per request, then drops the batch. It does not buffer to disk.
Because every record carries camunda.cluster.id, camunda.partition.id, and camunda.log.position, Camunda deduplicates redelivered records downstream.
Limitations
- Analytics-grade only. No exactly-once delivery, no reconciliation, no gap filling.
- Fixed signal set. Individual signals cannot be toggled; only whole categories.
- No feedback on failure. A misconfigured endpoint produces no operator-visible error.