Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Application Development

This section covers developing applications against Apache Cassandra, including CQL syntax, data modeling principles, and driver configuration.


A common misconception is that Cassandra is "eventually consistent" and therefore unsuitable for applications requiring strong consistency guarantees. In reality, Cassandra provides tunable consistency—developers control the consistency level on a per-query basis, ranging from eventual consistency to full linearizable consistency.

Consistency LevelGuaranteeUse Case
ONEAcknowledged by one replicaMaximum availability, eventual consistency
QUORUMAcknowledged by majority of replicasStrong consistency with good availability
LOCAL_QUORUMMajority within local datacenterStrong consistency with low latency in multi-DC
ALLAcknowledged by all replicasMaximum consistency, reduced availability
SERIAL / LOCAL_SERIALLinearizable per-partition (via Paxos)Compare-and-set operations (LWT)

Strong Consistency Heuristic

When R + W > RF (reads + writes > replication factor), strong consistency is generally achieved under normal operation. With RF=3, using QUORUM for both reads and writes satisfies this: 2 + 2 > 3. Note: this is a heuristic that assumes no concurrent failures; edge cases exist under specific failure modes.

Strong consistency (most applications):

// Consistency is set via driver, not in CQL
Statement stmt = SimpleStatement.builder("INSERT INTO users (id, name) VALUES (?, ?)")
.setConsistencyLevel(ConsistencyLevel.QUORUM)
.build();
Statement read = SimpleStatement.builder("SELECT * FROM users WHERE id = ?")
.setConsistencyLevel(ConsistencyLevel.QUORUM)
.build();

Eventual consistency (high-throughput, loss-tolerant):

// Metrics, logs, time-series where some loss is acceptable
Statement stmt = SimpleStatement.builder("INSERT INTO metrics (sensor_id, ts, value) VALUES (?, ?, ?)")
.setConsistencyLevel(ConsistencyLevel.ONE)
.build();

Linearizable consistency (compare-and-set):

-- Lightweight transaction for conditional updates
UPDATE accounts SET balance = ? WHERE id = ? IF balance = ?;

Early Cassandra documentation emphasized availability and partition tolerance (the "AP" in CAP theorem), leading many to assume consistency was sacrificed. In practice:

  • Cassandra defaults to ONE for reads and writes, which is eventually consistent
  • Developers who do not explicitly set consistency levels experience eventual consistency
  • The CAP theorem describes behavior during network partitions, not normal operation

Configure Consistency Explicitly

Driver defaults vary by driver and version (often LOCAL_ONE or ONE). Production applications should explicitly set consistency levels based on data requirements rather than relying on defaults.


Cassandra drivers differ fundamentally from traditional database drivers. A connection to a relational database typically abstracts away server topology—the application connects to a single endpoint, and failover (if any) is handled transparently by the database or a proxy layer.

Cassandra drivers expose the distributed nature of the cluster directly to the application. This design provides significant advantages—applications can achieve lower latency, better load distribution, and precise control over consistency—but it places responsibility on the developer to configure failure handling correctly.

AspectTraditional DatabaseCassandra Driver
Topology awarenessHidden behind single endpointDriver maintains live map of all nodes
Node failuresHandled by database/proxyApplication must configure retry and reconnection behavior
Request routingDatabase decidesApplication configures load balancing policy
Consistency trade-offsFixed by databaseApplication chooses per-query consistency level

The driver provides configurable policies that determine application behavior during normal operation and failure scenarios:

PolicyControls
Load BalancingWhich nodes receive requests; datacenter affinity; rack awareness
RetryWhether to retry failed requests; which errors are retryable; how many attempts
ReconnectionHow quickly to attempt reconnection after node failure; backoff strategy
Speculative ExecutionWhether to send redundant requests to reduce tail latency

Default policies may not match production requirements. A retry policy that works for idempotent reads may cause duplicate writes. A load balancing policy optimized for single-datacenter deployments will perform poorly across regions. Speculative execution improves latency but increases cluster load.

Incorrectly configured driver policies can cause:

  • Cascading failures — Aggressive retry policies can overwhelm an already struggling node
  • Uneven load — Poor load balancing concentrates requests on subset of nodes
  • Data inconsistency — Retrying non-idempotent operations may duplicate writes
  • Unnecessary latency — Failing over to remote datacenter when local nodes are available
  • Connection storms — Aggressive reconnection after network partition recovery

When developing applications against Cassandra:

  1. Understand the policies — Read the driver documentation for each policy type before writing production code
  2. Configure explicitly — Do not rely on defaults; configure each policy based on application requirements
  3. Test failure scenarios — Simulate node failures, network partitions, and high latency during development
  4. Monitor in production — Track driver metrics (connection pool usage, retry rates, speculative execution triggers)
  5. Consider idempotency — Design operations to be safely retryable where possible

  • AxonOps Workbench — Open-source GUI for schema management, query execution, and data exploration
  • CQLAI — Modern AI-powered CQL shell with rich terminal interface
  • CQL Reference — Cassandra Query Language syntax and semantics
  • Data Modeling — Principles for designing effective Cassandra data models
  • Drivers — Driver architecture, connection management, and policy configuration
  • Design Patterns — Battle-tested patterns for common use cases