Counters in Cassandra

Getting started

In order to use counters in Cassandra you need to first set up a cluster, see the Getting started guide for more information. Also note that counters are available starting with Cassandra 0.8.0.


To use counters, you have to define a column family (or super column family) whose columns will act as counters. To create such a column family counterCF using the CLI, you will have to do:

[default@test] create column family counterCF with default_validation_class=CounterColumnType and replicate_on_write=true;

Setting the default_validation_class to CounterColumnType indicates that the columns will be counters. Setting replicate_on_write=true will be optional starting in 0.8.2, but a bug made it default to false in 0.8.0 and 0.8.1, which is unsafe.

Incrementing and accessing counters

Once the cluster is up and running with these settings you can simply increment or decrement long values from the counters as follows (example is using the python thrift client):

client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', 100), ConsistencyLevel.ONE)
client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', -50), ConsistencyLevel.ONE)

And read it back

rv = client.get('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE).counter_column.value

Please read the rest of this wiki page, especially Technical limitations and Operational considerations to make sure this actually does what you need.


The interface follows the main API. The main differences are:

Internally, the data store generates timestamps on the server to determine priority of deletion.

The new structures for dealing with counters are:

struct CounterColumn {
    1: required binary name,
    2: required i64 value

struct CounterSuperColumn {
    1: required binary name,
    2: required list<CounterColumn> columns

struct ColumnOrSuperColumn {
    1: optional Column column,
    2: optional SuperColumn super_column,
    3: optional CounterColumn counter_column,
    4: optional CounterSuperColumn counter_super_column

where the pre-existing ColumnOrSuperColumn has the two new fields, specific to counters, counter_column and counter_super_column.

Moreover, as mentioned previously, the timestamp field of Deletion is now optional (but remain mandatory for non counter column family operation).

The counter operations comprise the usual batch_mutate, get, get_slice, multiget_slice, multiget_count and get_range_slice (secondary indexes on counter column family is not supported at the moment), as well as the following new operations for access to a single counter:

  # counter methods

   * Increment or decrement a counter.
  void add(1:required binary key,
           2:required ColumnParent column_parent,
           3:required CounterColumn column,
           4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
       throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),

   * Remove a counter at the specified location.
  void remove_counter(1:required binary key,
                      2:required ColumnPath path,
                      3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
      throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),

Technical limitations

Further reading

See CASSANDRA-1072 and especially the design doc for further information about how this works internally (but note that some of the limitations fixed in these technical documents have been fixed since then, for instance all consistency level are supported, for both reads and writes).


Counters (last edited 2013-11-13 20:55:34 by 50)