Evaluate telemetry, feeds, regional writes, and ad-hoc workloads against partition-local access, maintenance cost, invariants, and measurable failure/latency requirements.
Use Cases: Telemetry, Time-Ordered Events, High-Write Services, and Multi-Region Workloads
Model AtlasMart documents with nested objects, arrays, dynamic fields, validation, and compatibility-safe schema evolution while distinguishing missing from explicit null.
Learning outcomes
Chapter 12 ends by deciding where the wide-column model is a good fit. AtlasMart has telemetry, activity feeds, regional service state, and a tempting list of ad-hoc business questions. The model excels when the application can name a partition key, read a bounded ordered slice, tolerate deliberate denormalization, and operate repair/compaction at the write rate. It becomes awkward when requirements demand unpredictable joins, global secondary predicates, or large cross-partition atomic transactions.
Map telemetry and time-ordered activity to bounded partition/clustering layouts.
Reason about regional high-write services without confusing locality with strong consistency.
Recognize scatter-gather and transaction requirements that break the model.
Choose a derived query table only when the query is stable enough to justify write fan-out.
1. Workloads that align naturally
| Workload | Possible partition/clustering design | Why it fits | Watch |
|---|---|---|---|
| device telemetry | (tenant, device, day) / event_time DESC | append-heavy, predictable device/time query | celebrity device, TTL/compaction |
| activity feed | (tenant, user, month) / event_time DESC | bounded newest-first history | fan-out strategy, late events |
| regional service state | (region, account_bucket) / entity_id | write locality and explicit regional routing | cross-region invariants/failover |
| immutable audit/event projection | (entity, period) / sequence DESC | ordered append and bounded retrieval | retention, repair, source-of-truth contract |
“Multi-region” is not itself a reason to choose wide-column storage. Replication topology, consistency level, conflict behavior, recovery objectives, and data residency still determine whether the architecture is correct. The table design only establishes where data is partitioned and how it is queried.
2. Workloads that push against the grain
Ad-hoc joins across customers, products, merchants, and time; arbitrary filtering on many non-key fields; large cross-partition transactions; and rapidly changing query patterns are warnings. You can precompute more tables, add indexes, or introduce a search/analytical system, but each extra capability changes cost and semantics. At some point the right answer is a relational, search, graph, or analytical database rather than an ever-growing set of wide-column projections.
from dataclasses import dataclass
@dataclass(frozen=True)
class Workload:
name: str
writes_per_sec: int
query: str
partitions_per_query: int
ordered: bool
cross_partition_tx: bool
unpredictable_queries: bool
workloads = [
Workload("telemetry", 50000, "device + day -> latest samples", 1, True, False, False),
Workload("activity_feed", 12000, "user + month -> newest events", 1, True, False, False),
Workload("regional_status", 8000, "region + account bucket -> current states", 1, False, False, False),
Workload("global_ad_hoc", 500, "arbitrary predicates + joins over all merchants", 720, False, True, True),
]
def fit(w):
reasons=[]
if w.partitions_per_query > 20:
reasons.append("scatter-gather")
if w.cross_partition_tx:
reasons.append("large cross-partition transaction")
if w.unpredictable_queries:
reasons.append("unpredictable/ad-hoc access")
return (not reasons, reasons)
for w in workloads:
ok, reasons = fit(w)
print(w.name, "fit=" + str(ok), "reasons=" + (", ".join(reasons) if reasons else "partition-local predictable access"))
# Derived-table alternative for one stable global query.
query = "failed payments by merchant/day"
source_write = 1
derived_write = 1
print("stable alternate query:", query)
print("write fan-out for source + derived table:", source_write + derived_write)
print("query partitions touched after derived design:", 1)
The first three workloads are predictable partition-local access patterns. The global ad-hoc query is deliberately marked a poor fit because it touches hundreds of partitions and asks for a cross-partition transaction/unpredictable predicates. A stable new question—failed payments by merchant/day—can justify one additional derived table, reducing that query to one partition at the cost of a second write/projection.
3. A production decision matrix
| Question | Favorable answer | Warning answer |
|---|---|---|
| Can the service derive a partition key from every critical request? | Yes, usually one/few bounded keys | No; discovery requires global scan |
| Are rows naturally ordered within that key? | Yes, clustering matches range/time slices | No stable ordering/query shape |
| Can partitions be bounded under p99 skew? | Yes, with documented buckets | One entity can grow without bound |
| Can duplication be repaired? | Source + idempotent replay/reconciliation exist | Multiple copies can mutate independently |
| Can operations sustain maintenance? | Compaction/repair/headroom included in capacity plan | Only foreground QPS was sized |
| Do invariants cross many partitions? | Rare/compensatable or owned elsewhere | Frequent atomic multi-partition invariants |
4. Wrong approach: choose a wide-column database because “writes are fast”
Write throughput is produced by a particular storage engine, hardware, replication/durability policy, partition distribution, compaction state, client concurrency, and dataset. A benchmark with uniform keys, no deletes, empty caches, relaxed durability, or no repair backlog may have little predictive value. The safe evaluation replays AtlasMart-like skew, TTL/deletes, realistic value sizes, required consistency, failure-domain loss, compaction, repair, and tail-latency SLOs.
They prove data-model mechanics and failure histories in deterministic Python. They do not measure Cassandra throughput, SSD endurance, JVM garbage collection, network tails, compaction throughput, or cloud cost. Those require a pinned product/version/topology and a separately documented benchmark.
5. Production judgment and bridge to Chapter 13
Choose wide-column storage when stable partition-local queries, very high write rates, bounded time/event histories, and deliberate denormalization dominate. Reject or supplement it when the product requires arbitrary joins/global exploration, unpredictable secondary predicates, or broad atomic transactions. Record the partition key, clustering order, bucket math, table fan-out, consistency level, replication topology, repair interval, compaction strategy, TTL/deletion policy, backup/restore path, tenant isolation, SLOs, and migration rollback in the decision notebook.
Chapter 13 changes data shape again. Graph databases make relationships themselves first-class and optimize neighborhood/path traversal rather than partition-local time slices. The same discipline still applies: start from the query and invariant, then select the structure whose mechanics match it.
Check your understanding
- Name two workloads that naturally fit a wide-column model.
- Why is multi-region deployment not enough to prove fit?
- What makes the global ad-hoc workload a poor fit in the lab?
- When is another denormalized table justified?
- What must a real benchmark include that the Python lab omits?
Review the answers
1. Examples include device telemetry and time-ordered activity feeds where the partition key and bounded clustering slice are known.
2. Replication, consistency, conflicts, recovery, residency, and invariants remain independent design requirements.
3. It requires scatter-gather across hundreds of partitions plus unpredictable predicates and a broad transaction boundary.
4. When the alternate query is stable and valuable enough to justify extra writes, storage, lag monitoring, and repair.
5. Pinned product/version/topology, realistic data/skew, durability/consistency, compaction/repair state, failure injection, device/network behavior, and tail-latency measurements.
Authoritative references
- Chang et al. — Bigtable: A Distributed Storage System for Structured Data (OSDI 2006) — primary research for the wide-column lineage, ordered row keys, column families, and sparse structured data.
- Apache Cassandra 5.0 — Data definition — current implementation reference for partition keys, clustering columns, composite primary keys, and clustering order.
- Apache Cassandra — Logical data modeling — query-first table design and primary-key reasoning.
- Apache Cassandra 5.0 — Tombstones — deletion markers, grace/reconciliation, repair interaction, and resurrection risk.
- Apache Cassandra 5.0 — Compaction overview — immutable SSTables, compaction, TTL/deletes, and read/space effects.
- Apache Cassandra releases — Cassandra 5.0.9 is the latest GA release as of the August 2026 review.