Skip to content

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

nodetool setcolumnindexsize

Cassandra 4.1+

This command is available in Cassandra 4.1 and later.

Sets the column index size threshold for SSTable partition index granularity.


Terminal window
nodetool [connection_options] setcolumnindexsize <size_in_kb>

See connection options for connection options.


nodetool setcolumnindexsize sets the column index size threshold in kilobytes. This threshold controls how frequently Cassandra creates index entries within a partition when writing SSTables. Despite the name "column index," this setting actually controls the partition index granularity—how Cassandra navigates within large partitions to find specific rows or cells.

Understanding the Name

The term "column index" is a legacy name from earlier Cassandra versions when the data model was column-oriented. In modern Cassandra (3.0+), this is more accurately described as the partition index or row index interval within SSTables.


When Cassandra reads data from an SSTable, it needs to locate the specific rows within a partition. Without any indexing, Cassandra would have to read the entire partition sequentially to find the requested data—extremely inefficient for large partitions.

Large Partition (1 GB)
┌─────────────────────────────────────────────────────────────┐
│ Row 1 │ Row 2 │ Row 3 │ ... │ Row 999,999 │ Row 1,000,000 │
└─────────────────────────────────────────────────────────────┘
Without index: Must scan from beginning to find this row

The column index creates periodic "bookmarks" within a partition, allowing Cassandra to skip directly to the approximate location of the data it needs:

Partition with Column Index (default 64 KB intervals)
┌──────────────┬──────────────┬──────────────┬──────────────┐
│ Block 1 │ Block 2 │ Block 3 │ Block 4 │
│ (64 KB) │ (64 KB) │ (64 KB) │ (64 KB) │
└──────────────┴──────────────┴──────────────┴──────────────┘
▲ ▲ ▲ ▲
│ │ │ │
Index Entry Index Entry Index Entry Index Entry
To find a row:
1. Read index entries (small)
2. Find correct block via binary search
3. Scan only that 64 KB block

The column_index_size (default: 64 KB) determines how much partition data is written before Cassandra creates a new index entry:

ThresholdIndex Entry Created Every...Index Entries for 1 GB Partition
16 KB16 KB of data~65,536 entries
64 KB (default)64 KB of data~16,384 entries
256 KB256 KB of data~4,096 entries

ArgumentDescription
size_in_kbColumn index size threshold in kilobytes (required). Must be a positive integer.

Scenario 1: Very Large Partitions with Point Queries

Section titled “Scenario 1: Very Large Partitions with Point Queries”

Problem: Application frequently reads individual rows from partitions that are hundreds of megabytes or gigabytes in size.

Symptom: High read latency even when querying by full primary key.

Solution: Decrease the threshold (e.g., 16 KB or 32 KB) to create more index entries.

Terminal window
# Current setting (check first)
nodetool getcolumnindexsize
# Output: Current value for column_index_size: 64 KiB
# Reduce for more granular indexing
nodetool setcolumnindexsize 16

Result: More index entries means faster row lookups within partitions, at the cost of slightly larger index memory usage.

Problem: Workload consists primarily of small partitions (< 100 KB each), and the default creates unnecessary index entries.

Symptom: Higher than expected memory usage for partition indexes; most partitions have only 0-1 index entries anyway.

Solution: Increase the threshold (e.g., 128 KB or 256 KB) to reduce index overhead.

Terminal window
# Increase threshold for small partition workloads
nodetool setcolumnindexsize 128

Result: Fewer index entries means less memory usage and smaller SSTable index files.

Scenario 3: Range Queries on Wide Partitions

Section titled “Scenario 3: Range Queries on Wide Partitions”

Problem: Application performs range queries (e.g., WHERE partition_key = X AND clustering_key > Y) on wide partitions.

Symptom: Range queries are slow because Cassandra must scan large blocks to find the starting point.

Solution: Decrease the threshold to enable faster seek to the start of the range.

Terminal window
# Smaller threshold for better range query performance
nodetool setcolumnindexsize 32

Problem: Nodes have limited heap memory, and partition indexes are consuming too much space.

Symptom: Frequent GC pauses; nodetool info shows high "Index Summary" memory usage.

Solution: Increase the threshold to reduce index entry count.

Terminal window
# Reduce memory usage at cost of some read performance
nodetool setcolumnindexsize 128

AspectEffect
Read latency (point queries)Improved - Can locate rows faster
Read latency (range queries)Improved - Better seek accuracy
Index memory usageIncreased - More entries to store
SSTable file sizeSlightly increased - More index data
Write performanceMinimal impact - Slightly more index writes
AspectEffect
Read latency (point queries)Degraded - Must scan larger blocks
Read latency (range queries)Degraded - Less precise seeking
Index memory usageReduced - Fewer entries to store
SSTable file sizeSlightly reduced - Less index data
Write performanceMinimal impact - Fewer index writes

  • Wide partitions (> 1 MB) with point queries
  • Very wide partitions (> 100 MB) with any query pattern
  • Memory-constrained environments where every MB counts
  • High-performance requirements where milliseconds matter
  • Small partitions (< 64 KB) - No index entries created anyway
  • Full partition reads - Must read everything regardless
  • Write-heavy workloads - Reads are infrequent
  • Append-only patterns - Always reading latest data

Terminal window
nodetool getcolumnindexsize

Sample output:

Current value for column_index_size: 64 KiB
Terminal window
nodetool setcolumnindexsize 64

Optimize for Large Partition Point Queries

Section titled “Optimize for Large Partition Point Queries”
Terminal window
# More granular indexing for faster point lookups
nodetool setcolumnindexsize 16
Terminal window
# Fewer index entries to reduce memory footprint
nodetool setcolumnindexsize 128
set_column_index_based_on_data.sh
#!/bin/bash
# Get partition statistics
avg_partition_size=$(nodetool tablestats my_keyspace.my_table 2>/dev/null | \
grep "Average partition size" | awk '{print $5}')
echo "Average partition size: $avg_partition_size bytes"
# Recommend setting based on partition size
if [ "$avg_partition_size" -gt 10000000 ]; then # > 10 MB
echo "Large partitions detected. Recommend: 16-32 KB"
nodetool setcolumnindexsize 32
elif [ "$avg_partition_size" -lt 50000 ]; then # < 50 KB
echo "Small partitions detected. Recommend: 128-256 KB"
nodetool setcolumnindexsize 128
else
echo "Medium partitions. Default 64 KB is appropriate."
nodetool setcolumnindexsize 64
fi

New SSTables Only

Changes to the column index size only affect newly written SSTables. Existing SSTables retain their original column index structure until they are compacted or rewritten.

SSTablesAffected?How to Apply New Setting
New writesYesImmediate
Existing SSTablesNoRun major compaction or upgradesstables
Compaction outputYesNew SSTables use new setting
Terminal window
# Change setting
nodetool setcolumnindexsize 32
# Force rewrite of all SSTables (resource intensive!)
nodetool upgradesstables -a my_keyspace my_table
# Or wait for natural compaction to gradually apply
AspectImpact
Immediate disk I/ONone
Immediate memoryNone
Future writesMinimal
Future compactionsDifferent index structure
Future readsDepends on direction of change

compare_read_latency.sh
#!/bin/bash
KEYSPACE="$1"
TABLE="$2"
echo "=== Before Change ==="
nodetool getcolumnindexsize
nodetool tablestats $KEYSPACE.$TABLE | grep -E "Local read latency|SSTable count"
echo ""
echo "Record these values, make the change, run some reads, then compare."
Terminal window
# Check index file sizes
find /var/lib/cassandra/data/my_keyspace/my_table-* -name "*Index.db" -exec ls -lh {} \;
# Sum of index files
find /var/lib/cassandra/data/my_keyspace/my_table-* -name "*Index.db" -exec du -ch {} + | tail -1
Terminal window
# View index summary memory
nodetool info | grep -i "index"
# Detailed table statistics
nodetool tablestats my_keyspace.my_table | grep -i "memory"

The column index size can also be set in cassandra.yaml for persistence across restarts. The parameter name varies by version:

Cassandra VersionParameter NameExample
Pre-4.1column_index_size_in_kb64
4.1+column_index_size64KiB
# cassandra.yaml (4.1+)
column_index_size: 64KiB
# cassandra.yaml (Pre-4.1)
# column_index_size_in_kb: 64

Comparison:

MethodPersistenceRestart RequiredScope
nodetool setcolumnindexsizeUntil restartNoSingle node
cassandra.yamlPermanentYes (for change)Configured nodes

Best Practice

Use nodetool setcolumnindexsize to test changes, then update cassandra.yaml once the optimal value is determined. This ensures the setting survives restarts.


Terminal window
# Get partition statistics for the table
nodetool tablestats my_keyspace.my_table | grep -E "partition|size"

Look for:

  • Average partition size: Main indicator for tuning
  • Maximum partition size: Identifies outliers
  • Number of partitions: Context for decision
Terminal window
# Baseline read latency
nodetool tablestats my_keyspace.my_table | grep "Local read latency"
Terminal window
# Based on analysis, adjust the setting
nodetool setcolumnindexsize <new_value>

Either wait for natural writes/compaction, or force it:

Terminal window
# Force flush to create new SSTable with new setting
nodetool flush my_keyspace my_table
Terminal window
# After some reads occur with new SSTables
nodetool tablestats my_keyspace.my_table | grep "Local read latency"

Update cassandra.yaml:

column_index_size_in_kb: <new_value>

ValueUse Case
16 KBVery large partitions (> 100 MB), frequent point queries
32 KBLarge partitions (10-100 MB), mixed query patterns
64 KB (default)General purpose, balanced workloads
128 KBSmall partitions, memory-constrained nodes
256 KBVery small partitions, minimal read requirements

Terminal window
# Verify the setting was applied
nodetool getcolumnindexsize
# Remember: only affects NEW SSTables
# Check when SSTables were created
ls -la /var/lib/cassandra/data/my_keyspace/my_table-*/
# Force new SSTables
nodetool flush my_keyspace my_table

If read latency increased after raising the threshold:

Terminal window
# Revert to smaller value
nodetool setcolumnindexsize 64
# Force recompaction with new setting
nodetool compact my_keyspace my_table

If memory usage increased after lowering the threshold:

Terminal window
# Increase threshold to reduce index entries
nodetool setcolumnindexsize 128
# May need to recompact to apply to existing data
nodetool compact my_keyspace my_table
Terminal window
# Check partition sizes
nodetool tablestats my_keyspace.my_table
# Output includes:
# - Average partition size (bytes)
# - Maximum partition size (bytes)
# Rule of thumb:
# < 100 KB average: Small partitions (consider larger threshold)
# 100 KB - 10 MB average: Medium partitions (default is fine)
# > 10 MB average: Large partitions (consider smaller threshold)

Column Index Size Guidelines

  1. Start with default - 64 KB works well for most workloads
  2. Measure before changing - Get baseline latency and memory metrics
  3. Test in staging - Validate changes before production
  4. Change gradually - Don't jump from 64 KB to 16 KB; try 32 KB first
  5. Monitor after change - Watch read latency and memory usage
  6. Make permanent - Update cassandra.yaml once optimal value found
  7. Document the reason - Record why a non-default value was chosen

Cautions

  • Don't optimize prematurely - Only tune if measurements indicate a problem
  • Consider compaction impact - Changing requires compaction to apply to all data
  • Memory vs latency trade-off - Smaller threshold uses more memory
  • Per-node setting - Must be set on each node individually

When to Leave at Default

The default 64 KB is appropriate for most Cassandra deployments. Consider tuning only when:

  • Read latency is unacceptably high on wide partition queries
  • Memory is severely constrained and index overhead is significant
  • Monitoring clearly shows partition index as a bottleneck

CommandRelationship
getcolumnindexsizeView current threshold
tablestatsCheck partition sizes and read latency
compactForce compaction to apply new setting
upgradesstablesRewrite all SSTables with new setting
flushForce memtable flush to create new SSTable
infoView memory usage including indexes