﻿---
title: Set up Azure Cosmos DB instrumentation
description: How to enable Elastic APM .NET Agent instrumentation of Azure Cosmos DB operations to capture them as APM spans.
url: https://www.elastic.co/elastic/docs-builder/docs/4047/reference/apm/agents/dotnet/setup-azure-cosmosdb
products:
  - APM .NET Agent
  - APM Agent
applies_to:
  - Serverless Observability projects: Generally available
  - Elastic Stack: Generally available
  - Application Performance Monitoring Agent for .NET: Generally available
---

# Set up Azure Cosmos DB instrumentation
## Supported versions


| Package                                    | Supported versions |
|--------------------------------------------|--------------------|
| `Microsoft.Azure.Cosmos`                   | ≥3.0.0 <4.0.0      |
| `Microsoft.Azure.DocumentDB.Core` (legacy) | ≥2.4.1 <3.0.0      |
| `Microsoft.Azure.DocumentDB` (legacy)      | ≥2.4.1 <3.0.0      |

For the full compatibility matrix including supported installation methods, refer to [Data access technologies](/elastic/docs-builder/docs/4047/reference/apm/agents/dotnet/supported-technologies#supported-data-access-technologies).
<note>
  `Microsoft.Azure.DocumentDB.Core` and `Microsoft.Azure.DocumentDB` are deprecated. The recommended replacement is `Microsoft.Azure.Cosmos`.
</note>


## Quick start

This page assumes the core agent is already set up. If not, see [Set up the APM .NET Agent](https://www.elastic.co/elastic/docs-builder/docs/4047/reference/apm/agents/dotnet/set-up-apm-net-agent) first.
Add the [`Elastic.Apm.Azure.CosmosDb`](https://www.nuget.org/packages/Elastic.Apm.Azure.CosmosDb) NuGet package to your project:
```sh
dotnet add package Elastic.Apm.Azure.CosmosDb
```

Subscribe to diagnostic events once at application startup:
```csharp
using Elastic.Apm;
using Elastic.Apm.Azure.CosmosDb;

Agent.Subscribe(new AzureCosmosDbDiagnosticsSubscriber());
```

HTTP-based diagnostic events from `Microsoft.Azure.Cosmos`, `Microsoft.Azure.DocumentDb`, and `Microsoft.Azure.DocumentDb.Core` are captured as DB spans. This covers **Gateway mode only**. Because `CosmosClient` defaults to **Direct mode** (TCP), most applications also need the additional setup described in [Direct mode (TCP)](#_direct_mode_cosmosdb) below to capture CRUD and query spans.

## Connection modes and instrumentation coverage

`CosmosClient` supports two connection modes, which affect how operations are instrumented.

### Direct mode (TCP)

`CosmosClient` defaults to **Direct mode**, which routes data-plane requests over the RNTBD TCP protocol, bypassing HTTP entirely. The `Elastic.Apm.Azure.CosmosDb` package does not observe these requests, so **CRUD and query operations produce no spans by default in Direct mode**.
To capture Direct-mode operations, enable [built-in OpenTelemetry support in the Cosmos SDK](https://learn.microsoft.com/en-us/azure/cosmos-db/sdk-observability) (requires `Microsoft.Azure.Cosmos` ≥ 3.36.0). The APM agent's [OpenTelemetry bridge](https://www.elastic.co/elastic/docs-builder/docs/4047/reference/apm/agents/dotnet/opentelemetry-bridge) (enabled by default) captures the resulting `Azure.Cosmos.Operation` activities as `db/cosmosdb` spans.
Set the following **once at application startup, before creating any `CosmosClient` instance**:
```csharp
AppContext.SetSwitch("Azure.Experimental.EnableActivitySource", true);
```

You must also explicitly enable distributed tracing on the client — it is **turned off by default** in stable SDK releases:
```csharp
var client = new CosmosClient(connectionString, new CosmosClientOptions
{
    CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions
    {
        DisableDistributedTracing = false
    }
});
```

<note>
  `Azure.Experimental.EnableActivitySource` is a process-wide AppContext switch. The "Experimental" label refers to the switch name itself, not to the underlying functionality. Microsoft might rename or enable it by default in a future SDK release. See [Azure Cosmos DB SDK observability](https://learn.microsoft.com/en-us/azure/cosmos-db/sdk-observability) for the current status.
</note>


### Gateway mode (HTTP)

When `CosmosClient` is configured with `ConnectionMode.Gateway` (or when using the Cosmos emulator), data-plane requests travel over HTTPS. The `Elastic.Apm.Azure.CosmosDb` package intercepts these HTTP requests and captures them as `db/cosmosdb` spans with operation names such as `Cosmos DB Create/query document`.
No additional configuration is required beyond the preceding quick-start steps.
<warning>
  **Gateway mode with the SDK activity source and this package produces duplicate spans.** This applies only when `Elastic.Apm.Azure.CosmosDb` is referenced, `Azure.Experimental.EnableActivitySource` is set (see [Direct mode](#_direct_mode_cosmosdb)), *and* `ConnectionMode.Gateway` is in use. Each operation generates one OTel bridge span (from the Cosmos SDK, named by the SDK, for example `create_item`) plus one or more HTTP-derived spans (from this package, named `Cosmos DB <operation>`). Paged queries and retried operations each produce a separate HTTP request, adding further HTTP spans. If the total number of spans in a transaction exceeds `transaction_max_spans`, later spans are dropped entirely. Because `Azure.Experimental.EnableActivitySource` is a process-wide switch, applications that mix Direct-mode and Gateway-mode clients cannot avoid Gateway duplicates while enabling Direct-mode tracing. If the duplicates are undesirable, do not set the switch when using Gateway mode. The switch is only required for Direct mode.
</warning>