DEV Community

Cover image for DynamoDB vs Cassandra
DynoTable
DynoTable

Posted on • Edited on • Originally published at dynotable.com

DynamoDB vs Cassandra

Amazon DynamoDB and Apache Cassandra are both distributed NoSQL databases that
partition data by key and scale horizontally, and they share a common ancestor in
Amazon's 2007 Dynamo paper. But they sit at opposite ends of the operational
spectrum: DynamoDB is a fully managed, serverless AWS service, while Cassandra is
open-source software you deploy and run yourself as a masterless peer-to-peer ring.

Is DynamoDB or Cassandra the right choice?

Both are horizontally scalable NoSQL stores that partition by key. Choose
DynamoDB if you want a fully managed, serverless database on AWS with no cluster
to operate and pay-per-use billing. Choose Cassandra if you want an open-source,
self-managed, masterless ring — running on your own hardware or across clouds — with
per-query tunable consistency and no vendor lock-in.

DynamoDB vs Cassandra at a glance

Characteristic DynamoDB Apache Cassandra
Data model Key-value and document; schemaless JSON-like items Partitioned wide-column store; rows grouped into partitions
Query language Low-level API operations plus PartiQL (a SQL-compatible query language) CQL (Cassandra Query Language), an SQL-like language
Partitioning / keys Partition (hash) key, with an optional sort key for a composite primary key Primary key = one or more partition-key columns plus zero or more clustering columns
Secondary indexes Global secondary indexes (GSI) and local secondary indexes (LSI) Local secondary indexes (2i) and storage-attached indexing (SAI); materialized views
Consistency Eventually consistent by default; strongly consistent reads available per request Tunable per operation (e.g. ONE, QUORUM, ALL) against a per-keyspace replication factor
Scaling / operations Fully managed and serverless; AWS handles storage, scaling, patching, and repair Self-managed masterless ring you deploy on commodity hardware (or a managed Cassandra-compatible service)
Multi-region Global Tables — multi-Region, active-active replication Multi-datacenter replication configured per keyspace
Pricing / ops model Pay-per-use: on-demand (per request) or provisioned capacity; no infrastructure to run Free, open-source software (Apache License 2.0); you provision, run, and pay for the infrastructure
Best fit Teams on AWS wanting zero-ops NoSQL that scales automatically Teams wanting an open-source, self-hosted, cloud-agnostic ring with per-query consistency control

When DynamoDB is the better choice

  • You want zero operational overhead. DynamoDB is fully managed and serverless — there is no cluster to size, patch, repair, or rebalance. AWS handles storage and scaling in the background.
  • You are already on AWS. It integrates natively with IAM, Lambda, and the rest of the AWS ecosystem, and Global Tables give active-active multi-Region replication without you standing up datacenters.
  • Your traffic is spiky or unpredictable. On-demand capacity bills per request, so you pay for what you use instead of provisioning and running idle nodes.
  • You want managed durability and backups. Point-in-time recovery, on-demand backups, and cross-Region replication are configuration, not infrastructure you run.

When Cassandra is the better choice

  • You need an open-source, cloud-agnostic database. Cassandra is Apache-licensed and runs anywhere — on-premises, across multiple clouds, or hybrid — with no vendor lock-in to a single provider's managed service.
  • You want fine-grained, per-operation consistency control. Its tunable consistency lets each read and write choose a level (such as ONE, QUORUM, or ALL) against the keyspace replication factor, trading latency for consistency per query.
  • You want a masterless architecture with no single point of failure. Every node is equal and can serve reads and writes, and the cluster stays available even when individual nodes or whole datacenters go offline.
  • You are willing to operate the cluster (or pay a managed provider to) in exchange for that control and portability.

What a CQL query becomes in DynamoDB

CQL looks close enough to SQL that the port feels mechanical. Here is a real
tenant-scoped event log and the query you would run against it:

CREATE TABLE app.tenant_order_events (
    tenant_id   text,
    event_time  timestamp,
    event_id    timeuuid,
    order_id    text,
    status      text,
    amount      decimal,
    PRIMARY KEY ((tenant_id), event_time, event_id)
) WITH CLUSTERING ORDER BY (event_time DESC, event_id ASC);

SELECT order_id, status, amount
FROM app.tenant_order_events
WHERE tenant_id = 'acme'
  AND event_time >= '2026-07-01 00:00:00+0000'
  AND event_time <  '2026-08-01 00:00:00+0000'
  AND status = 'failed'
LIMIT 100
ALLOW FILTERING;
Enter fullscreen mode Exit fullscreen mode

Three things in that statement land differently.

Two clustering columns, one sort key. PRIMARY KEY ((tenant_id), event_time, event_id)
sorts rows inside the partition by two columns. DynamoDB gives you exactly one sort
key, so both collapse into a single string you concatenate on write
(2026-07-14T09:12:03Z#7c9a…) and parse back on read. The
CLUSTERING ORDER BY … DESC that Cassandra fixes at table creation becomes
ScanIndexForward: false, set per request.

ALLOW FILTERING becomes silent. Cassandra rejects that statement without the
clause, and the CQL spec warns that a query using it "may thus have unpredictable
performance". DynamoDB asks for no opt-in. status moves into a FilterExpression
and the request looks like any other:

{
  "TableName": "tenant_order_events",
  "KeyConditionExpression": "tenant_id = :t AND event_sk BETWEEN :from AND :to",
  "FilterExpression": "#s = :status",
  "ScanIndexForward": false,
  "Limit": 100,
  "ExpressionAttributeNames": {"#s": "status"},
  "ExpressionAttributeValues": {
    ":t": {"S": "acme"},
    ":from": {"S": "2026-07-01T00:00:00Z"},
    ":to": {"S": "2026-08-01T00:00:00Z"},
    ":status": {"S": "failed"}
  }
}
Enter fullscreen mode Exit fullscreen mode

The filter is applied after the Query finishes, so the request consumes the same
read capacity whether it is present or not, and Limit caps items evaluated, not
items matched. CQL's LIMIT 100 returns 100 rows. This returns however many of the
first 100 items happened to be failures. The gap between ScannedCount and Count
in the response is your only signal that you read 100 items to keep three.

Per-query consistency becomes one boolean. Cassandra sets a level per operation:
LOCAL_QUORUM for a read you care about, ONE for a cheap one, sized against the
keyspace replication factor so that W + R > RF. DynamoDB has ConsistentRead: true
or the eventually consistent default, and it applies to tables and local secondary
indexes only. Every read from a global secondary index is eventually consistent, with
no override.

Those last two interact badly. The obvious fix for the filter is a GSI on status,
and taking it means that read can never be strongly consistent again. In Cassandra
you would raise the consistency level on that one query; here there is no level to
raise.

So the work that moves into your application is: composing and parsing the sort key,
paging on LastEvaluatedKey until you have collected 100 matches, and choosing
between paying to filter and reading an index you cannot read strongly.

Aggregates move too. CQL computes COUNT, MIN, MAX, SUM and AVG server-side
over the rows a query returns, and groups by primary-key columns:

SELECT COUNT(*) FROM app.tenant_order_events WHERE tenant_id = 'acme';
Enter fullscreen mode Exit fullscreen mode

That count is cheap in Cassandra because it stays inside one partition. DynamoDB's
Select: "COUNT" gives you the same number and bills the same read units as fetching
every item, since it has to read each one to increment the counter. PartiQL adds
nothing here either: its SELECT has no aggregate functions and no GROUP BY.

DynoTable's SQL Workbench is where that shape lands instead. CQL would reject this
rollup, because GROUP BY accepts only primary-key columns and status is not one.
Here it is a single statement:

SELECT status, COUNT(*) AS events, SUM(amount) AS total
FROM tenant_order_events
WHERE tenant_id = 'acme'
GROUP BY status
Enter fullscreen mode Exit fullscreen mode

It compiles to DynamoDB's native Query and Scan, planned against your real keys
and indexes, and does the grouping and the sums on the client. It supports GROUP BY
on any attribute plus COUNT and SUM, which PartiQL does not have. It adds no
server-side aggregate to DynamoDB, because nothing can; it removes the paging and
tallying loop you would otherwise write.

Working with DynamoDB

Once you have chosen DynamoDB, DynoTable is a desktop client for working
with your tables directly. It reads your standard AWS credential chain, so it connects
to the same regions and tables you already use — your data stays in DynamoDB, and there
is nothing to migrate.

Where a plain visual client only browses and scans, DynoTable adds a SQL Workbench that
expresses relational-shaped queries — JOINs, GROUP BY, and aggregates — while staying
within DynamoDB's access-pattern rules, and an AI agent that runs on your own AWS
Bedrock credentials. If you are hand-writing key conditions, filters, and update
expressions, the free
DynamoDB Expression Builder generates the correct
syntax for the SDK, CLI, and PartiQL without installing anything.

DynoTable is a closed-source commercial app; this page describes what it does, not how
it is built.

FAQ

Is DynamoDB based on Cassandra?
No. Neither is built on the other. Both trace back to Amazon's 2007 Dynamo paper —
Cassandra was created at Facebook by a co-author of that paper and also draws on Google's
Bigtable — but DynamoDB is a separate, fully managed AWS service and Cassandra is an
independent open-source project. They share design lineage, not code.

Cassandra vs DynamoDB for scale and cost?
Both scale horizontally to very large workloads. The real difference is the operating
model: DynamoDB's cost is pay-per-use (on-demand requests or provisioned capacity) with
no servers to run, so it shifts spend from operations to usage. Cassandra's software is
free, but you pay for and operate the infrastructure — nodes, storage, and the team to
run the ring — so its total cost depends heavily on scale and how it is managed.

Does Cassandra support SQL like DynamoDB?
Both offer SQL-like access rather than full relational SQL. Cassandra uses CQL, an
SQL-like language, and DynamoDB offers PartiQL, a SQL-compatible query language, alongside
its low-level API. Neither provides cross-partition JOINs natively; both are designed
around single-partition access patterns.

Related

References

Last verified 2026-07-13. Apache Cassandra is a trademark of the Apache Software
Foundation; referenced here for identification only.

Top comments (0)