Cosmos DB TTL and Archival Automation
On a schedule, the flow identifies documents past a business retention period in Cosmos DB, archives them to Blob/Data Lake as JSON, then removes them (or relies on TTL), keeping the operational container lean and costs down while preserving history. Automates Cosmos data lifecycle.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This flow automates Azure Cosmos DB data lifecycle (TTL + archival). On a daily schedule it finds documents whose business timestamp is older than a configurable retention window, writes a full JSON copy of each document to Azure Blob Storage, deletes the document from Cosmos, and posts a run summary to Microsoft Teams. Old documents bloat RU/storage cost and slow queries; archiving cold data to cheap blob storage before pruning keeps the operational container lean and fast while preserving a complete history for compliance and restore. Ships Off (demo) — going live requires only authorizing the three connections and setting the environment variable values.
Use Case
A team running a globally distributed or high-write Cosmos container wants cold documents moved to inexpensive storage on a retention schedule, with an auditable archive and a delete step that respects the container's partition key — fully unattended and reported to a Teams channel each run. Age is measured against a configurable business timestamp field (e.g. createdDate), not the system _ts, so retention reflects business meaning.
Flow Architecture
Daily Retention Sweep
RecurrenceRuns the lifecycle pass once a day at 02:00 UTC.
Initialize Config (x10)
Initialize variableLoads each env var into a typed variable: account, database, container, partition-key field, retention field, retention days (int), blob account, blob folder, Teams group, Teams channel.
Compose Cutoff & Query
ComposeCutoff = now minus retention days; builds the Cosmos SQL selecting documents older than the cutoff.
Query Expired Documents
Cosmos - QueryDocuments_V5Cross-partition query returning expired docs under body/value; a condition branches on whether any matched.
Archive Each Document to Blob
Blob - CreateFile_V2For each expired doc (sequential, concurrency 1) writes {id}.json with the full document to the archive folder.
Delete Each Document from Cosmos
Cosmos - DeleteDocument_V2Deletes the doc by id + raw partition key, running only after the archive step succeeds.
Post Summary to Teams
Teams - PostMessageToConversationPosts an archived-and-removed count, or a nothing-to-archive message so every run is visible.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_CosmosAccountName | String | REPLACE_WITH_COSMOS_ACCOUNT | Cosmos DB account (per-action path param). |
| flowlibs_CosmosDatabaseId | String | REPLACE_WITH_DATABASE_ID | Cosmos database id. |
| flowlibs_CosmosContainerId | String | REPLACE_WITH_CONTAINER_ID | Container/collection id to query and prune. |
| flowlibs_CosmosPartitionKeyField | String | partitionKey | Document field used as partition key (required to delete). |
| flowlibs_RetentionTimestampField | String | createdDate | Document field holding the business timestamp (ISO-8601). |
| flowlibs_CosmosRetentionDays | String | 90 | Docs older than this many days are archived + removed (parsed with int()). |
| flowlibs_ArchiveBlobAccount | String | REPLACE_WITH_STORAGE_ACCOUNT | Azure Blob Storage account (dataset) receiving archives. |
| flowlibs_ArchiveBlobFolder | String | /cosmos-archive | Blob folder path for archived JSON. |
| flowlibs_TeamsGroupId | String | <your-team-id> |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure Cosmos DB | shared_documentdb | QueryDocuments_V5 DeleteDocument_V2 |
| Azure Blob Storage | shared_azureblob | CreateFile_V2 |
| Microsoft Teams | shared_teams | PostMessageToConversation |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- TTL combo
- Set the Cosmos container's native TTL instead of (or alongside) the explicit delete; the flow still produces the blob archive and TTL prunes automatically.
- Restore / rehydrate
- Build a companion flow that reads a {id}.json from the archive folder and re-creates the document with Cosmos CreateDocument_V3.
- Partitioned archive
- Extend flowlibs_ArchiveBlobFolder or the blob name to write a folder per partition key or per date for easier lookup.
- Retention granularity
- Point flowlibs_RetentionTimestampField at any ISO-8601 field; change flowlibs_CosmosRetentionDays to tune the window without editing logic.
- Throughput
- For very large sweeps, raise the loop concurrency (watch Cosmos RU/429s) or page the query with continuationToken.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Retention cutoff
Computes the cutoff timestamp from the configurable retention days.
EXPR.02Cosmos query
Selects documents whose business timestamp is older than the cutoff.
EXPR.03Raw partition key (delete header)
Builds the JSON-array partition-key header required by DeleteDocument_V2.
EXPR.04Archive blob name
Names each archived document {id}.json.
EXPR.05Summary count
Counts how many documents were processed this run.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.