A backend engineer interviewing for a role on a payments infrastructure team once described a table she'd built with a composite partition key of (customer_id, month), then couldn't explain why a query for a single customer's transactions across six months required six separate round trips instead of one. She knew Cassandra was "distributed" and "fast," but she'd never sat down and worked through what a partition actually is or why the query pattern has to be decided before the schema, not after. That gap between using Cassandra and understanding it is exactly what most interview loops probe for. Apache Cassandra remains one of the most widely deployed wide-column stores behind large-scale systems, and the project's own documentation still opens with the same warning every candidate eventually has to internalize: model your data around your queries, not the other way around (Apache Cassandra documentation, Architecture overview).
The point prep guides tend to gloss over: most Cassandra interview questions aren't really about Cassandra syntax. CQL looks close enough to SQL that anyone can fake familiarity for five minutes. What actually separates a candidate who's run Cassandra in production from one who's read about it is whether they can reason about a partition's physical size on disk, explain what a tunable consistency level actually trades away, or say out loud why a secondary index on a high-cardinality column is close to a production incident waiting to happen. Netflix's own engineering team has published real numbers on how far a correctly modeled Cassandra cluster scales, north of a million writes per second in one widely cited benchmark, and the same post spends more time on schema design than on hardware (Netflix Technology Blog, 2011).
This page covers Cassandra interview questions across eight areas: data modeling and partition keys, tunable consistency levels, CQL query patterns and anti-patterns, the write path (memtables, commit log, SSTables), compaction strategies, cluster topology (gossip, vnodes, replication), tombstones and performance pitfalls, and operational concerns like repair and hinted handoff. Code examples are real CQL throughout.
Data modeling: partition keys, clustering columns, and query-first design
Every Cassandra loop starts here, because a candidate's data modeling instincts predict almost everything else about how they'll perform on the harder questions later.
Easy questions
12The partition key determines which node (or nodes, with replication) a row physically lives on, by hashing it through the configured partitioner to produce a token. Every row sharing the same partition key value lives together on disk, sorted by the clustering columns. Clustering columns don't affect placement at all, they only control the order rows are stored and read within a single partition.
CREATE TABLE orders_by_customer (
customer_id uuid,
order_date timestamp,
order_id uuid,
amount decimal,
PRIMARY KEY (customer_id, order_date, order_id)
);
-- customer_id is the partition key
-- order_date, order_id are clustering columns, sorted within the partitionA relational database lets you join and filter across tables at query time almost regardless of how you normalized the schema, so the query can adapt to whatever shape the data is in. Cassandra has no joins and heavily restricts ad hoc filtering, so if the schema doesn't already match the query you need, there usually isn't a fast way to get the answer at all. You end up denormalizing on purpose, often storing the same data two or three times in different tables, one per query pattern, because that's cheaper than a slow scatter-gather read at 2am.
It means writing the same logical data into multiple tables, each shaped around one specific access pattern. An orders table keyed by customer_id serves "show me this customer's orders," while a separate orders_by_status table keyed by status serves "show me all pending orders," even though both tables describe orders. In a relational system this looks wasteful. In Cassandra it's the expected trade-off: writes are cheap and horizontally scalable, so paying a small write-time cost to keep every read a single-partition lookup is usually the right call.
Replication factor is set per keyspace and decides how many copies of each row Cassandra keeps across the cluster, typically 3 in production. Consistency level is set per query and decides how many of those replicas have to respond before the coordinator returns success to the client. A replication factor of 3 with consistency level ONE means only one of the three replicas needs to acknowledge a write for it to succeed, even though three copies eventually exist.
QUORUM requires a majority of replicas, floor(RF/2) + 1, to respond. With RF=3 that's 2 out of 3. It's the common default because pairing QUORUM reads with QUORUM writes guarantees the read and write replica sets overlap by at least one node, so a read always sees the most recent successful write. It's the practical middle ground between ONE, which is fast but can return stale data, and ALL, which is strongly consistent but fails the entire operation if even one replica is unreachable.
Because that filter can't be satisfied by looking up a specific partition, it would require scanning every partition in the table (or across a lot of them) and discarding rows that don't match, which is exactly the kind of unbounded, unpredictable-latency operation Cassandra is designed to prevent by default. ALLOW FILTERING lets the query run anyway, but it's a signal to think hard about whether the schema is actually shaped for that query, not a fix.
SELECT * FROM orders_by_customer WHERE amount > 100;
-- InvalidRequest: amount isn't part of the primary key
SELECT * FROM orders_by_customer WHERE amount > 100 ALLOW FILTERING;
-- runs, but likely scans far more partitions than you expectBecause CQL can only sort using the order rows are already physically stored in, which is the clustering column order defined at table creation. There's no equivalent of a relational database sorting an arbitrary result set in memory after fetching it, since a query might touch data spread across many nodes and Cassandra deliberately avoids operations whose cost scales unpredictably with data size. If you need to sort by a column, that column has to be a clustering column in the table's primary key.
The write is first appended to the commit log on disk, an append-only, sequential-write log that exists purely for crash recovery. At essentially the same time, the write is applied to the memtable, an in-memory structure sorted by clustering key for the relevant partition. Once both of those succeed, the coordinator considers the write durable and can acknowledge it back to the client, well before anything gets flushed to a permanent SSTable file.
Every flush creates a new, immutable SSTable, so over time a partition's data ends up scattered across more and more files, along with old row versions and tombstones nobody needs anymore. Compaction periodically merges multiple SSTables into fewer, larger ones, keeping only the latest version of each cell and physically dropping data shadowed by tombstones once they've aged past the grace period. Without it, both read latency and disk usage would climb indefinitely as the same logical row's history piles up across an ever-growing number of files.
Gossip is a peer-to-peer protocol where each node periodically exchanges state information, which other nodes it knows about, their status, load, schema version, with a few randomly chosen peers, and that information propagates across the whole cluster within a few rounds. There's no central coordinator because a single point tracking cluster membership would itself be a single point of failure, exactly the thing Cassandra's whole design is built to avoid. Every node ends up with an eventually-consistent view of the cluster's state without anyone being in charge of maintaining it.
A tombstone is a marker written in place of the deleted data, saying "this row, or this column, was deleted at this timestamp," rather than an actual physical removal. It has to work this way because the data might exist in multiple SSTables across multiple nodes, some of which the DELETE hasn't reached yet or won't reach until a repair runs, so an immediate physical delete on the node handling the request could get resurrected by an older replica still holding the pre-delete value. The tombstone has to be replicated and has to survive long enough that every replica agrees the row is gone before it's safe to actually reclaim the space during compaction.
Repair compares data across replicas for the same range and reconciles any differences, fixing inconsistencies caused by dropped writes, extended node outages that outlasted hinted handoff, or network issues that silently caused a replica to miss an update. It has to run regularly, generally within the gc_grace_seconds window and no less often than roughly weekly on most production clusters, because without it, replicas can quietly drift apart and there's no other mechanism guaranteeing they'll ever converge back to the same state.
Medium questions
25Usually you don't try to make one table serve more than one query pattern. You pick the partition key that satisfies the most frequent or most latency-sensitive query, then build a second table, sometimes materialized through the application, sometimes through a materialized view, for the other pattern. The mistake I see most often is someone trying to shove a secondary access pattern into an existing table's clustering columns and ending up with a partition key that doesn't match either query well.
All the rows for each value pile onto the same partition, and since Cassandra assigns whole partitions to nodes, you get a hot partition and, eventually, a hot node. A "status" partition key with three values on a busy table means three partitions absorbing the entire table's write and read load no matter how many nodes are in the cluster, because adding nodes doesn't spread a partition across more of them. This is the single most common modeling mistake candidates who've only used relational databases make on their first Cassandra project.
A simple primary key like PRIMARY KEY (customer_id) makes customer_id alone the partition key, one partition per customer. A composite partition key, written PRIMARY KEY ((tenant_id, customer_id), order_date), combines two columns inside the extra parentheses so that tenant_id and customer_id together determine placement, not either one alone. That's the pattern for multi-tenant systems where you want every tenant's data to spread across the cluster instead of tenant_id alone acting as a low-cardinality hot-partition risk.
Cassandra doesn't force eventual consistency, it makes consistency tunable per query. If you write at QUORUM and read at QUORUM with RF=3, the two overlapping majorities guarantee the read sees the latest write, which is effectively strong consistency for that read path. Eventual consistency only shows up if you deliberately choose weaker levels, like writing at ONE and reading at ONE, where the read might hit a replica that hasn't received the write yet. The tunability is the actual feature, not a fixed guarantee in either direction.
QUORUM counts a majority across every replica in every datacenter combined, which means a write has to cross the wide-area network and wait on acknowledgments from a remote datacenter before it can succeed. LOCAL_QUORUM only requires a majority of the replicas within the coordinator's own datacenter, so cross-datacenter latency and any temporary WAN partition don't block the write at all. Almost every multi-DC production deployment uses LOCAL_QUORUM specifically to avoid tying local write latency to a link that might be having a bad day on the other side of the world.
Last-write-wins, based on a client-side or server-side timestamp attached to every write, either supplied by the driver or generated server-side if the driver doesn't set one. Cassandra doesn't merge conflicting column values, the write with the higher timestamp simply overwrites the one with the lower timestamp, compared at the cell level, not the whole row. This is why clock synchronization across the cluster actually matters operationally, a node with a clock running fast enough can make its writes always win regardless of which one actually happened later in real time.
The risk isn't a slightly slower query, it's a query whose latency depends on how much data exists in the table, not on how much data you're actually asking for. A query that's fine in staging with a thousand rows can time out in production with a hundred million, and the failure mode isn't gradual, it tends to show up suddenly once the table crosses some size threshold and the coordinator node starts timing out or running out of memory building the result set. Teams that ban ALLOW FILTERING outright in code review aren't being paranoid, they're avoiding a class of incident that's genuinely hard to catch in testing.
Secondary indexes work reasonably well on low-cardinality columns where each indexed value maps to a modest, roughly consistent number of rows spread evenly across the cluster, something like a status field on a small table. They become a trap on high-cardinality columns, like email or user_id, because the index itself is distributed by the indexed value, not the base table's partition key, so a lookup can require querying most or all nodes to assemble the full result. That fan-out is invisible in the query itself and only shows up as latency once the table gets big enough for it to matter.
A materialized view automatically maintains a second table with a different primary key, derived from a base table, so you can query the same data by a different partition key without manually writing to two tables from the application. Cassandra handles the duplication and keeps the view in sync as the base table changes.
CREATE MATERIALIZED VIEW orders_by_status AS
SELECT * FROM orders_by_customer
WHERE status IS NOT NULL AND customer_id IS NOT NULL AND order_id IS NOT NULL
PRIMARY KEY (status, customer_id, order_id);In practice a lot of production teams still prefer to write to both tables manually from the application, or through a stream processor, because materialized views have had well-documented consistency edge cases during node failures and repairs, and debugging a view that's silently drifted from its base table is worse than the extra application code it would have taken to avoid one.
WHERE customer_id IN (a, b, c) on a partition key fans the query out to however many partitions those keys hash to, potentially different nodes, and merges the results, so it's really multiple single-partition reads bundled into one round trip from the client's perspective. WHERE order_date IN (...) on a clustering column, by contrast, filters within a single already-located partition, which is cheap since it's just reading a narrower slice of data that was already going to be read together. The partition-key version is the one to watch, a large IN list there can quietly turn one query into dozens of coordinator-side reads.
Sequential writes to disk are dramatically faster than random writes, even on modern SSDs, and the commit log's only job is durability, not queryability, so there's no reason to pay any cost for structure it'll never need. Nobody ever reads the commit log directly to answer an application query, it's replayed strictly during startup after an unclean shutdown, to rebuild whatever memtable state existed before the crash. That single-purpose design is why Cassandra can accept writes at the speed of appending to a file, rather than at the speed of updating an indexed data structure.
A flush is triggered by the memtable filling up to a configured size threshold, by memory pressure across all memtables on the node, or by an explicit nodetool flush. Once a memtable is flushed to an immutable SSTable file on disk, the corresponding portion of the commit log is no longer needed for recovery and gets marked for deletion, since that data is now durably represented in the SSTable instead. The commit log is really just a bridge covering the window between a write being acknowledged and that write being safely flushed to permanent, queryable storage.
Immutability is what makes SSTables safe to write sequentially and read concurrently without locking, since nothing ever changes underneath a reader once the file exists. An update doesn't rewrite the old SSTable, it writes a brand new row version, with a newer timestamp, into whatever memtable is currently active, which eventually flushes into a new SSTable. A delete works the same way, it writes a tombstone marker, not a physical removal. At read time, Cassandra merges every version of a row across the memtable and all relevant SSTables, keeping the one with the highest timestamp for each column, and dropping anything shadowed by a tombstone.
Each SSTable keeps a bloom filter, a compact probabilistic structure that can say with certainty a partition key is not in that file, or say it might be. It's a filter for ruling files out cheaply, not a lookup mechanism. A false positive just means Cassandra goes and checks the partition index and data file for a key that turns out not to be there after all, costing one wasted disk seek, not a correctness bug. False negatives can't happen by construction, so the filter never causes Cassandra to skip an SSTable that genuinely has the data.
STCS groups SSTables of roughly similar size together and merges a set of them once enough accumulate, producing progressively larger tables over time. It's write-optimized and cheap on I/O, but its downside is that a given row's data can still end up spread across SSTables of very different sizes if it isn't written frequently enough to get caught up in each merge cycle, and it can temporarily need up to double the disk space of the data being compacted, since the old SSTables aren't deleted until the new merged one finishes writing.
LCS organizes SSTables into levels of fixed size, typically 160MB each, where any single level guarantees non-overlapping key ranges across its SSTables. That guarantee means a read for a given partition usually only has to check one SSTable per level instead of scanning across many overlapping files, which makes LCS the better choice for read-heavy workloads. The trade-off is it does noticeably more compaction I/O to maintain that per-level guarantee, so it costs more in disk and CPU to keep that read speed advantage.
TWCS groups SSTables into time-based buckets, an hour or a day, say, and only compacts within a bucket, never merging data across time windows. For time-series data with a TTL, that matters because entire SSTables eventually age out and can be dropped wholesale once every row inside has expired, without Cassandra needing to rewrite or scan them first. SizeTiered has no concept of time locality, so a row from six months ago and a row from five minutes ago can end up merged into the same SSTable, meaning that whole file can't be dropped until the newest row in it also expires.
CREATE TABLE sensor_readings (
sensor_id uuid,
reading_time timestamp,
value double,
PRIMARY KEY (sensor_id, reading_time)
) WITH compaction = {'class': 'TimeWindowCompactionStrategy', 'compaction_window_unit': 'DAYS', 'compaction_window_size': 1}
AND default_time_to_live = 2592000;A vnode is one of several smaller token ranges assigned to a physical node, instead of that node owning one single, large contiguous range on the ring. Originally each node got exactly one token range, which meant adding or removing a node required manually recalculating and rebalancing token ranges across the whole cluster, and it made data distribution lumpy whenever nodes had different hardware capacity. With vnodes, typically 256 per node by default in older versions, joining or leaving the cluster spreads the rebalancing work across many small ranges automatically, and streaming during that rebalance is spread across far more of the existing nodes instead of overloading just the ones adjacent to the change.
Replication factor sets the count, but the strategy decides the placement rule. NetworkTopologyStrategy, the one almost every real production keyspace uses, lets you specify a replication factor per datacenter, so a row can have three replicas in one region and two in another, and within each datacenter it also tries to place replicas across different racks so a single rack failure doesn't take out every copy of a partition at once. SimpleStrategy just walks the ring and places replicas at the next N nodes with no rack or datacenter awareness at all, which is why it's fine for a single-node dev setup and genuinely dangerous in production.
A new node is assigned a share of the token ring's vnodes, which means it now owns a portion of the key space that used to belong entirely to its existing neighbors. To actually serve reads correctly for that portion, it needs the SSTable data for every partition that hashes into its new token ranges, so the existing replica owners for those ranges stream the relevant SSTable data directly to the joining node before it's marked as fully bootstrapped and starts serving traffic.
gc_grace_seconds is how long a tombstone has to exist, defaulting to 10 days, before compaction is allowed to actually remove it and reclaim the space. It exists to prevent a specific failure mode called a zombie row: if a node has been down or unreachable longer than gc_grace_seconds and never received the delete, then comes back and gets repaired after the tombstone's already been purged elsewhere, that node's stale pre-delete data could get treated as the newest version and effectively bring a deleted row back to life. The setting is really a bet that every replica will either receive the tombstone through normal replication or get repaired within that window.
The likely cause is a queue-like or expiring-data pattern where rows get deleted (or expire via TTL) far more often than the partition itself is deleted, leaving a large accumulation of tombstones a single read has to scan past before finding live data. Cassandra logs a warning once a read scans more than a configurable number of tombstones (1000 by default, tripping tombstone_warn_threshold) and will actually fail the query outright past tombstone_failure_threshold (100,000 by default), specifically to stop one bad partition from taking down a node's read latency for everyone else.
Hinted handoff is a short-term, automatic mechanism: if a coordinator can't reach a replica during a write, it stores a hint locally and replays it once that replica comes back, usually within a few hours. Repair is a manual or scheduled process that does a full, deep comparison of actual data across replicas using merkle trees, catching any inconsistency regardless of cause or how long ago it happened. Hints expire after a configurable window (three hours by default in modern versions), so any node down longer than that gets no hint replay at all for missed writes during that outage, which is exactly the gap repair exists to close.
A merkle tree is a tree of hashes where each leaf hashes a chunk of the data and each parent hashes the combination of its children, all the way up to a single root hash. Two replicas can compare their root hashes first, and only if those differ do they need to walk down and compare child hashes to narrow in on exactly which chunk of data actually diverged, instead of transferring and comparing every single row between nodes that might hold billions of them. It turns "are these two huge replicas identical" into a small number of hash comparisons for the common case where most of the data already matches.
nodetool status reports each node's state as seen through gossip, plus load, owned token percentage, host ID, and rack. UN means the node is up and has completed joining the ring normally, serving reads and writes as expected. DN means the node is currently marked down by gossip, either because it's genuinely offline, network-partitioned from the node you ran the command on, or in the middle of a longer GC pause severe enough that it's stopped responding to gossip heartbeats, which is a common false alarm worth checking before assuming a hardware failure.
Hard questions
10Bucketing means adding an extra component to the partition key, often a time window like year-month or a hashed shard number, specifically to cap how large any single partition can grow. A sensor_readings table partitioned only by sensor_id looks fine for months, then that partition keeps absorbing every new reading forever, since a device that's been reporting for three years has three years of clustering rows in one partition living on the same replicas.
CREATE TABLE readings_bucketed (
sensor_id uuid,
year_month text,
reading_time timestamp,
value double,
PRIMARY KEY ((sensor_id, year_month), reading_time)
);
-- partition key is now (sensor_id, year_month), so each partition
-- only ever holds one month of readings, capped and predictableWide partitions cause real operational pain: slower compaction on that specific SSTable range, larger snapshots, and read latency that climbs the more clustering rows a single read has to page through. The rule of thumb the Cassandra community settled on is to keep partitions well under 100MB and under a few hundred thousand cells, and to bucket proactively for any table with an unbounded, ever-growing clustering dimension like time-series data.
Usually not, because of the write path's durability guarantee independent of the consistency level. Any node that successfully writes a row appends it to its local commit log before acknowledging, and that commit log is fsynced to disk, so a crash right after acknowledgment doesn't lose the write on that node, it's recoverable on restart. What can happen is that the other two replicas never receive the write via normal replication if the coordinator or the crashed node doesn't retry, and depending on timing the row might sit inconsistent until hinted handoff or a repair fixes it. So the data isn't gone, but it can briefly be under-replicated and unavailable from the nodes a subsequent QUORUM read might contact, which is exactly the scenario that makes people distrust ONE for anything they truly can't afford to be inconsistent for even briefly.
token() returns the hashed value the partitioner computes from a partition key, the actual number used to place data on the ring. You'd call it directly mostly for range-scanning an entire table safely, paging through it by token range instead of by an arbitrary column, since it lets you resume a full-table scan from exactly where you left off without re-scanning already-processed partitions, and it's the mechanism tools like Spark connectors use internally to split a table into parallel scan ranges across the cluster.
SELECT * FROM orders_by_customer
WHERE token(customer_id) > token(?)
LIMIT 1000;
-- pages through the whole table in token order, resumable and boundedThe coordinator has to check the memtable and every SSTable that could possibly contain that partition, using a bloom filter per SSTable first to cheaply rule out files that definitely don't have the partition, then a partition index to find where in a candidate SSTable the row actually starts. It reads all matching fragments and merges them cell by cell, keeping the newest timestamp per column across every source. This is exactly why read latency and read amplification climb as a partition accumulates versions across more SSTables without being compacted, more files to check means more bloom filter lookups, more disk seeks, and more merge work per read.
First I'd check whether the compaction strategy actually matches the write and access pattern, a time-series table stuck on SizeTiered instead of TimeWindow is a common root cause. Then I'd check the write rate against the configured compaction throughput throttle (compaction_throughput_mb_per_sec), since a node can genuinely be generating SSTables faster than the compaction thread pool is allowed to process them, especially right after a large bulk load or a burst of traffic. I'd also check nodetool compactionstats for the actual pending count and which tables are contributing most, since it's frequently one poorly modeled table (unbounded partitions, or a workload with heavy overwrite churn) dragging the whole node's I/O down rather than a cluster-wide problem.
Any node in the cluster can act as coordinator for any request, that's a deliberate design choice so clients don't need to know the ring topology. The coordinator hashes the partition key to find which nodes actually own replicas for it, forwards the write to each of those replica nodes in parallel, and waits for however many acknowledgments the requested consistency level needs before replying to the client. If one of the target replicas is temporarily down, the coordinator stores a hint, a record of the missed write, and replays it to that node once it comes back, which is the hinted handoff mechanism, though hints alone aren't a substitute for repair if a node is down long enough for hints to expire.
Because the delete rate roughly matches the insert rate by design, which means the ratio of tombstones to live data in that partition stays permanently bad instead of settling down over time the way a normal table's tombstone ratio does once old data ages out. Every consumer scanning for the next unprocessed item has to read past however many tombstones have piled up ahead of the live rows, and that cost only grows as throughput grows, since higher throughput means more deletes accumulating at the same rate as more inserts. Purpose-built queue systems, or at minimum a design that avoids row-level deletes entirely (marking processed instead of removing, with periodic full-partition drops), sidestep this because Cassandra's storage engine fundamentally isn't optimized for a workload where delete volume tracks insert volume one to one.
A row-level tombstone marks one specific row or cell as deleted. A range tombstone is written by a single DELETE statement that removes a whole range of clustering rows at once (or all rows in a partition), and it has to be checked against every SSTable that might contain data in that range, even ones that were written long after the delete, because Cassandra has to keep applying that boundary until compaction eventually merges everything and the range tombstone itself can be dropped. Deleting a large clustering range in one statement is efficient to issue but can leave an outsized, long-lived marker that every subsequent read into that range has to account for until it clears.
A full repair compares and reconciles all data in the specified range every time it runs, regardless of whether it's already been repaired before, which gets expensive and slow as data volume grows. Incremental repair tracks which SSTables have already been marked as repaired and only compares unrepaired data on subsequent runs, which is far cheaper on an ongoing basis, but it depends on repaired and unrepaired SSTables staying correctly separated by the storage engine, and mixing repair strategies inconsistently across a cluster's history has historically caused real headaches, including anti-compaction bugs that made some teams stick with full repair on a longer cycle instead.
Four days is almost certainly past the default hint window and possibly close to or past gc_grace_seconds depending on configuration, so hinted handoff alone can't be assumed to have caught the node up. The safe move is running a repair against that node specifically before routing meaningful read traffic to it, and until that repair completes, a read at consistency level ONE that happens to land on that node risks returning stale data, while QUORUM reads are protected as long as the other replicas in the quorum are healthy and up to date. If the outage exceeded gc_grace_seconds, there's also a real risk that a tombstone got purged elsewhere while this node still holds the pre-delete data, meaning that specific row could resurface incorrectly if repair isn't run before the tombstone is gone everywhere.
How to prepare for a Cassandra interview in 2026
Skip another read-through of the CAP theorem slide. Build one small schema that forces a real decision: model a time-series table with a bucketed partition key and a TTL, pick a compaction strategy for it and be ready to justify why, then deliberately write a query that needs ALLOW FILTERING and explain in your own words why it's a smell rather than a shortcut. Run nodetool status and nodetool compactionstats against even a single-node local cluster so the output isn't unfamiliar the first time an interviewer asks you to read one.
Across the backend and infrastructure mock interviews run through LastRoundAI, the tombstone questions catch more candidates off guard than the consistency-level questions do, even though consistency levels get far more attention in prep material. My read is that QUORUM versus ONE is the kind of thing people memorize as a flashcard fact, while tombstones only really click once you've been paged for a slow partition at 3am. We don't track a precise number on that gap, but it comes up often enough in review sessions to flag here.
One thing worth knowing walking in: Cassandra's own documentation has gotten noticeably more explicit in recent versions about anti-patterns that used to be left as tribal knowledge, unbounded partitions, queue-like delete patterns, and secondary indexes on high-cardinality columns are all called out directly rather than buried in a mailing list thread somewhere (Apache Cassandra documentation, Data modeling). An interviewer who's read that page recently will notice if your answer treats these as edge cases instead of the first things to check.
Get the reps in before the real thing
Explaining a partition key on a whiteboard is not the same as defending your schema choice out loud once an interviewer asks what happens when that partition hits ten million rows. LastRoundAI's mock interview mode runs live system-design and coding rounds with real-time follow-up questions in your browser, and the free plan includes 15 credits a month that reset monthly rather than piling up unused. Starter is $19/mo if a handful of sessions isn't enough runway.
Once your answers hold up under a follow-up, the slower part of the job hunt is usually just getting in front of enough backend and infrastructure roles that actually test distributed data stores instead of treating them as a resume keyword. Auto-Apply queues tailored applications for your review, 10 a month on the free plan, up to 400 a month on the Ultimate plan, and nothing goes out until you approve it.
Questions about either product go to contact@lastroundai.com. That's the only inbox we check.
How this list was built
Worth being straight about where these questions come from, because plenty of pages in this category are not. The set was compiled from a research pass across official documentation, vendor release notes, published engineering writing and public discussion of hiring processes, then cross-checked against the current version of each technology so nothing here describes behaviour that has since changed.
What that means in practice: these are the questions the material supports as reasonable and current for this role, not a transcript of any one company's loop. We have not sat in on your interview and we are not going to claim we have. Treat the list as well-sourced preparation rather than a leaked question bank, and expect your panel to phrase things their own way.
If you spot something out of date, tell us at contact@lastroundai.com and we will fix it.
Frequently asked questions
Is Cassandra still worth learning in 2026?
For interview purposes the question is really whether the teams you are targeting use it, which is worth checking against their actual job postings rather than general popularity rankings. Where it is in use it tends to be deeply embedded and slow to replace.
Should I memorise Cassandra syntax for the interview?
Rarely worth it. Most interviewers care that you know what to reach for and why, and will not fail you for forgetting an exact flag. Being confidently wrong about behaviour costs far more than admitting you would check the documentation.
What is the most common mistake in Cassandra interviews?
Answering the question that was asked and stopping there. The strongest candidates add the trade-off or the failure mode without being prompted, which is what signals real use rather than revision.
How long does it take to prepare for a Cassandra interview?
If you already work with Cassandra day to day, a focused week on the areas you avoid in practice is usually enough. Coming in cold, expect three to four weeks. The gap is rarely knowledge; it is being able to explain something you normally just use.
What Cassandra topics come up most often?
Interviewers concentrate on the parts that cause production incidents rather than the parts that are pleasant to learn. Expect the fundamentals to be assumed and the follow-up questions to sit one layer below what a tutorial covers.

