Schema Migration Tool ——

cassachange logo1 for Cassandra, AstraDB, ScyllaDB & beyond

Purpose-built CQL migration tool. Versioned scripts, rollback, distributed locking, multi-keyspace deploys, environment profiles, and secret manager integration — across eight validated platforms including Google Bigtable, Azure CosmosDB for Cassandra, and Azure Managed Cassandra. No JVM, no XML changelogs, no compromises.

Works identically on a developer's laptop and in CI — validate offline, dry-run locally, test the MCP server against a dev cluster before anything reaches staging or production.
cassachange — deploy session
$ cassachange deploy --profile prod --tag release-2.1.0
[secrets] resolved 2 keys via azure-keyvault
[lock] acquired global (host:a4f3b1)
[RUN] V1.0.0__create_users.cql 42ms
[RUN] V1.1.0__add_orders.cql 28ms
[SKIP] V1.2.0__add_profiles.cql already applied
[RUN] R__users_by_email.cql checksum changed
[RUN] A__refresh_perms.cql always
[notify] Slack → deploy_success
[lock] released
✓ myapp_prod: run 3 | skip 1 | errors 0 | tag release-2.1.0
$
10
CLI Commands
4
Script Types
LWT
Distributed Locking
0
JVM Required
Validated on Apache Cassandra DataStax AstraDB ScyllaDB Azure Managed Cassandra ENT Azure CosmosDB for Cassandra ENT Amazon Keyspaces ENT Google Bigtable ENT

Protocol

How It Works

Every deploy follows a deterministic 9-step sequence. Nothing runs without validation. Nothing runs twice.

01

Validate Keyspaces

Checks all target keyspaces and the history keyspace exist in Cassandra. Exits immediately with a descriptive error if any are missing.

02

Acquire Deploy Lock

Writes a distributed lock row using Cassandra LWT (INSERT IF NOT EXISTS). Atomic at the cluster level — blocks concurrent deploys.

03

Discover Scripts

Recursively walks your migrations folder. Classifies every .cql file by prefix. Sorts versioned scripts globally by semver number.

04

Read History

Queries change_history to build the set of applied versions and checksums for the target keyspace. One query — no N+1.

05

Run V__ Scripts

Applies pending versioned scripts in ascending semver order. Already-applied versions are skipped automatically.

06

Run R__ Scripts

Reruns repeatable scripts whose MD5 checksum has changed since last apply. Unchanged checksums are skipped.

07

Run A__ Scripts

Always executes every deploy — no conditions, no history check. Designed for grants and permission refreshes.

08

Record History

Writes a SUCCESS or FAILED row to change_history for every script. Includes keyspace, checksum, tag, run_id, and execution time in ms.

09

Release Lock

Releases the lock via DELETE IF run_id = ... — a Cassandra LWT so only this process can release its own lock.

cassachange never creates keyspaces. All keyspaces — including the history keyspace — must be provisioned externally via Terraform or equivalent. Keyspace creation is an infrastructure concern; schema migration is cassachange's concern.

Conventions

Four Script Types

The filename is the config. No XML, no YAML changelogs — just well-named .cql files in any folder structure you choose.

V

Versioned

Runs once, in ascending semver order. Never re-runs. The workhorse of schema evolution — CREATE TABLE, ALTER TABLE, new indexes.

V1.2.0__add_orders_table.cql
U

Undo

Paired rollback for a versioned script. Only executes on cassachange rollback. Enables explicit, safe schema reversal — free.

U1.2.0__add_orders_table.cql
R

Repeatable

Reruns on deploy when its MD5 checksum changes. Ideal for UDFs, lookup tables, and secondary views. Unchanged = skipped.

R__users_by_username.cql
A

Always

Executes on every single deploy — no conditions whatsoever. Designed for grants and permissions that must always be current.

A__refresh_permissions.cql
Scriptdeployrollback
V__ (versioned)✓ pending only✓ via U__
U__ (undo)
R__ (repeatable)✓ if changed
A__ (always) ✓ always

Scripts are discovered recursively. Organise by module, release, team — any structure. Version ordering is always global across all subdirectories.

migrations/ — by module layout
users/ V1.0.0__create_users_table.cql V1.2.0__add_profile_fields.cql U1.2.0__add_profile_fields.cql R__users_by_username.cql orders/ V1.1.0__add_orders_table.cql V1.3.0__add_order_status.cql U1.1.0__add_orders_table.cql shared/ A__refresh_permissions.cql
migrations/ — by release layout
release-1.0/ V1.0.0__initial_schema.cql release-1.1/ V1.1.0__add_orders.cql U1.1.0__add_orders.cql release-1.2/ V1.2.0__add_profiles.cql U1.2.0__add_profiles.cql
Version ordering is global across all subdirectories. V1.1.0 in orders/ runs before V1.2.0 in users/ regardless of folder. Duplicate versions across subdirectories are caught by cassachange validate.

CLI

Nine Commands

Composable, consistent CLI. Config via YAML, environment variables, or flags. Same connection args across every command. Core migration commands plus seven complementary tools for observability, governance, and developer workflow.

deploy+ Lock
Applies all pending migrations. Acquires distributed lock, runs V__ (pending), R__ (changed), A__ (always), releases lock. Supports profiles, tags, dry-run output.
# profile + release tag cassachange deploy \ --profile prod --tag rel-2.1.0 # dry run → JSON plan cassachange deploy --dry-run-output plan.json
rollback+ Lock
Rolls back versioned migrations using paired U__ undo scripts. Supports rollback by version number or by release tag. Writes ROLLED_BACK sentinel rows.
# roll back to a version cassachange rollback \ --target-version 1.1.0 # roll back a whole release cassachange rollback --tag rel-2.1.0
validateOffline
Lints all scripts without connecting to Cassandra. Catches naming errors, duplicate versions, orphaned undo scripts, empty files. Run this in every PR pipeline.
cassachange validate # custom folder cassachange validate \ --root-folder ./db/migrations
status
Reads and displays the full migration history. Shows VERSION, KEYSPACE, TAG, SCRIPT, STATUS, and INSTALLED_ON. Filter by keyspace or tag.
cassachange status # filter to one release tag cassachange status --tag rel-2.1.0
repairRecovery
Operational recovery without touching the database manually. Reset FAILED scripts for retry, inspect lock state, or force-release a stuck deploy lock.
# inspect — no changes cassachange repair --list # mark failed scripts for retry cassachange repair --keyspace myapp # force-release stuck lock cassachange repair --release-lock
baselineNew
Introspects a live keyspace and generates a V0.0.0__baseline.cql file. Captures tables, UDTs, indexes, UDFs, UDAs. All statements use IF NOT EXISTS.
# generate from live keyspace cassachange baseline \ --keyspace myapp # with version + output dir cassachange baseline \ --keyspace myapp \ --baseline-version 1.0.0
auditImmutable
Views the immutable audit log. Every deploy start/end, script run, failure, and rollback is recorded with operator, hostname, and timestamp.
# last 50 audit events cassachange audit # filter to a specific run cassachange audit \ --run-id <uuid> --limit 100
deployDry Run
Writes a structured JSON plan — every skip (with reason) and every planned run (with checksum). No lock acquired, no DB writes. Use as a CI artifact or PR comment.
# generates plan.json, no DB writes cassachange deploy \ --profile prod \ --dry-run-output plan.json
analyse⚠ paid
Connects to a live keyspace and scores every table against 23 rules across 5 categories — partition key hotspots, ALLOW FILTERING traps, TTL gaps, index misuse, schema anti-patterns. Exit code 2 on criticals.
# score all keyspaces in profile cassachange analyse --profile dev # with remediation advice cassachange analyse \ --profile prod --verbose # JSON output for CI gates cassachange analyse \ --profile prod --json

Core Capabilities

The foundation. Everything cassachange needs to reliably evolve a Cassandra schema in production — versioning, safety, auditability, and recovery.

🔢

Versioned Migrations

V__ scripts run once, in strict semver order, globally across all subdirectories. Applied versions are permanently recorded in change_history and never re-run.

V1.0.0__create_users.cql ✓ applied V1.1.0__add_orders.cql ✓ applied V1.2.0__add_indexes.cql → pending
↩️

Rollback via U__ Scripts

Every versioned script can have a paired U__ undo script. Roll back the latest version or everything above a target version. ROLLED_BACK sentinels allow re-application later. Free.

# roll back one version cassachange rollback --keyspace myapp # roll back to v1.1.0 cassachange rollback --target-version 1.1.0
🔒

Distributed Locking via LWT

INSERT IF NOT EXISTS (Paxos-backed LWT) prevents concurrent deploys at the cluster level. Lock carries a 30-minute TTL — a crashed deploy never permanently blocks future ones.

acquire → INSERT IF NOT EXISTS (LWT) release → DELETE IF run_id = ... expire → TTL 1800s auto-expiry repair → --release-lock escape hatch

Offline Script Validation

cassachange validate lints all scripts without connecting to Cassandra. Catches bad filenames, duplicate versions, orphaned undo scripts, empty files. Zero cost to run on every PR.

cassachange validate V1.0.0__create_users.cql V1.1.0__add_orders.cql V1.1.0__add_index.cql duplicate version!
🗂

Repeatable & Always Scripts

R__ scripts rerun when their MD5 checksum changes — ideal for UDFs and lookup tables. A__ scripts execute every deploy unconditionally — perfect for grants and permission refreshes.

R__users_by_username.cql checksum changed → RUN R__orders_by_status.cql checksum same → SKIP A__refresh_permissions.cql always → RUN
🔧

Repair Command

When a deploy fails, repair provides a safe, fully auditable recovery path. List failures, mark them for retry, or force-release a stuck lock — without touching the database manually.

# inspect without changes cassachange repair --list # mark failed scripts for retry cassachange repair --keyspace myapp # force-release stuck lock cassachange repair --release-lock
📜

Immutable Audit Log

Every deploy start/end, script execution, failure, rollback, and repair is written to audit_log as an immutable append-only row. Operator, hostname, run_id, and timestamp on every event.

DEPLOY_START operator=ci run_id=a4f3b1 SCRIPT_RUN V1.2.0__... SUCCESS 42ms DEPLOY_END total_errors=0
🌐

Multi-Keyspace Deploy

Run one deploy across multiple keyspaces in a single command. Each keyspace gets its own change_history rows. One lock acquired, all keyspaces migrated sequentially.

cassachange deploy \ --keyspaces myapp_prod,orders_prod,analytics_prod myapp_prod: run 2 | skip 1 | errors 0 orders_prod: run 1 | skip 2 | errors 0 analytics_prod: run 0 | skip 3 | errors 0
☁️

Dual Connection Mode

Standard Cassandra (username/password, SSL/mTLS), AstraDB (Secure Connect Bundle + token), ScyllaDB, Azure Managed Cassandra, and Amazon Keyspaces — all detected automatically from config. Enterprise adds Google Bigtable proxy and Azure CosmosDB for Cassandra. No mode flag, no manual switching.

# standard cassandra hosts: [10.0.0.1, 10.0.0.2] username: cassandra # astradb — just set env vars ASTRA_TOKEN=AstraCS:... ASTRA_SECURE_CONNECT_BUNDLE=./scb.zip

Operational Maturity

Features that make cassachange production-grade — environment management, observability, secret security, and structured rollout controls.

🌿

Per-Environment Config Profiles

Define named profiles in cassachange.yml. Each profile deep-merges over base config — connection settings, keyspaces, timeouts, notifications. Select via --profile or CASSACHANGE_PROFILE.

profiles: dev: hosts: [127.0.0.1] keyspace: myapp_dev prod: hosts: [cass1.prod] timeout: 120 cassachange deploy --profile prod
📄

Dry-Run Output to File

--dry-run-output plan.json writes a structured JSON plan — every skip (with reason) and every planned run (with checksum). Use as a CI artifact or PR comment. Implies --dry-run automatically.

cassachange deploy \ --dry-run-output plan.json # plan.json: { "total_actions": 5, "actions": [ { "action": "run", "script": "V1.2.0" }, { "action": "skip", "reason": "applied" } ]}
🔔

Webhook & Notification Channels

Fire-and-forget notifications to Slack (Block Kit), Microsoft Teams (Adaptive Card), or any generic HTTP webhook. Failures log a WARNING — never block a deploy.

notifications: on_events: [deploy_success, script_failed] channels: - type: slack webhook_url_env: SLACK_WEBHOOK_URL - type: webhook url: https://ops.example.com/hook
🔐

Secret Manager Integration

Pull credentials at runtime from HashiCorp Vault, AWS SSM, AWS Secrets Manager, or Azure Key Vault. Injected before connection opens, removed from live config — URIs never appear in logs.

secrets_provider: azure-keyvault secrets: password: akv://my-vault/cassandra-pw astra_token: akv://my-vault/creds#token # vault:// | ssm:/// | asm:// also supported

Per-Statement Execution Timeout

Set a per-CQL-statement timeout in seconds. Raises OperationTimedOut if exceeded. Configure per-profile so dev uses the default and prod gets extra time for large schema changes.

# prod profile profiles: prod: timeout: 120 # seconds/statement # or via CLI / env var cassachange deploy --timeout 120 CASSACHANGE_TIMEOUT=120
🏷

Release Tagging

Attach a release tag to every deploy. Tags are stored in change_history per script row. Filter status by tag, or roll back an entire release by tag name instead of hunting individual versions.

cassachange deploy --tag rel-2.1.0 # roll back the whole release cassachange rollback --tag rel-2.1.0 # inspect the release cassachange status --tag rel-2.1.0

Developer Experience

Features that smooth the day-to-day — onboarding existing clusters, introspection, and workflow tooling that keeps the team moving fast.

📸

Baseline Schema Introspection

Point cassachange at an existing live keyspace and it generates a complete V0.0.0__baseline.cql — tables, UDTs, indexes, UDFs, UDAs. All statements use IF NOT EXISTS so the file is safe to re-run. The starting point for bringing an unmanaged cluster under version control.

cassachange baseline --keyspace myapp \ --output ./migrations \ --baseline-version 1.0.0 # generates: V1.0.0__baseline_myapp.cql # captures: tables, UDTs, indexes, UDFs, UDAs # all: CREATE ... IF NOT EXISTS
🏗

Recursive Folder Scanning

Organise migrations any way you like — by module, team, release, or feature. cassachange walks the entire tree recursively, classifies every .cql file by prefix, and sorts versions globally. Folder structure never affects execution order.

migrations/ users/ V1.0.0, V1.2.0, R__... orders/ V1.1.0, V1.3.0, U1.1.0 payments/ V2.0.0, V2.1.0 shared/ A__refresh_permissions.cql # global execution order: V1.0.0 → V1.1.0 → V1.2.0 → V1.3.0 → V2.0.0 → V2.1.0
🐍

Pure Python, No JVM

Runs on Python 3.8+ with two runtime dependencies: cassandra-driver and pyyaml. No Java, no Maven, no Docker required to run migrations. Secret provider extras are optional installs only if you use them.

pip install cassachange # core pip install cassachange[vault] # + hvac pip install cassachange[aws] # + boto3 pip install cassachange[azure] # + azure-identity pip install cassachange[all] # everything
⚙️

GitHub Actions Workflow

A production-ready 4-job pipeline ships in the package: validate (every PR) → dry-run → deploy → rollback (manual only). Rollback cannot fire on a push event. Dry-run artifact uploaded to GitHub before the real deploy runs.

validate → every push, no DB connection dry-run → plan.json artifact uploaded deploy → push to main, env gate rollback → manual trigger only # workflow_dispatch inputs: profile: staging | prod tag: release-2.1.0
🔑

Flexible Auth Priority Chain

Configuration priority is explicit and overridable at every layer — CLI beats env vars beats YAML beats defaults. Add CASSACHANGE_PROFILE to your CI environment and never touch a flag. Credentials stay in secrets, non-sensitive config lives in YAML.

# priority (highest → lowest): CLI flags → --profile prod --tag v2.1.0 env vars → CASSACHANGE_PROFILE=prod cassachange.yml → profiles.prod.hosts defaults → port 9042, root ./migrations
🩺

Multi-Keyspace Profiles

Define keyspaces as a list in any profile. One --profile prod deploy migrates all production keyspaces in sequence — no scripts, no loops. Still overridable with --keyspace or --keyspaces on the CLI for surgical runs.

profiles: prod: keyspaces: - myapp_prod - orders_prod - analytics_prod # migrates all three in one command: cassachange deploy --profile prod

Editions

Community & Enterprise

cassachange is free and open source. The enterprise edition adds secret manager integration, the immutable audit log, and a full suite of schema intelligence and observability tools.

Community
FREE
Everything you need to run reliable Cassandra schema migrations in production.
✓  Deploy / rollback / validate / status / repair
✓  Versioned, repeatable, always, undo scripts
✓  Distributed locking (LWT)
✓  CQL syntax linter
✓  Dry run + JSON plan output
✓  Per-environment config profiles
✓  Release tagging + tag-based rollback
✓  Slack / Teams / webhook notifications
✓  Multi-keyspace deploy
✓  Baseline schema introspection
✓  Per-statement timeout
✓  GitHub Actions CI/CD integration
↑ Apache Cassandra · AstraDB · ScyllaDB · Azure Managed Cassandra
pip install cassachange

docker
Enterprise
PAID
Everything in Community, plus secret management, audit log, schema intelligence, observability, governance tools, and enterprise platform support: Google Bigtable proxy, Azure CosmosDB for Cassandra, and Amazon Keyspaces.
✓  Everything in Community
Security & Compliance
✓  Secret manager integration
HashiCorp Vault · AWS SSM · AWS Secrets Manager · Azure Key Vault
✓  File secrets  SSL certs + AstraDB SCB from vault
✓  Immutable audit log  SOC2 / HIPAA ready & full event history
Schema Intelligence
✓  23-rule scorer — partition  hotspots, ALLOW FILTERING traps, TTL gaps, index misuse, anti-patterns
✓  compare two live keyspaces  — BREAKING / WARNING / INFO per difference
✓  generate an idempotent  V__.cql migration from a diff
✓  policy-as-code schema enforcement  — CI exit codes, GitHub annotations, 23 + 12 custom rules
Observability & Operations
✓  5-probe table health snapshots  — row count, partition size, TTL drift, tombstone ratio, collection bloat
✓  OLS growth projections  to 180-day horizon — WARNING / CRITICAL thresholds per table
✓  self-contained HTML CI/CD analytics  — success rate, p95 deploy times, slowest & most-failed scripts
✓  schema-aware synthetic test data  — semantic column hints, batched INSERTs, reproducible via seed
Platform Extensions
✓  Google Bigtable  via Cassandra proxy — schema-map, proxy lint.
✓  Azure CosmosDB for Cassandra  SSL + AKV credentials
✓  Amazon Keyspaces  managed Cassandra — mTLS, AKV cert vault
✓  Priority support
pip install cassachange-enterprise

docker

mcp server
Contact: enterprise@cassachange.com
Community edition — clear errors when enterprise features are used
secrets block in cassachange.yml
ERROR Secret manager integration requires cassachange-enterprise. pip install cassachange-enterprise enterprise@cassachange.com
cassachange audit
ERROR 'Audit' requires cassachange-enterprise. pip install cassachange-enterprise enterprise@cassachange.com
cassachange analyse / diff / generate / contract
ERROR Schema intelligence tools require cassachange-enterprise. pip install cassachange-enterprise enterprise@cassachange.com
cassachange monitor / capacity / dashboard / seed
ERROR Observability tools require cassachange-enterprise. pip install cassachange-enterprise enterprise@cassachange.com


Safety

Distributed Locking

One deploy at a time, guaranteed. Cassandra Lightweight Transactions ensure atomicity at the cluster level — no external coordination needed.

🚀
Deploy A
CI push to main
🔒

deploy_lock

INSERT IF NOT EXISTS
TTL: 30 minutes

Deploy B
Blocked — clear error
acquire → INSERT IF NOT EXISTS (LWT — cluster-atomic)
release → DELETE IF run_id = ... (only owner can release)
expire → TTL 1800s auto-expiry if process crashes
repair → cassachange repair --release-lock (force escape hatch)

Cassandra LWT Guarantee

Uses INSERT IF NOT EXISTS — Paxos-backed atomic operation. No race conditions between concurrent CI pipelines, ever.

30-Minute Auto-Expiry TTL

Lock row has a TTL baked in. A crashed deploy never permanently blocks future deploys — the lock dissolves automatically.

🔑

Owner-Only Release

Release uses DELETE IF run_id = ... — another LWT. A process cannot release a lock it doesn't own, preventing accidental unlocks.

👁

Dry Run Skips Lock

--dry-run never acquires the lock. Safe to run as many times as needed in review pipelines without blocking any real deploys.

🔧

Repair Escape Hatch

cassachange repair --release-lock force-releases a stuck lock immediately. No need to wait for TTL or access the database directly.


Recovery

The Repair Command

When a deploy fails, repair gives you a safe, fully auditable path back. Original FAILED rows are never deleted — every state transition is preserved.

1

Deploy fails mid-run

cassachange records a FAILED row in change_history. The lock is released. The cluster is in a known intermediate state.

status: FAILEDrecorded in change_history. Audit trail begins.
2

Inspect what failed

Run repair --list to see all FAILED scripts, which keyspaces they affect, and any currently active lock rows. Zero side effects.

cassachange repair --listShows failures and lock state. No changes made.
3

Fix the CQL script

Edit the broken migration in your repo. Open a PR, get it reviewed, merge. The fix is in version control where it belongs.

Edit file → commit → merge to main
4

Mark failed scripts for retry

Run cassachange repair. Inserts a REPAIRED sentinel row per failed script. Original FAILED rows remain — full audit chain preserved.

cassachange repair --keyspace myappInserts REPAIRED rows. No destructive changes.
5

Redeploy

Run cassachange deploy. Repaired scripts are retried. On success, change_history shows the full chain: FAILED → REPAIRED → SUCCESS.

cassachange deploy --keyspace myappHistory: FAILED → REPAIRED → SUCCESS
🔐

Stuck Lock Recovery

When a crashed deploy leaves the lock behind

# option 1 — wait 30min for TTL auto-expire # option 2 — force-release immediately cassachange repair --release-lock # check lock state first cassachange repair --list
📜

Audit Trail Status Values

All transitions are immutable rows in change_history

SUCCESS ← script applied cleanly FAILED ← script errored mid-run REPAIRED ← marked for retry by repair ROLLED_BACK ← undo script executed

Configuration

Connection Modes

Apache Cassandra, AstraDB, ScyllaDB, Azure Managed Cassandra, Amazon Keyspaces — detected automatically from config. Enterprise adds Google Bigtable proxy, Azure CosmosDB for Cassandra, and Amazon Keyspaces. No mode flag, no manual switching.

🖥

Apache Cassandra 3.x / 4.x / 5.x

Username/password. Optional SSL/mTLS.

hosts: - cass1.prod - cass2.prod port: 9042 username: app_user keyspace: myapp history_keyspace: myapp_migrations # ssl: true / ssl_cafile: /path/to/ca.crt
☁️

DataStax AstraDB

SCB zip + application token. Protocol v4 auto-pinned.

# cassachange.yml — non-secret config keyspace: myapp history_keyspace: myapp_migrations # env vars — never commit # ASTRA_SECURE_CONNECT_BUNDLE=./scb.zip # ASTRA_TOKEN=AstraCS:xxxx...
🦋

ScyllaDB 5.2+

Identical config to Cassandra. No plugin needed.

hosts: - scylla-node-1.internal - scylla-node-2.internal port: 9042 username: app_user history_keyspace: myapp_migrations # LWT lock requires ScyllaDB ≥ 5.2
🔷

Azure Managed Cassandra

Real Cassandra nodes. mTLS auth. Natural Azure Key Vault fit.

hosts: - cluster.cassandra.cosmos.azure.com ssl: true history_keyspace: myapp_migrations # enterprise: pull certs from Azure Key Vault # ssl_cafile: akv://vault/ca-cert-b64 # ssl_certfile: akv://vault/client-cert-b64
enterprise
🟠

Amazon Keyspaces

CQL subset. LWT best-effort. No DROP TABLE / UDTs.

hosts: - cassandra.us-east-1.amazonaws.com port: 9142 ssl: true ssl_cafile: /path/to/sf-class2-root.crt # enterprise: asm://myapp-keyspaces#password
enterprise
🟢

Google Bigtable

Via Cassandra-to-Bigtable proxy. CQL migrations — proxy translates to Bigtable API.

bigtable_proxy: true bigtable_proxy_host: 127.0.0.1 bigtable_proxy_port: 9042 keyspace: myapp history_keyspace: myapp_cass # cassachange schema-map verify # cassachange validate ← proxy lint
enterprise
🔷

Azure CosmosDB for Cassandra

Cassandra-compatible API. SSL + token auth. Azure Key Vault cert support.

hosts: - myaccount.cassandra.cosmos.azure.com port: 10350 ssl: true username: myaccount history_keyspace: myapp_migrations # enterprise: pull password from Azure Key Vault # password: akv://my-vault/cosmos-cassandra-key

cassachange-enterprise
PAID

Schema Analyser

Connect to a live keyspace and get a scored report of schema anti-patterns, hotspot risks, TTL gaps, and index problems — before they cause incidents in production. Reads from system_schema only. No writes, no side effects.

Usage

Reads keyspace / keyspaces from your profile — same config as deploy.

# Analyse all keyspaces in your dev profile cassachange analyse --profile dev # Single keyspace override cassachange analyse --profile prod --keyspace myapp # Show remediation advice per finding cassachange analyse --profile prod --verbose # JSON output — pipe into CI gates or dashboards cassachange analyse --profile prod --json # Suppress specific rules cassachange analyse --profile prod --skip PK004,IR004
📊

Sample Output

Tables sorted by severity. Score per table and overall keyspace.

sessions [40/100 CRITICAL] 1 critical 1 warning ✖ CRITICAL TH001 Table Health Ephemeral table without TTL — unbounded growth → ALTER TABLE sessions WITH default_time_to_live = 86400; user_events [70/100 FAIR] 2 warning ⚠ WARNING PK002 Partition Key Quality Timestamp-only partition key — write hotspot risk ───────────────────────────────────────── Overall score: 61/100 FAIR 3 critical 7 warning 4 info Exit codes: 0 = clean · 1 = warnings · 2 = criticals

23 rules across 5 categories

Partition Key Quality · PK001–PK004 Query Safety · QS001–QS004 Table Health · TH001–TH005 Schema Anti-patterns · SA002–SA006 Index Recommendations · IR001–IR005
RuleSeverityWhat it catches
PK001CRITICALBoolean / tinyint partition key — all data on one node
PK002WARNINGTimestamp-only partition key — time-series write hotspot
PK003WARNINGDate as first composite key component — daily write hotspot
PK004INFOTime-series table without TTL — unbounded disk growth
QS001CRITICALNo clustering columns + many regular columns — ALLOW FILTERING trap
QS002WARNING4+ clustering columns — complex slice query risk
QS003WARNINGText / blob clustering column — unbounded sort range
QS004INFONo clustering columns — range queries not possible
TH001CRITICALSession / cache / token table without TTL — unbounded growth
TH002WARNINGAppend-oriented table without TTL or deletion strategy
TH003WARNING50+ columns — relational model transposed to Cassandra
TH004WARNINGUnbounded list / map collection — partition bloat risk
TH005CRITICALCounter columns mixed with regular columns — writes will fail
SA002WARNINGInteger id as partition key — sequential write hotspot
SA003WARNINGNo temporal anchor and no TTL — data lifecycle unmanageable
SA004WARNINGUUID partition with no clustering — isolated row pattern
SA005INFOColumn names are CQL reserved keywords — quoting required everywhere
SA006INFOCOMPACT STORAGE — deprecated in Cassandra 4.x, removal planned
IR001WARNING3+ secondary indexes on one table — hidden write amplification
IR002WARNINGSecondary index on UUID / timeuuid — index as large as base table
IR003WARNINGSecondary index on boolean / tinyint — near-full cluster scan on read
IR004INFO8+ non-key columns with no indexes — limited access pattern flexibility
IR005INFOSAI index present — not available on ScyllaDB or Amazon Keyspaces

Automation

GitHub Actions Included

Four jobs. Rollback is manual-only by design — it can never be triggered accidentally by a push event. Dry-run artifact uploaded before real deploy runs.

Job 01

validate

Offline lint — no Cassandra connection. Catches naming errors, duplicates, orphaned undos. Zero cost to run on every PR.

Every push
Job 02

dry-run

Generates migration-plan.json and uploads it as a GitHub artifact. Gives reviewers a clear view of exactly what will change before approving the deploy.

Push to main
Job 03

deploy

Runs after dry-run passes. Deploys with --profile and --tag from workflow_dispatch inputs. Sends Slack notification on success or failure.

Push to main
Job 04

rollback

Manual trigger only — via GitHub Actions UI. Rolls back by tag or target version. Can never fire on a push event. Dry run runs first.

Manual only
🔑

Standard Cassandra Secrets

CASSANDRA_HOSTS CASSANDRA_USERNAME CASSANDRA_PASSWORD CASSACHANGE_HISTORY_KEYSPACE SLACK_WEBHOOK_URL
☁️

AstraDB Secrets

ASTRA_TOKEN ASTRA_SECURE_CONNECT_BUNDLE # base64-encoded zip CASSACHANGE_HISTORY_KEYSPACE # encode SCB on macOS: base64 -i secure-connect.zip | pbcopy # encode on Linux: base64 -w 0 secure-connect.zip

Comparison

cassachange vs Other Tools

General-purpose SQL migration tools are excellent for relational databases. Their Cassandra support is a community afterthought bolted on. cassachange is native.

cassachange

Versioned scripts
Repeatable scripts
Always scripts (A__)✓ free
Undo / Rollback✓ free
Distributed locking✓ Cassandra LWT
Offline validation✓ free
Multi-keyspace deploy
Release tagging
Dry-run → JSON plan✓ free
Config profiles
Secret manager✓ Vault / SSM / ASM / AKV
Webhooks✓ Slack / Teams
Native CQL✓ first-class
AstraDB auth✓ built-in
ScyllaDB support✓ native
Azure Managed Cassandra✓ Enterprise + AKV cert fit
Azure CosmosDB Cassandra✓ Enterprise
Amazon Keyspaces✓ Enterprise
Google Bigtable proxy✓ Enterprise
GitHub Actions CI/CD
Schema analyser
Drift detection
Table monitoring
Capacity projections
AI / MCP integration✓ 13-tool server
RuntimePython 3.8+

SQL-First Tools

Versioned scripts
Repeatable scripts
Always scripts (A__)
Undo / Rollback✓ paid tier
Distributed locking
Offline validation
Multi-keyspace deploy
Release tagging
Dry-run → JSON plan⚠ paid
Config profiles⚠ env files
Secret manager
Webhooks
Native CQL⚠ plugin
AstraDB auth
ScyllaDB support
Azure Managed Cassandra
GitHub Actions CI/CD⚠ manual
Schema analyser
Drift detection
Table monitoring
Capacity projections
AI / MCP integration
RuntimeJVM (Java 8+)

Generic Migrators

Versioned scripts
Repeatable scripts⚠ partial
Always scripts (A__)
Undo / Rollback⚠ DDL only
Distributed locking
Offline validation
Multi-keyspace deploy⚠ relational only
Release tagging
Dry-run → JSON plan⚠ paid
Config profiles⚠ manual
Secret manager
Webhooks
Native CQL⚠ wrapper
AstraDB auth
ScyllaDB support
Azure Managed Cassandra
GitHub Actions CI/CD⚠ manual
Schema analyser
Drift detection
Table monitoring
Capacity projections
AI / MCP integration⚠ Preview, SQL only
RuntimeJVM / Node / Ruby

cassachange

Native CQL execution✓ cassandra-driver
AstraDB SCB✓ built-in
AstraDB token auth
Protocol v4 auto-pin✓ no warnings
No keyspace creation✓ Terraform-safe
Multi-keyspace run
CQL rollback scripts✓ U__ files
Live baseline
ScyllaDB✓ hosts mode
Azure Managed Cassandra✓ full + AKV certs
Amazon Keyspaces✓ CQL subset
Plugin stability✓ no plugins needed
CQL schema analysis✓ 23 rules
Drift detection✓ live keyspace diff
CQL from diff✓ ALTER / CREATE / DROP
CQL contracts✓ TTL · PK · index limits
Capacity alerts✓ partition · tombstone · TTL

SQL-First Tools

Native CQL execution⚠ community plugin
AstraDB SCB✗ custom DataSource
AstraDB token auth
Protocol v4 auto-pin
No keyspace creation✗ tries CREATE SCHEMA
Multi-keyspace run
CQL rollback scripts✗ no CQL gen
Live baseline
ScyllaDB
Azure Managed Cassandra
Amazon Keyspaces
Plugin stability✗ frequently breaks
CQL schema analysis✗ SQL-only rules
Drift detection
CQL from diff✗ SQL only
CQL contracts
Capacity alerts

Generic Migrators

Native CQL execution⚠ 3rd-party ext
AstraDB SCB
AstraDB token auth
Protocol v4 auto-pin
No keyspace creation✗ tries CREATE SCHEMA
Multi-keyspace run
CQL rollback scripts✗ no CQL gen
Live baseline
ScyllaDB
Azure Managed Cassandra
Amazon Keyspaces
Plugin stability✗ lags releases
CQL schema analysis
Drift detection
CQL from diff
CQL contracts
Capacity alerts

cassachange

Rollback available
CostFree
Cassandra DDL✓ explicit CQL
MechanismExplicit U__ CQL you write
Rollback by tag✓ --tag release-2.1.0
Audit trail✓ ROLLED_BACK row
Re-apply after✓ automatic
Dry-run preview✓ --dry-run
Rollback safety✓ cassachange diff first

SQL-First (Free)

Rollback available
Cost
Cassandra DDL
Mechanism
Rollback by tag
Audit trail
Re-apply after
Dry-run preview
Rollback safety

SQL-First (Paid)

Rollback available
Cost~$500+/yr
Cassandra DDL✗ no CQL support
MechanismExplicit undo SQL
Rollback by tag
Audit trail
Re-apply after⚠ manual
Dry-run preview
Rollback safety
SQL-first paid tiers auto-generate DROP TABLE / ALTER TABLE for relational DDL. They cannot generate CQL. On paid tiers, Cassandra rollback still requires manual undo scripts — the same approach as cassachange, except cassachange is free and includes rollback-by-tag.

cassachange

Env profiles (YAML)✓ profiles: block
Dry-run artifact✓ --dry-run-output
Slack / Teams✓ built-in
Generic webhook
HashiCorp Vault
AWS SSM / ASM
Azure Key Vault
Tag + rollback
Immutable audit log✓ audit_log table
Per-statement timeout
Live baseline
Table monitoring✓ 5-probe snapshots
Schema scoring✓ 23 rules, 0–100 score
Drift detection✓ BREAKING / WARNING / INFO
Migration from diff✓ idempotent CQL
Test data seeding✓ schema-aware
Deploy dashboard✓ HTML, KPIs, trends
Capacity projections✓ OLS regression per table
Policy enforcement✓ policy-as-code, CI exit codes

SQL-First Tools

Env profiles (YAML)⚠ env-specific files
Dry-run artifact⚠ paid
Slack / Teams
Generic webhook
HashiCorp Vault
AWS SSM / ASM
Azure Key Vault
Tag + rollback
Immutable audit log⚠ partial
Per-statement timeout⚠ JDBC global
Live baseline⚠ SQL only
Table monitoring
Schema scoring
Drift detection
Migration from diff
Test data seeding
Deploy dashboard
Capacity projections
Policy enforcement

Generic Migrators

Env profiles (YAML)
Dry-run artifact⚠ paid
Slack / Teams
Generic webhook
HashiCorp Vault
AWS SSM / ASM
Azure Key Vault
Tag + rollback
Immutable audit log
Per-statement timeout
Live baseline✗ (CQL)
Table monitoring
Schema scoring
Drift detection
Migration from diff
Test data seeding
Deploy dashboard
Capacity projections
Policy enforcement

cassachange

Cassandra / Astra / Scylla★★★★★
Azure Managed Cassandra★★★★★
Amazon Keyspaces★★★★
Ease of setup★★★★★
Rollback (free)★★★★★
AstraDB support★★★★★
Secret management★★★★★
Observability★★★★★
Schema contracts★★★★★
Schema advisor★★★★★
Relational DB fit

SQL-First Tools

Cassandra / AstraDB★★★★★
Azure Managed Cassandra
Amazon Keyspaces
Ease of setup★★★★★
Rollback (free)
AstraDB support
Secret management★★★★★
Observability
Schema contracts
Schema advisor
Relational DB fit★★★★★

Generic Migrators

Cassandra / AstraDB★★★★
Azure Managed Cassandra
Amazon Keyspaces
Ease of setup★★★★★
Rollback (free)★★★★★
AstraDB support
Secret management★★★★★
Observability
Schema contracts
Schema advisor
Relational DB fit★★★★★
Use cassachange if your database is Cassandra or AstraDB. Use a SQL-first or generic migration tool if your primary database is relational and Cassandra is secondary. Don't fight your tools — pick the one built for your stack.

Professional Services

for Teams Running Cassandra

From CI/CD-integrated schema migrations to AI-ready vector search — hands-on Cassandra expertise for teams that want to move fast without hiring an in-house specialist.

cassachange Workshop

A focused half-day or full-day session teaching your team how to use cassachange for safe, repeatable Cassandra schema migrations — including full CI/CD pipeline integration tailored to your stack.

✓  cassachange fundamentals and migration lifecycle
✓  CI/CD integration (GitHub Actions, GitLab, Jenkins)
✓  Schema versioning and rollback strategy
✓  Live walkthrough on your real schema
# half-day → cassachange core + CI/CD wiring # full-day → above + live schema migration lab → book a session

Cassandra for AI Use Cases

Cassandra 5.0 brings native vector search, making it a first-class store for RAG pipelines, generative AI, and ML workloads. We design and operate the data layer your AI stack depends on.

✓  Vector search schema design (Cassandra 5.0)
✓  RAG pipeline integration and embedding storage
✓  High-velocity event and feature store patterns
✓  Geo-replicated, low-latency reads for inference
✓  AstraDB vector + generative AI setup
CREATE INDEX ON embeddings (vector) USING 'sai' WITH OPTIONS = { 'similarity_function': 'cosine' };

Cassandra + Spark Analytics

Cassandra handles high-speed ingestion, persistent storage, and low-latency queries. Spark handles large-scale transformations, aggregations, ML, and stream processing. We wire the two together.

✓  High-velocity ingestion pipeline design
✓  Spark-Cassandra connector setup and tuning
✓  Partition strategy for analytical query patterns
✓  Stream processing with Spark Structured Streaming
✓  ML feature store backed by Cassandra
# Cassandra → ingest · store · low-latency reads # Spark → transform · aggregate · ML · stream # connector → spark-cassandra-connector 3.x → contact us to scope your pipeline

Bring cassachange to your team

Embedded expertise for a sprint, a quarter, or a migration project. Schema redesign, AstraDB adoption, cassachange rollout, or a full platform audit — scoped to what you need.

✓  Schema audit and redesign
✓  cassachange rollout and team enablement
✓  Architecture review and sign-off
→ enterprise@cassachange.com
Not sure where to start?
Drop us a line — we'll scope the right engagement in one call.
enterprise@cassachange.com