Container initialization
Choose between lazy (default) and eager container creation for predictable startup.
This page explains how and when Cosmos DB containers are created when using the repository pattern.
Lazy initialization (default)
By default, containers are created lazily — on the first repository operation that touches them.
// Container doesn't exist yetvar repository = serviceProvider.GetRequiredService<IRepository<Product>>();
// Container is created here on first accessvar product = await repository.CreateAsync(new Product { Name = "Widget" });How lazy initialization works
- Application starts — no containers are created.
- First repository operation (
CreateAsync,GetAsync, …) is called. - The internal
ICosmosContainerServicechecks whether the container exists. - If
IsAutoResourceCreationIfNotExistsEnabledistrue, it creates the database/container. - The repository operation completes.
Configuration
Lazy creation is gated by IsAutoResourceCreationIfNotExistsEnabled:
builder.Services.AddCosmosRepository(options =>{ options.IsAutoResourceCreationIfNotExistsEnabled = true; // Default});| Value | Behavior |
|---|---|
true (default) | Containers are created on demand; database is created if missing. Convenient for dev. |
false | Containers must already exist. Recommended for production when infrastructure is managed externally (Bicep, Terraform, ARM, …). |
Pros and cons
Pros: simple, no extra code, only creates what you use.
Cons: higher first-request latency, health checks may flap during startup, configuration errors only surface at runtime, can break Kubernetes readiness probes.
Eager initialization
Eager initialization creates containers at application startup before any requests are handled.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosRepository(options =>{ options.ContainerBuilder.Configure<Product>(c => c .WithContainer("products") .WithPartitionKey("/category"));});
var app = builder.Build();
await app.Services.EagerlyInitializeCosmosContainersAsync();
app.Run();How eager initialization works
EagerlyInitializeCosmosContainersAsync():
- Returns immediately if
IsAutoResourceCreationIfNotExistsEnabledisfalse. - Discovers item types in priority order:
- Types explicitly configured via
ContainerBuilder.Configure<TItem>(). - Types from the assemblies you pass in.
- Types from all loaded assemblies (fallback).
- Types explicitly configured via
- Calls
ICosmosContainerService.GetContainerAsync()for each type. - Awaits all containers before returning.
- Logs the initialization process.
When to use eager initialization
✅ Use when:
- Your app uses health checks (Kubernetes, load balancers, …).
- You want consistent latency on every request, including the first.
- You want to fail fast at startup if Cosmos DB is misconfigured.
- You’re running in containers with readiness probes.
❌ Don’t use when:
IsAutoResourceCreationIfNotExistsEnabledisfalse(it’s a no-op).- You have many containers and want quick startup.
- Containers are created externally (Infrastructure as Code).
Explicit type discovery
If item types live in assemblies that aren’t loaded at startup, pass them explicitly:
await app.Services.EagerlyInitializeCosmosContainersAsync( typeof(Product).Assembly, typeof(Order).Assembly);If you used ContainerBuilder.Configure<T>() they are discovered automatically:
builder.Services.AddCosmosRepository(options =>{ options.ContainerBuilder.Configure<Product>(c => c.WithContainer("products"));});
await app.Services.EagerlyInitializeCosmosContainersAsync(); // Discovers ProductComparison
| Aspect | Lazy | Eager |
|---|---|---|
| When containers are created | First repository access | App startup |
| First request latency | Higher (creation + request) | Normal |
| Startup time | Faster | Slower (waits for containers) |
| Configuration | Default | Requires explicit call |
| Health checks | May fail during init | Pass after startup completes |
| Fail-fast | Errors at runtime | Errors at startup |
| Best for | Dev / simple apps | Production with health checks |
Common scenarios
Development
builder.Services.AddCosmosRepository(options =>{ options.CosmosConnectionString = "AccountEndpoint=https://localhost:8081/..."; options.IsAutoResourceCreationIfNotExistsEnabled = true;});Production with health checks
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosRepository(options =>{ options.IsAutoResourceCreationIfNotExistsEnabled = true; options.ContainerBuilder.Configure<Product>(c => c.WithContainer("products")); options.ContainerBuilder.Configure<Order>(c => c.WithContainer("orders"));});
builder.Services.AddHealthChecks().AddCosmosRepository();
var app = builder.Build();
await app.Services.EagerlyInitializeCosmosContainersAsync();
app.MapHealthChecks("/health");app.Run();Production with Infrastructure as Code
builder.Services.AddCosmosRepository(options =>{ // Containers are created externally (Bicep / Terraform / ARM) options.IsAutoResourceCreationIfNotExistsEnabled = false;});
// No eager initialization neededLogging
Both modes emit detailed logs:
// Lazy[Debug] Container 'products' does not exist. Creating...[Information] Successfully created container 'products'
// Eager[Information] Eagerly initializing 2 Cosmos DB container(s) for 2 item type(s)[Debug] Successfully initialized container 'products' for item type 'Product'[Debug] Successfully initialized container 'orders' for item type 'Order'[Information] Successfully completed eager initialization of 2 Cosmos DB container(s)Set the log level to Debug for the most detail:
{ "Logging": { "LogLevel": { "Microsoft.Azure.CosmosRepository": "Debug" } }}Best practices
- Use eager initialization with health checks to avoid startup flapping.
- Configure types explicitly via
ContainerBuilder.Configure<T>()for automatic discovery. - Set
IsAutoResourceCreationIfNotExistsEnabled = falsewhen infrastructure is externally managed. - Watch the startup logs — verify containers are created the way you expect.
- Use generous startup probe timeouts when using eager initialization with many containers.