cassandra-easy-stress is a powerful and flexible tool for performing benchmarks and testing data models for Apache Cassandra.
Most benchmarking tools require learning complex configuration systems before you can run your first test. cassandra-easy-stress provides pre-built workloads for common Cassandra patterns. Modify these workloads with flexible parameters to match your environment, or write custom workloads in Kotlin when you need full control.
Full docs are here: https://apache.github.io/cassandra-easy-stress/
The easiest way to get started on Linux is to use system packages. Instructions for installation can be found here: https://apache.github.io/cassandra-easy-stress/#_installation
Clone this repo, then build with gradle:
git clone https://github.com/apache/cassandra-easy-stress.git cd cassandra-easy-stress ./gradlew shadowJar
Use the shell script wrapper to start and get help:
bin/cassandra-easy-stress -h
Time series workload with a billion operations:
bin/cassandra-easy-stress run BasicTimeSeries -i 1B
Key value workload with a million operations across 5k partitions, 50:50 read:write ratio:
bin/cassandra-easy-stress run KeyValue -i 1M -p 5k -r .5
Time series workload, using TWCS:
bin/cassandra-easy-stress run BasicTimeSeries -i 10M --compaction "{'class':'TimeWindowCompactionStrategy', 'compaction_window_size': 1, 'compaction_window_unit': 'DAYS'}"
Time series workload with a run lasting 1h and 30mins:
bin/cassandra-easy-stress run BasicTimeSeries -d "1h30m"
Time series workload with Cassandra Authentication enabled:
bin/cassandra-easy-stress run BasicTimeSeries -d '30m' -U '<username>' -P '<password>' **Note**: The quotes are mandatory around the username/password if they contain special chararacters, which is pretty common for password
Docs are served out of /docs and can be rebuild using ./gradlew docs.
Run all tests against the default version (Cassandra 5.0):
./gradlew test
Run tests against a specific version:
./gradlew test40 # Cassandra 4.0 ./gradlew test41 # Cassandra 4.1 ./gradlew test50 # Cassandra 5.0
Run tests against all versions sequentially:
./gradlew testAllVersions
All integration tests use Testcontainers to automatically manage Cassandra instances. This means:
When a test class extends CassandraTestBase, the framework automatically:
CASSANDRA_VERSION environment variable (defaults to “5.0”)docker/cassandra-{version}/Each Cassandra version uses a custom Dockerfile that enables experimental features:
materialized_views_enabled: trueThe Dockerfiles are located at:
docker/cassandra-4.0/Dockerfiledocker/cassandra-4.1/Dockerfiledocker/cassandra-5.0/DockerfileSome workloads require specific Cassandra versions or features. Annotations control when workloads are tested.
Marks workloads that require a minimum Cassandra version. Tests automatically skip these workloads on older versions.
Example:
@MinimumVersion("5.0") class SAI : IStressWorkload { // SAI indexes are only available in Cassandra 5.0+ }
How it works:
CASSANDRA_VERSION environment variable determines which version is runningWorkload.getWorkloadsForTesting() filters out workloads where the version doesn't meet the minimumCurrently annotated workloads:
MaterializedViews - Requires 5.0+ (materialized views enabled)SAI - Requires 5.0+ (Storage Attached Indexes)Marks workloads that require DataStax Enterprise features. These are skipped by default.
Example:
@RequireDSE class DSESearch : IStressWorkload { // Uses DSE Search (Solr) functionality }
Enable in tests:
TEST_DSE=1 ./gradlew test
Currently annotated workloads:
DSESearch - Uses DSE Search (Solr)Marks workloads that use Accord transaction features (available in Cassandra 6.0+). These are skipped by default.
Example:
@RequireAccord class TxnCounter : IStressWorkload { // Uses Accord transactions }
Enable in tests:
TEST_ACCORD=1 ./gradlew test
Currently annotated workloads:
TxnCounter - Uses Accord transactionsTo run all tests including DSE and Accord workloads:
TEST_DSE=1 TEST_ACCORD=1 ./gradlew test
Individual test tasks are created for each Cassandra version:
./gradlew test40 # Cassandra 4.0 ./gradlew test41 # Cassandra 4.1 ./gradlew test50 # Cassandra 5.0
These are proper Gradle Test tasks, so they support all standard Test task options:
# Run only specific tests ./gradlew test50 --tests "*KeyValue*" # Enable debug mode ./gradlew test50 --debug-jvm # Rerun even if up-to-date ./gradlew test40 --rerun-tasks
How they work:
CASSANDRA_VERSION environment variable to the corresponding versiontest taskRuns tests against all Cassandra versions sequentially:
./gradlew testAllVersions
This task:
test40, test41, and test50mustRunAfter to prevent Docker resource conflictsExecution time:
The standard test task respects the CASSANDRA_VERSION environment variable:
# Test against Cassandra 4.1 CASSANDRA_VERSION=4.1 ./gradlew test # Test against Cassandra 5.0 (default) CASSANDRA_VERSION=5.0 ./gradlew test
If CASSANDRA_VERSION is not set, it defaults to “5.0”.
The GitHub Actions CI workflow (.github/workflows/ci.yml) runs on every push and pull request.
Test matrix:
This creates 6 test jobs total:
Workflow steps:
./gradlew test50)cassandra-easy-stress-{version}.tar.gzReplicate CI behavior locally:
# Run the same tests as CI for Cassandra 5.0 ./gradlew test50 ktlintCheck detekt # Test all versions like CI does (sequentially) ./gradlew testAllVersions # Generate coverage report ./gradlew test koverXmlReport
Integration tests extend CassandraTestBase:
class MyWorkloadTest : CassandraTestBase() { @Test fun testWorkload() { // connection is available from CassandraTestBase val result = connection.execute("SELECT * FROM system.local") assertThat(result).isNotNull } }
Available properties from CassandraTestBase:
connection: CqlSession instanceip: Container IP addressport: Mapped CQL portlocalDc: Datacenter name (defaults to “datacenter1”)Utility methods:
cleanupKeyspace(): Drops the test keyspacekeyspaceExists(): Checks if test keyspace existsgetCassandraVersion(): Returns Cassandra release version stringTest guidelines:
CassandraTestBase for integration tests requiring Cassandra@BeforeEach to ensure clean state with cleanupKeyspace()runBlocking in tests (use kotlinx.coroutines.test.runTest instead)cassandra-easy-stress includes a Model Context Protocol (MCP) server that allows AI assistants to interact with the stress testing tool. To start in server mode:
cassandra-easy-stress server
To test the MCP server integration with Claude Code:
Add the MCP server (assuming it's running locally):
claude mcp add -t sse cassandra-easy-stress http://localhost:9000/sse
Run the MCP integration test prompt:
/test-mcp
This will verify that the MCP server is properly configured and accessible from Claude Code.
The MCP server should work with any tool that supports the Model Context Protocol. If you‘ve successfully integrated cassandra-easy-stress with another MCP-compatible tool, please send a PR with instructions and we’ll update this README.