CQL data types

Data type is declared and enforced for each column in a table.

BLOB type

The blob type stores binary data as Binary Large Objects (BLOBs) of arbitrary bytes (no validation). Values are hexadecimal constants in the format 0xhex or 0Xhex where hex is one or more hex characters ([0-9,a-f,A-F]). For example, 0x0000cafe3.

BLOBs are suitable for small binary payloads (small images or short strings). Storing large BLOBs, such as images or videos, can lead to unbalanced partitions and degraded performance. Therefore, the practical limit and recommended size for BLOBs is less than 1 MB, despite the maximum theoretical size of 2 GB.

For large binary content, store the data in an object store or content delivery network (CDN), and then store the URI in your database instead.

You can use functions to convert between native types and BLOBs:

  • typeAsBlob(value): Accepts a native type value and converts it into a BLOB.

  • blobAsType(value): Accepts a 64-bit BLOB value and attempts to convert it into the specified native type. Replace Type with the desired type, such as blobAsBigint.

For examples of blob functions, see Create a table column.

Boolean type

The boolean type represents a true or false value. Stored internally as true or false, regardless of the original form used for INSERT or UPDATE. When inserting or updating, values are case insensitive and not quoted.

When using the CQL shell COPY TO command to import or export data, you can change the format using the boolstyle option. For example, when importing survey results that have a column of yes/no responses.

Collection types

The collection data types map, list, and set are used to group and store values together in one column. The elements within a collection each have a defined type that you must specify in the table definition.

Use collections to store small amounts of related data, such as phone numbers, tags, or addresses. Collections aren’t appropriate for data that is expected to grow unbounded or data models that require extracting individual values from collections. For unbounded grouping of data, use a table with one or more clustering columns. To extract individual elements, store values in separate columns or a separate table.

For more information about using collections, see Collections in CQL.

Collection data types
Type Constants supported Description

set

n/a

Comma separated list of unique values sorted by position starting at zero.

Supports appending and prepending elements in INSERT and UPDATE statements using the + and - operators if non-frozen.

list

n/a

Comma separated list of non-unique values of the same data type, list[data_type]. Elements are ordered by zero-indexed positions in the list.

Supports appending and prepending elements in INSERT and UPDATE statements using the + and - operators if non-frozen. These operations aren’t idempotent and they can require read-before-write. Implicit retries can result in duplicate appends or prepends. To avoid these issues, use a set or a frozen list (FROZEN<list<type>>) if possible.

map

n/a

Series of key-value pairs where the keys are unique. The map elements are sorted by keys, but they aren’t ordered like lists.

Supports appending and prepending elements in INSERT and UPDATE statements using the + and - operators if non-frozen.

When setting TTL with INSERT or UPDATE, the TTL applies to the newly inserted/updated elements only. To apply a TTL to all elements, you must overwrite the entire map.

Counter

The counter type is used exclusively to store numbers that are updated by increments or decrements, such as page views, games played, or units in inventory. Counter values are 64-bit signed integers that can only be incremented or decremented.

counter columns have the following limitations:

  • You cannot directly set the value of a counter. Instead, you must increment or decrement counter values using the UPDATE command with the + or - operator. This includes the first write to a counter column and all subsequent updates.

  • A counter column cannot be part of a PRIMARY KEY.

  • Tables with counter columns can have only counter columns and PRIMARY KEY columns.

  • You cannot create indexes on counter columns.

  • counter columns must be set when creating a table. You cannot use ALTER TABLE to add a counter to an existing table. If you drop a counter column; you cannot use ALTER TABLE to recreate the dropped column.

  • You cannot set counter values to expire with Time-To-Live (TTL) or USING TIMESTAMP.

  • If nodes go down or writes fail, counter values can be inaccurate because counter operations are non-idempotent and cannot be retried implicitly. Retrying can result in an overcount, but not retrying can result in an undercount, so additional logic must be defined to handle counter write failures and data reconciliation.

Counter-related settings can be set in cassandra.yaml.

For examples, see Create a table column.

Date and time types

Date and time data types are designed for storing time series data or other timestamps.

When writing date and time values, use single quotes around string formatted values, and no quotes for integer values. For example, compare the string format purchase_date = '2017-05-12' to the integer days since epoch format purchase_date = 17298.

Type Constants supported Description

date

strings

32-bit unsigned integer representing the number of days since epoch (January 1, 1970) with no corresponding time value

Insert or update values as an integer (days since epoch) or in string format '<yyyy>-<mm>-<dd>', for example '2017-05-13'.

DateRangeType

strings

DateRangeType is only supported in DSE and HCD.

Similar to the Solr DateRangeField type, it stores a date range in the format [<beginning_date> TO <end_date>]. Insert the custom ranges between square brackets. Truncated timestamps represent the entire date span or use the range syntax to create a custom range. For example:

  • 2018-01: Beginning of the first day to the end of the last day in January 2018.

  • 2018-01T15: Range includes hours of the day from 1500 to before 1600 (3pm to 4pm).

  • [2017-01-15 TO 2017-11-01]: The start of the fifteenth of January through the end of the first day of November.

  • [2017 TO 2017-11-01]: Start of 2017 until the end of the first day of November.

  • [* TO 2018-01-31]: From the earliest representable time through to the end of the day on 2018-01-31.

  • [2017-02-02T14:57:00 TO 2017-02-02T15:10:17]: From 14:57:00 to 15:10:17 on February 2, 2017.

If you specify a date instance using a date function, like currentDate(), you get the first millisecond of that day, not the entire day’s range.

The type name is case sensitive. Enclose the type name in single quotes when creating a table.

duration

strings

Encoded as three signed integers of variable lengths, where the integers represent the number of months, days, and nanoseconds. Provided in one of several possible formats. For details, see Date, time, and timestamp format.

time

strings

Encoded 64-bit signed integers representing the number of nanoseconds since midnight with no corresponding date value.

The insert/update string format is '<hh>:<mm>:<ss>[.<fff>]', where milliseconds (<f>) are optional.

timestamp

strings

64-bit signed integer representing the date and time since epoch (January 1 1970 at 00:00:00 GMT) in milliseconds.

The insert/update string format is ISO-8601; the string must contain the date and optionally can include the time and time zone, '<yyyy>-<mm>-<dd> [<hh>:<MM>:<ss>[.<fff>]][+/-<NNNN>]' where <NNNN> is the RFC 822 4-digit time zone specification (+0000 refers to GMT and US PST is -0800). If no time zone is specified, the client timezone is assumed. For example '2015-05-03 13:30:54.234-0800', '2015-05-03 13:30:54+0400', or '2015-05-03'.

For more information, see Date, time, and timestamp format.

Geospatial types

Geospatial types are useful for storing data that is geometric in nature.

Geospatial type names are case sensitive. Enclose the type name in single quotes when creating a table.

Type Description

PointType

Contains two coordinate values for latitude and longitude.

LineStringType

Comma-separated list of points.

PolygonType

Set of two linestrings.

Numeric types

Numeric types store values of different precision. Choose types that are appropriately precise for the values you need to store. For example, don’t use bigint when int is sufficient.

Enter numeric types in plain text in the INSERT, UPDATE, and the SELECT statement WHERE clause. For example, age = 31.

Integers

Type Constants supported Description

tinyint

integers

8-bit signed integer

smallint

integers

16-bit signed integer

int

integers

32-bit signed integer

bigint

integers

64-bit signed integer

varint

integers

Arbitrary-precision integer

Maps to Java type java.math.BigInteger

Decimals

The default decimal separator is a period (.). Change the decimal separator in the driver settings or using cqlshrc decimalsep option. Internally, the decimal separator is stored as a period.

Type Constants supported Description

decimal

integers, floats

Variable-precision decimal

Supports integers and floats.

When dealing with currency, it is a best practice to have a currency class that serializes to and from an int or to use the decimal form.

Maps to Java type java.math.BigDecimal

float

integers, floats

32-bit IEEE-754 floating point

Maps to Java type java.lang.Float

double

integers, floats

64-bit IEEE-754 floating point

Maps to Java type java.lang.Double

Static keyword

static isn’t a distinct data type. It is a modifier that can be applied to a column of any type.

Static columns apply the same value to all rows in a partition. The columns is static in every partition, but each partition can have a different value that is applied to the rows in that specific partition.

The table must have clustering columns to define static columns. Only non-clustering columns can be marked static, and a static column cannot be part of the partition key.

For an example, see Create a table column.

String and text types

Don’t use string types when another type is more appropriate. For example, don’t use strings to store numbers, and don’t use text to store timestamps.

Wrap strings in single quotes or double dollar signs ($$) in INSERT, UPDATE, and the SELECT statement WHERE clause.

For values that contain single quotes, `, or reserved characters, you must use additional escaping or change the wrapping style. For example, to insert a comment into a text field that contains a single quote and punctuation, wrap the string in ` not ':

INSERT INTO cycling.comments (
  id, created_at, comment
) VALUES (
  e7ae5cf3-d358-4d99-b900-85902fda9bb0,
  currentTimestamp(),
  $$ It's pouring rain, race should have been postponed :'( $$
);

For more information, see Escaping characters.

Type

Constants supported

Description

ascii

strings

US-ASCII characters

text

strings

UTF-8 encoded string

varchar

strings

UTF-8 encoded string

inet

strings

IP address string in IPv4 or IPv6 format

date and time strings

strings

See Date and time types.

Tuple type

The tuple type can store two or more values of the same or different data types in the same column. They are similar to collections and user-defined types (UDTs), but tuples are less strict than collections, and they don’t require defining a custom type at the keyspace level. However, DataStax recommends collections and UDTs over tuples due to the following limitations:

  • Tuples are always frozen, even if you don’t specify the frozen keyword. This means the entire field is overwritten when using INSERT or UPDATE. Therefore, your statements must provide a value for each element in the tuple, and you must explicitly declare null for elements that have no value.

  • You must access elements by position. This can make application development more difficult because you must remember the position at which each type is used and the meaning of each position.

  • During upgrades and migrations, additional steps are required to avoid data loss associated with the tuple type.

If you choose to use tuples, limit their use to simple groupings. When the grouping becomes more complex, consider whether a collection would be more appropriate.

Tuples are fixed-length sets that can accommodate up to 32,768 fields, but a best practice is to use no more than five fields. Additionally, tuples can contain nested tuples, and they can be nested in other data types. For example, both of the following are valid: tuple<int,tuple<text,text>,boolean> and set<tuple<text,inet>>.

For examples, see Create a table column.

Unique identifier types

Use uuid and timeuuid types to represent unique identifiers. They are often used to uniquely identify rows and ensure that each row has a distinct value. For more information, see UUID and timeuuid.

Type Constants supported Description

uuid

uuids

128-bit universally unique identifier (UUID) Generate with the uuid() function.

timeuuid

uuids

128-bit Version 1 UUID; unique identifier that includes a conflict-free timestamp. Generate with the now() function.

User-defined type (UDT)

User-defined types (UDTs) are custom types that are similar to map collections. They must be defined at the keyspace level before being used in a table definition.

Use UDTs judiciously to avoid performance issues and suboptimal data models. For more information, see User-defined type (UDT) overview.

Vector type

Although vector data isn’t exclusively used for vector search, the vector type is required to perform vector search on a column with CQL.

The vector type stores multiple values in a single column as an array of float32 values. Vector arrays are limited to a maximum dimension of approximately 8,000 (213) items.

Deprecated types

The following types are supported for backward compatibility only:

  • custom type: Customized type added as a sub-class to AbstractType where the class name was fully qualified or relative to the org.apache.cassandra.db.marshal package. Replaced by user defined type (UDT).

CQL type conversion compatibility

CQL data types have strict requirements for conversion compatibility.

Some conversions are prevented on clustering columns. Clustering columns have stricter requirements because they mandate the order in which data is written to disk.

Supported data type conversions
Original data type Converted data type Clustering columns Non-clustering columns

ascii, bigint, boolean, decimal, double, float, inet, int, timestamp, timeuuid, uuid, varchar, varint

blob

Not allowed on clustering columns

Allowed on non-clustering columns

int

varint

Allowed on clustering columns

Allowed on non-clustering columns

text

varchar

Allowed on clustering columns

Allowed on non-clustering columns

timeuuid

uuid

Not allowed on clustering columns

Allowed on non-clustering columns

varchar

text

Allowed on clustering columns

Allowed on non-clustering columns

Was this helpful?

Give Feedback

How can we improve the documentation?

© Copyright IBM Corporation 2026 | Privacy policy | Terms of use Manage Privacy Choices

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: Contact IBM