Back to Blog
3 min read

Azure Cosmos DB Serverless: Pay-Per-Request NoSQL

Cosmos DB Serverless eliminates capacity planning. Pay only for consumed RUs—perfect for dev/test, sporadic workloads, and getting started.

Serverless vs Provisioned

AspectServerlessProvisioned
BillingPer request (RU)Per hour (RU/s)
Min cost$0 (when idle)~$24/month
Max throughput5,000 RU/s burstUnlimited
Multi-regionNoYes
Availability SLA99.9%99.99%
Best forDev/test, variable loadsProduction, steady loads

Creating Serverless Account

az cosmosdb create \
    --name my-cosmos-serverless \
    --resource-group myRG \
    --locations regionName=eastus \
    --capabilities EnableServerless \
    --default-consistency-level Session

Creating Database and Container

# Create database
az cosmosdb sql database create \
    --account-name my-cosmos-serverless \
    --resource-group myRG \
    --name mydb

# Create container (no throughput provisioning needed)
az cosmosdb sql container create \
    --account-name my-cosmos-serverless \
    --resource-group myRG \
    --database-name mydb \
    --name mycontainer \
    --partition-key-path /partitionKey

SDK Usage (Same as Provisioned)

using Microsoft.Azure.Cosmos;

var client = new CosmosClient(connectionString);
var container = client.GetContainer("mydb", "mycontainer");

// Create item
var item = new { id = "1", partitionKey = "pk1", name = "Test" };
await container.CreateItemAsync(item, new PartitionKey("pk1"));

// Query items
var query = new QueryDefinition("SELECT * FROM c WHERE c.partitionKey = @pk")
    .WithParameter("@pk", "pk1");

var iterator = container.GetItemQueryIterator<dynamic>(query);
while (iterator.HasMoreResults)
{
    var response = await iterator.ReadNextAsync();
    Console.WriteLine($"RU charge: {response.RequestCharge}");

    foreach (var item in response)
    {
        Console.WriteLine(item.name);
    }
}

Cost Optimization

// Track RU consumption
var response = await container.ReadItemAsync<MyItem>("id", new PartitionKey("pk"));
Console.WriteLine($"Read cost: {response.RequestCharge} RU");

var createResponse = await container.CreateItemAsync(newItem, new PartitionKey("pk"));
Console.WriteLine($"Write cost: {createResponse.RequestCharge} RU");

// Optimize queries
var query = container.GetItemQueryIterator<MyItem>(
    new QueryDefinition("SELECT c.id, c.name FROM c WHERE c.partitionKey = @pk")
        .WithParameter("@pk", "pk1"),
    requestOptions: new QueryRequestOptions
    {
        MaxItemCount = 100,
        PartitionKey = new PartitionKey("pk1")  // Avoid cross-partition
    }
);

Pricing Example

OperationRU CostPrice
Point read (1KB)1 RU$0.000000282
Point write (1KB)~5 RU$0.00000141
Query (simple)~3 RU$0.000000846
Query (complex)~50+ RUVariable

Example monthly cost:

  • 10,000 reads/day = 300K reads/month = $0.085
  • 1,000 writes/day = 30K writes/month = $0.042
  • Total: ~$0.13/month

When to Use Serverless

Good for:

  • Development and testing
  • Low-traffic applications
  • Bursty, unpredictable workloads
  • Getting started with Cosmos DB
  • Microservices with variable load

Not ideal for:

  • High-throughput production
  • Multi-region requirements
  • Sustained traffic > 5,000 RU/s
  • Applications needing 99.99% SLA

Migrating to Provisioned

# Cannot migrate in-place
# Export data, create provisioned account, import

# Using Data Migration Tool
dt.exe /s:CosmosDB /s.ConnectionString:"..." \
    /t:CosmosDB /t.ConnectionString:"..." /t.Throughput:1000

Cosmos DB Serverless: NoSQL without the commitment.

Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.