All articles
Cloud Architecture6 min read2024-03-20

Why We Chose Cosmos DB for Freight Booking State Management

NoSQL vs SQL for freight booking workflows — the tradeoffs we evaluated and how Cosmos DB's partition strategy solved our scale problem.

Cosmos DBAzureNoSQLFreight Tech

The Problem with Relational Models for Bookings

Freight bookings are inherently document-shaped. A single booking record contains:

  • Multi-leg route details (origin → tranship → destination)
  • Per-leg rate breakdowns across 8–15 charge types
  • Carrier-specific contract terms
  • Real-time status events from multiple parties

Normalising this into SQL tables meant 12+ JOINs for a single booking summary — unacceptable at scale.

Why Cosmos DB

Azure Cosmos DB with the SQL API gave us:

  • Document storage matching our booking object model 1:1
  • <10ms reads at P99 globally
  • Partition key on tenantId + routeHash for even distribution
  • Change Feed to stream booking state changes downstream

Partition Strategy

Partition key: /partitionKey = "{tenantId}_{originPort}_{destPort}"

This ensured all queries for a tenant's lane were co-located, avoiding cross-partition scatter-gather.

TTL for Rate Expiry

Carrier rates expire every 30–90 days. We used Cosmos DB TTL to auto-purge stale rate documents:

{
  "id": "rate_CMACGM_PKKAR_NLRTM_20240301",
  "carrier": "CMA-CGM",
  "originPort": "PKKAR",
  "destPort": "NLRTM",
  "totalRateUSD": 1450,
  "_ts": 1709251200,
  "ttl": 7776000
}

Results

  • 40% faster booking retrieval vs previous SQL implementation
  • Simplified schema evolution — no migration scripts for carrier-specific fields
  • Change Feed powering real-time notification pipeline