Skip to content

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

nodetool setcompactionthroughput

Sets the total compaction throughput limit across all compaction threads on a node.


Terminal window
nodetool [connection_options] setcompactionthroughput <throughput_mb_per_sec>

See connection options for connection options.

nodetool setcompactionthroughput controls the maximum rate at which all compaction operations combined can write data to disk. This throttle prevents compaction from consuming too much disk I/O and impacting production read/write workloads.

Aggregate Limit

The throughput limit is the total aggregate limit across all concurrent compaction threads, not a per-thread limit.

For example, with concurrent_compactors: 4 and throughput set to 128 MiB/s:

  • All 4 compaction threads share the 128 MiB/s budget
  • Each thread averages approximately 32 MiB/s (128 ÷ 4)
  • The actual distribution varies based on workload
Compaction Throughput DistributionCompaction Throughput DistributionTotal Throughput: 128 MiB/sThread 1~32 MiB/sThread 2~32 MiB/sThread 3~32 MiB/sThread 4~32 MiB/sDisk I/O

Non-Persistent Setting

This setting is applied at runtime only and does not persist across node restarts. After a restart, the value reverts to the compaction_throughput setting in cassandra.yaml (default: 64 MiB/s).

To make the change permanent, update cassandra.yaml:

compaction_throughput: 128MiB/s

ArgumentDescription
throughput_mib_per_secMaximum MiB/s for all compaction writes combined. 0 = unlimited

cassandra.yaml Parameter

The corresponding cassandra.yaml parameter changed in 4.1:

Cassandra VersionParameter NameExample
Pre-4.1compaction_throughput_mb_per_sec64
4.1+compaction_throughput64MiB/s

Terminal window
nodetool setcompactionthroughput 128
Terminal window
nodetool setcompactionthroughput 0
Terminal window
nodetool getcompactionthroughput

Symptoms:

  • nodetool compactionstats shows increasing pending compactions
  • SSTable counts rising over time
  • Read latencies gradually increasing

Action: Increase throughput to help compaction keep pace:

Terminal window
# Check current pending compactions
nodetool compactionstats
# Check current throughput
nodetool getcompactionthroughput
# Increase throughput
nodetool setcompactionthroughput 256
# Monitor progress
watch -n 10 'nodetool compactionstats'

Scenario 2: Production Latencies Spiking During Compaction

Section titled “Scenario 2: Production Latencies Spiking During Compaction”

Symptoms:

  • Read/write latencies spike when compaction is active
  • Disk I/O at or near 100% utilization
  • Application timeouts correlate with compaction activity

Action: Decrease throughput to reduce I/O contention:

Terminal window
# Check if compaction is running
nodetool compactionstats
# Reduce throughput to ease disk pressure
nodetool setcompactionthroughput 64
# Monitor latencies
nodetool proxyhistograms

Scenario 3: Maintenance Window - Clear Backlog

Section titled “Scenario 3: Maintenance Window - Clear Backlog”

Symptoms:

  • Scheduled maintenance with reduced traffic
  • Need to clear compaction backlog before peak hours

Action: Temporarily maximize throughput:

Terminal window
# Remove throttle during maintenance
nodetool setcompactionthroughput 0
# Or set very high value
nodetool setcompactionthroughput 1024
# Wait for compactions to complete
watch -n 10 'nodetool compactionstats'
# Restore normal throttle before traffic returns
nodetool setcompactionthroughput 128

Symptoms:

  • Large amount of data just loaded
  • Many SSTables created, pending compaction

Action: Increase throughput to consolidate data faster:

Terminal window
# After bulk load completes
nodetool setcompactionthroughput 512
# Monitor compaction progress
nodetool compactionstats
# Once caught up, restore normal value
nodetool setcompactionthroughput 128

Symptoms:

  • Disk usage approaching capacity
  • Compaction can free space by removing tombstones/overwrites

Action: Increase throughput to accelerate space reclamation:

Terminal window
# Check disk space
df -h /var/lib/cassandra
# Increase compaction speed
nodetool setcompactionthroughput 512
# Optionally trigger compaction on specific tables
nodetool compact my_keyspace my_table

Gather baseline metrics to understand current state:

#!/bin/bash
# baseline_metrics.sh - Capture before changing throughput
echo "=== Current Compaction Throughput ==="
nodetool getcompactionthroughput
echo ""
echo "=== Pending Compactions ==="
nodetool compactionstats
echo ""
echo "=== SSTable Counts (top 10 tables) ==="
nodetool tablestats | grep -E "Table:|SSTable count" | head -20
echo ""
echo "=== Disk I/O ==="
iostat -x 1 3 | tail -10
echo ""
echo "=== Read/Write Latencies ==="
nodetool proxyhistograms
MetricHow to CheckWhat to Look For
Pending compactionsnodetool compactionstatsShould decrease after increasing throughput
Disk I/O utilizationiostat -x 1%util should not sustain 100%
Disk I/O awaitiostat -x 1await (ms) indicates I/O latency
Read latencynodetool proxyhistograms99th percentile read latency
Write latencynodetool proxyhistograms99th percentile write latency
SSTable countnodetool tablestatsShould decrease as compaction catches up
Compaction throughputnodetool compactionstatsActual MiB/s being written
#!/bin/bash
# monitor_compaction.sh - Watch key metrics in real-time
while true; do
clear
echo "=== $(date) ==="
echo ""
echo "--- Compaction Status ---"
nodetool compactionstats | head -15
echo ""
echo "--- Disk I/O ---"
iostat -x 1 1 | grep -E "Device|sda|nvme" | tail -2
echo ""
echo "--- Recent Latencies ---"
nodetool proxyhistograms | head -10
sleep 10
done
ObservationProblemAction
Disk %util consistently 100%I/O saturatedDecrease throughput
await > 20ms (SSD) or > 100ms (HDD)I/O congestionDecrease throughput
Read 99th percentile spikingCompaction impacting readsDecrease throughput
Pending compactions growingThroughput too lowIncrease throughput
SSTable count rising steadilyCompaction can't keep upIncrease throughput

Storage TypeDefaultConservativeAggressiveNotes
HDD (7200 RPM)64 MiB/s32 MiB/s128 MiB/sLimited by seek time, be conservative
HDD (15K RPM)64 MiB/s48 MiB/s160 MiB/sSlightly better than 7200 RPM
SATA SSD128 MiB/s64 MiB/s256 MiB/sGood baseline for most SSDs
NVMe SSD256 MiB/s128 MiB/s512+ MiB/sCan handle much higher throughput
Cloud (EBS gp3)128 MiB/s64 MiB/sProvisioned IOPSDepends on provisioned performance
Cloud (local NVMe)256 MiB/s128 MiB/s512+ MiB/sSimilar to on-prem NVMe
Terminal window
# 1. Start with default or conservative value
nodetool setcompactionthroughput 64
# 2. Monitor disk utilization and latencies
iostat -x 5
nodetool proxyhistograms
# 3. If disk has headroom (util < 70%), increase
nodetool setcompactionthroughput 128
# 4. Continue monitoring
# 5. If latencies spike, back off
nodetool setcompactionthroughput 96
# 6. Find the sweet spot where:
# - Compaction keeps pace (pending not growing)
# - Disk not saturated (util < 80%)
# - Latencies acceptable

Pros and cons of low, high, and unlimited compaction throughputPros and cons of low, high, and unlimited compaction throughputLow Throughput (32-64 MiB/s)High Throughput (256+ MiB/s)Unlimited (0)ProsConsProsConsProsConsMinimal impact on production I/OStable read/write latenciesPredictable disk behaviorCompaction may fall behindSSTable count growsRead performance degrades over timeDisk space may fill with uncompacted dataCompaction keeps pace with writesFewer SSTables, better read performanceFaster tombstone removalMay impact production I/OPotential latency spikesDisk saturation riskMaximum compaction speedClears backlog fastestCan severely impact productionRisk of disk saturationOnly safe during maintenance windows

The optimal throughput balances:

  1. Compaction keeping pace - Pending compactions not growing
  2. Acceptable latencies - Production traffic not impacted
  3. Disk headroom - I/O utilization not saturated
Terminal window
# Good balance indicators:
# - Pending compactions: stable or decreasing
# - Disk I/O util: 50-70%
# - Read p99: within SLA
# - Write p99: within SLA

The throughput limit interacts with the number of concurrent compactors:

cassandra.yaml
concurrent_compactors: 4 # Number of parallel compaction threads
compaction_throughput: 128MiB/s # Total throughput for all threads
concurrent_compactorsthroughputPer-Thread Average
2128 MiB/s~64 MiB/s
4128 MiB/s~32 MiB/s
8128 MiB/s~16 MiB/s
4256 MiB/s~64 MiB/s
4512 MiB/s~128 MiB/s

Balancing Threads and Throughput

More compactors with the same throughput means each individual compaction runs slower, but more compactions run in parallel. The total throughput remains capped.

For CPU-bound compaction (compression), more threads can help. For I/O-bound compaction, the throughput limit is the bottleneck.


set_compaction_throughput_cluster.sh
#!/bin/bash
THROUGHPUT="${1:-128}"
# Get list of node IPs from local nodetool status
nodes=$(nodetool status | grep "^UN" | awk '{print $2}')
echo "Setting compaction throughput to $THROUGHPUT MiB/s on all nodes..."
for node in $nodes; do
echo -n "$node: "
ssh "$node" 'nodetool setcompactionthroughput '"$THROUGHPUT"' && echo "set to '"$THROUGHPUT"' MiB/s" || echo "FAILED"'
done
echo ""
echo "Verification:"
for node in $nodes; do
echo -n "$node: "
ssh "$node" "nodetool getcompactionthroughput"
done
# cassandra.yaml - applies after restart
compaction_throughput: 128MiB/s

Throughput Seems Limited Despite High Setting

Section titled “Throughput Seems Limited Despite High Setting”
Terminal window
# Check actual compaction throughput in compactionstats
nodetool compactionstats
# Look for "throughput" in output
# May be limited by:
# 1. Disk I/O capacity
# 2. CPU (if heavy compression)
# 3. No compactions pending
# Check disk I/O
iostat -x 1 5

Compaction Still Slow After Increasing Throughput

Section titled “Compaction Still Slow After Increasing Throughput”
Terminal window
# Check if compactions are actually running
nodetool compactionstats
# Check if disk is the bottleneck
iostat -x 1 3
# Check if CPU is bottleneck (compression)
top -H -p $(pgrep -f CassandraDaemon)
# May need to increase concurrent_compactors instead
# (requires cassandra.yaml change and restart)
Terminal window
# Runtime setting doesn't persist
# Check cassandra.yaml
grep compaction_throughput /etc/cassandra/cassandra.yaml
# Update for persistence
# Then restart or set runtime value

Throughput Guidelines

  1. Monitor before changing - Establish baseline metrics
  2. Adjust incrementally - Change by 50-100% at a time, not 10x
  3. Watch disk I/O - Keep utilization below 80%
  4. Check latencies - Ensure production traffic isn't impacted
  5. Time it right - Make aggressive changes during low-traffic periods
  6. Make permanent - Update cassandra.yaml after validating changes
  7. Apply cluster-wide - Set same value on all nodes for consistency

Avoid These Mistakes

  • Setting unlimited (0) during peak traffic
  • Ignoring disk I/O metrics when increasing throughput
  • Forgetting to persist changes to cassandra.yaml
  • Setting different values on different nodes (causes imbalance)

CommandRelationship
getcompactionthroughputView current throughput setting
compactionstatsMonitor active and pending compactions
setconcurrentcompactorsAdjust number of compaction threads
setstreamthroughputControl streaming throughput (different from compaction)
tablestatsView SSTable counts per table
proxyhistogramsCheck read/write latencies