Data types
This section describes the data types supported by YTsaurus and the way they are described in the schema and represented in the formats.
Overview
YTsaurus supports a number of primitive types:
string;integer;boolean;float;double;date;datetime;timestamp;interval.
As well as the following composite (complex) types:
optional;list;struct;tuple;variant;tagged.
You can use one of the following two methods to specify a type in a table schema:
- Using the
typeand (optionally) therequiredkeys: historically, the first method but it is only good for defining primitive or optional primitive types. - Using the
type_v3key.
The type key always expects a string.
The type_v3 key expects either a string for primitive types or a YSON dictionary.
A YSON dict always has the type_name key that stores the type name.
The remaining keys depend on the specific type and are described below.
Describing types in a schema
Primitive types
You can define primitive types in a schema both using the type and the type_v3 keys.
If primitive type T is defined using type, YTsaurus will additionally check the required key in the schema:
required=%true— the column will have a strictly defined type. TheNullvalue or a missing value is not allowed;required=%false— the column will have theoptional<T>type, allowing all primitive type values and theNullvalue.
The table lists the supported types and their representation in the type/type_v3 keys.
| Description | Representation in type |
Representation in type_v3 |
|---|---|---|
an integer belonging to the range [-2^63, 2^63-1] |
int64 |
int64 |
an integer belonging to the range [-2^31, 2^31-1] |
int32 |
int32 |
an integer belonging to the range [-2^15, 2^15-1] |
int16 |
int16 |
an integer belonging to the range [-2^7, 2^7-1] |
int8 |
int8 |
an integer belonging to the range [0, 2^64-1] |
uint64 |
uint64 |
an integer belonging to the range [0, 2^32-1] |
uint32 |
uint32 |
an integer belonging to the range [0, 2^16-1] |
uint16 |
uint16 |
an integer belonging to the range [0, 2^8-1] |
uint8 |
uint8 |
| an 8-byte floating-point number according to IEEE 754 | double |
double |
| a 4-byte floating-point number according to IEEE 754 | float |
float |
standard Boolean type true/false |
boolean |
bool (different from type) |
| a random sequence of bytes | string |
string |
| a proper UTF8 sequence | utf8 |
utf8 |
| a string that contains a valid JSON | json |
json |
| UUID, a random 16-byte sequence (stored in binary representation) | uuid |
uuid |
an integer in the range [-53375809, 53375808 - 1], represents the number of days from the Unix epoch; the representable time range is about 145,000 years into the past and into the future see the section about temporal types |
date32 |
date32 |
an integer in the range [-53375809 * 86400, 53375808 * 86400 - 1], represents the number of seconds from the Unix epoch; the representable time range is about 145,000 years into the past and into the future see the section about temporal types |
datetime64 |
datetime64 |
an integer in the range [-53375809 * 86400 * 10^6, 53375808 * 86400 * 10^6 - 1], representing the number of microseconds elapsed since the Unix epoch; the representable time range extends approximately 145,000 years into the past and future see the section on temporal types |
timestamp64 |
timestamp64 |
an integer in the range [-9223339708800000000, 9223339708800000000], represents the number of microseconds between two timestamp64 timestamps see the section about temporal types |
interval64 |
interval64 |
an integer in the range [0, 49673 - 1], represents the number of days from the Unix epoch; representable date range: [1970-01-01, 2105-12-31] see the section about temporal types |
date |
date |
an integer in the range [0, 49673 * 86400 - 1], represents the number of seconds from the Unix epoch; representable time range: [1970-01-01T00:00:00Z, 2105-12-31T23:59:59Z] see the section about temporal types |
datetime |
datetime |
an integer in the range [0, 49673 * 86400 * 10^6 - 1], represents the number of microseconds from the Unix epoch; representable time range: [1970-01-01T00:00:00Z, 2105-12-31T23:59:59.999999Z] see the section about temporal types |
timestamp |
timestamp |
an integer in the range [- 49673 * 86400 * 10^6 + 1, 49673 * 86400 * 10^6 - 1], represents the number of microseconds between two timestamp timestamps see the section about temporal types |
interval |
interval |
(experimental, do not use in production) type date with time zone information see the section about time zones |
tz_date | tz_date |
(experimental, do not use in production) type datetime with time zone information see the section about time zones |
tz_datetime | tz_datetime |
(experimental, do not use in production) type timestamp with time zone information see the section about time zones |
tz_timestamp | tz_timestamp |
(experimental, do not use in production) type date32 with time zone information see the section about time zones |
tz_date32 | tz_date32 |
(experimental, do not use in production) type datetime64 with time zone information see the section about time zones |
tz_datetime64 | tz_datetime |
(experimental, do not use in production) type timestamp64 with time zone information see the section about time zones |
tz_timestamp64 | tz_timestamp64 |
| an arbitrary YSON structure, physically represented as a byte sequence, cannot have the required=%true attribute |
any |
yson (different from type) |
a system singular type that can only contain null (creating a separate column with this type makes no sense; we don't expect to see this type in user tables, but it's useful for YQL integration) |
null |
null |
a singular type whose only possible value is null; this type is distinct from null (creating a separate column of this type is not particularly useful, and we do not expect this type to appear in user tables, but it is useful for YQL integration) |
void |
void |
Schema example:
type_v3=utf8
type_v3=bool
type_v3=yson
Temporal types
Temporal types in YTsaurus are categorized into two groups. Historically, the first ones to appear in the system were date, datetime, timestamp, and interval. They are used to represent times from the beginning of 1970 to the end of 2105. They were followed by date32, datetime64, timestamp64, and interval64. These types can be used to represent times over a wider range, about 145,000 years into the past and into the future. We recommend using the latter types, because they have a wider range of values.
All dates and times assume the Gregorian calendar. When working with points in time in the distant past, keep in mind that YTsaurus does not account for the adoption of the Gregorian calendar, which occurred at different times in different countries. YTsaurus assumes that the Gregorian calendar has always been used.
Time zones
Warning: support for the data types described in this section is incomplete and will likely change in a backward-incompatible way in the future. These types must not be used in production workflows.
Types tz_timestamp64, tz_datetime64, tz_date32, tz_timestamp, tz_datetime, and tz_date store time information incorporating time zone details. Logically, these types store the pair:
- a timestamp represented by an integer of the corresponding "timezone-free" type; the number represents a point in time in the UTC
- The time zone id, an unsigned 16-bit number (see the list of time zones; numbering is zero-based:
"GMT"= 0,"Europe/Moscow"= 1).
The internal representation of values for these types is described below. Certain higher-level tools offer a convenient way to work with these types.
|
tz type |
corresponding "no time zone" type |
underlying integer type |
integer type value range |
unit |
|
tz_date |
date |
Uint16 |
|
days |
|
tz_datetime |
datetime |
Uint32 |
|
seconds |
|
tz_timestamp |
timestamp |
Uint64 |
|
microseconds |
|
tz_date32 |
date32 |
Int32 |
|
days |
|
tz_datetime64 |
datetime64 |
Int64 |
|
seconds |
|
tz_timestamp64 |
timestamp64 |
Int64 |
|
microseconds |
This pair is serialized into a string as follows:
- The timestamp is written in presorted representation (see below).
- The time zone id is written in presorted representation (see below).
The presorted representation of an integer is obtained as follows:
- The number is written in big-endian format.
- If the number has a signed type, the most significant (sign) bit is inverted. Otherwise, this step is skipped.
Example. To store the point in time 2025-01-01T00:00:00 in the Moscow time zone using the tz_datetime64 type, follow these steps:
- Convert this point in time to UTC. The result is
2024-12-31T21:00:00Z. - Convert the UTC time to a Unix timestamp. The result is
1735678800. - Write this timestamp in big-endian representation. The result is
"\x00\x00\x00\x00\x67\x74\x5b\x50". - Because the
tz_datetime64type is based on the signedInt64type, invert the most significant bit. The result is"\x80\x00\x00\x00\x67\x74\x5b\x50". - Convert the
"Europe/Moscow"time zone name to its id. The result is1. - Write the id in big-endian representation. The result is
"\x00\x01". - Append the time zone id to the timestamp. The result is
"\x80\x00\x00\x00\x67\x74\x5b\x50\x00\x01".
Decimal
The values of type decimal(p, s) are real numbers with the specified precision.
To define this type in a schema, specify the following keys:
type_name: value ofdecimal.precision: total number of decimal digits in a numeric value,precisionmust be in the range[1, 35].scale: number of digits to the right of the decimal point in a numeric value,scalemust be in the range[0, precision].
Schema example:
type_v3={
type_name=decimal;
precision=10;
scale=2;
}
The values 3.14, -2.71, 9.99 may be of type decimal(3, 2) (precision=3, scale=2).
The type supports a number of special values, such as nan, +inf, -inf.
Description of binary representation
decimal numbers have a special binary representation,
which is used by default in many formats, such as yson.
For the purposes of this representation, the values of decimal(p, s) types are maintained as binary strings. Binary string length
depends on precision.
| Precision | Number of bits in the representation | Number of bytes in the representation |
|---|---|---|
| 1-9 | 32 | 4 |
| 10-18 | 64 | 8 |
| 19-38 | 128 | 16 |
| 39-76 | 256 | 32 |
You need to perform the following steps to obtain a binary representation of a decimal number. These steps will be illustrated with the values 3.1415, -2.7182 of type decimal(5, 4).
- Take an integer made up of the value's digits. The number of bits is taken from
precisionin the table above. In this example, 32-bit numbers31415,-27182. - Write the number as a big-endian sequence. In this example, the strings are
\x00\x00\x7A\xB7,\xFF\xFF\x95\xD2. - Invert the most significant bit. In this example, the strings are
\x80\x00\7A\xB7,\x7F\xFF\x95\xD2.
The integer representations of the special values of nan, +inf, -inf for the first step are shown in the table below:
| Special value | Integer representation |
|---|---|
nan |
INT_MAX |
+inf |
INT_MAX - 1 |
-inf |
- INT_MAX + 1 |
Please note
Currently, YQL supports only decimal values with a precision of 35 or less.
Optional type
The optional<T> type means that a value may be of type T or be empty.
Please note
Each use of optional for a type adds new values.
For instance, optional<optional<bool>> may take on the following values:
- The external
optionalis empty. - The external
optionalis non-empty, and the internal one is empty. - all
optionalvalues are set, with the valuetrueorfalse.
Legacy columns containing the type=T;required=false attributes correspond to type optional<T> defined using type_v3.
To define type optional, specify the keys below:
type_name: value ofoptional.item: element type description.
Schema example:
type_v3={
type_name=optional;
item=string;
}
type_v3={
type_name=optional;
item={
type_name=optional;
item=bool;
}
}
List
Values of type list<T> are lists of elements of type T.
To define the type in the schema, specify the keys below:
type_name: value oflist.item: element type description.
Schema example:
type_v3={
type_name=list;
item=string;
}
type_v3={
type_name=list;
item={
type_name=list;
item=double;
}
}
Struct
A collection of named fields with specified value types.
To define this type in a schema, specify the following keys:
type_name: value ofstruct.members: list of dictionaries with keys:name: field name, must be a non-empty utf8 string.type: field type.
Schema example:
type_v3={
type_name=struct;
members=[
{
name=foo;
type=int32;
};
{
name=bar;
type={
type_name=optional;
item=string;
}
};
]
}
Tuple
A collection of unnamed fields of certain predefined types.
To define this type, you need to specify the following keys in the schema:
type_name: value oftuple.elements: list of dictionaries with keys:type: element type.
Schema example:
type_v3={
type_name=tuple;
elements=[
{
type=double;
};
{
type=double;
};
]
}
Variant
Variant is strictly a single value from a defined collection of types.
A variant may be of one of two types:
- Variant over struct. Each type has a name (as in a struct), and each variant value is labeled with the name of the relevant variant element value.
- Variant over a tuple. In this case, all elements are unnamed, and each value is identified by an index.
To define this type, specify the following keys in a schema:
type_name: value ofvariant.elementsormembers(not both): the keys have a structure similar to these keys intuple/struct:
elements: for the option with unnamed elements with the key itself containing a list of dictionaries with keys:type: element type.
members: for the option with named elements with the key itself containing a list of dictionaries with keys:name: element name, must be a non-empty utf8 string.type: description of element type.
Schema example:
type_v3={
type_name=variant;
members=[
{
name=int_field;
type=int64;
};
{
name=string_field;
type=string;
};
]
}
type_v3={
type_name=variant;
elements=[
{
type=int32;
};
{
type=string;
};
{
type=double;
};
]
}
Dict
A dict is a sequence of key/value pairs.
YTsaurus does not check the keys for uniqueness or order.
However, most clients will upload data to an actual dictionary while processing, and the value for non-unique keys will be lost.
To define this type, specify the following keys in a schema:
type_name: value ofdict.key: description of key type.value: value type description.
Schema example:
type_v3={
type_name=dict;
key=int64;
value={
type_name=optional;
item=string;
};
}
Tagged
The tagged type helps annotate other types with a string. Any value of type T can serve as a value for type tagged<TAG_NAME,T>,
however, the types themselves will be considered different wherever YTsaurus compares schemas. For instance, when the possibility of merging two tables into one is being checked.
To define this type, specify the following keys in a schema:
type_name: value oftagged.tag: tag name, must be a non-empty utf8 string.item: element type description.
Media in the web UI
The web UI can display images and play audio when viewing a table or YQL query results in Query Tracker. To enable this, set the column type to tagged<string> via type_v3, and specify the media tag in the tag field:
type_v3={
type_name=tagged;
tag="image/svg";
item="string";
}
The image/svg value indicates that the column contains a Base64-encoded SVG image. For other supported media types, select a tag value from the table:
Value of the tag field |
Cell content | Notes |
|---|---|---|
image/svg image/svg+xml image/jpeg image/png image/gif image/webp |
Base64-encoded image | The value must contain a Base64 string without the Data URL prefix |
imageurl |
Image URL | The web UI loads data only from addresses allowed by the administrator in the uiSettings.reUnipikaAllowTaggedSources parameter of the UI configuration. If the address is not allowed, the URL is displayed as text |
audio/mpeg audio/webm audio/wav |
Base64-encoded audio | The value must contain a Base64 string without the Data URL prefix |
audiourl |
Audio URL | The web UI loads data only from addresses allowed by the administrator in the uiSettings.reUnipikaAllowTaggedSources parameter of the UI configuration. If the address is not allowed, the URL is displayed as text |
Current limitations
- The web UI does not display images or play audio from Cypress nodes of the
filetype. These features are available only for table columns. - The web UI currently cannot play video from either table columns or Cypress nodes of the
filetype.
Limits
Two limits apply when viewing a table in the web UI:
|
Limit |
When it applies |
Value |
|
Cell data loading limit |
When opening a table, as the UI loads the values of all cells on the page |
1 KiB by default, up to 64 KiB. Can be changed |
|
Media preview limit |
When clicking the preview button , as the UI loads a single value in full |
16 MiB. Cannot be changed |
Cell data loading limit. The web UI limits the amount of data downloaded from each table cell to avoid loading large values into memory along with the entire page. By default, this limit is 1 KiB and applies to all values, including Base64 strings.
If the size of a Base64 string exceeds the current cell data loading limit, the UI receives only part of the value, marks it as incomplete, and displays a preview button in the cell. To view the image, click this button:

Media preview limit. A separate limit of 16 MiB applies to the size of the Base64 string used for previews. It applies to the encoded value in the cell, not to the size of the original file.
If the string exceeds this limit, you cannot view the image or play the audio. This limit cannot be changed in the settings.
Note
If there is no preview button, the absence of the image or audio is not caused by incomplete loading. Verify that the Base64 value is valid and that the data matches the specified tag.
Thus, media data within the cell limit (1 KiB by default, up to 64 KiB) is displayed immediately; data above the cell limit and up to 16 MiB is displayed after you click the preview button ; and data larger than 16 MiB is not displayed.
Example
In this example, you will create a table with a column for a PNG image. You will then write the YTsaurus logo to it in Base64 and verify the result in the web interface.
-
Save the YTsaurus logo to the current directory as
logo.png. -
Create the
//tmp/tagged-mediatable with a column for a PNG image:$ yt create table --attributes '{ schema=[ {name=image; type_v3={item=string; type_name=tagged; tag="image/png"}}; ] }' //tmp/tagged-media -
Encode the image contents in Base64 without the Data URL prefix and write the string to the table:
$ IMAGE_BASE64=$(base64 < logo.png | tr -d '\r\n') $ printf '{"image":"%s"}\n' "$IMAGE_BASE64" \ | yt write-table --format json //tmp/tagged-media -
Open the
//tmp/tagged-mediatable in the web interface. Theimagecolumn should display the YTsaurus logo.
Representing compound types in formats
Formats are used to read and write tables.
Some formats do not support composite data, and some, such as dsv / schemaful_dsv, will return an error in response to an attempt to read a composite value. For example, Values of type "any" are not supported by the chosen format.
YSON
There are two YSON representations of composite types. The representations of the struct and variant types differ:
the default representation is more convenient to use,
while the alternative representation is somewhat more efficient for storage and processing.
You can switch between representations using the complex_type_mode flag. Possible values: named / positional.
Type representation descriptions are provided below. Unless otherwise specified, the type representation does not depend on the complex_type_mode setting.
The dict type with string keys has two representations. By default, the positional representation is used as a list (because this is how data is stored in YTsaurus). For readability, you can enable named mode using the string_keyed_dict_mode flag.
Primitive types
Primitive types have a linear representation as a single YSON value.
The table shows a mapping between the primitive and the YSON types.
type / type_v3 |
YSON representation |
|---|---|
int64 |
signed number |
int32 |
signed number |
int16 |
signed number |
int8 |
signed number |
uint64 |
unsigned number |
uint32 |
unsigned number |
uint16 |
unsigned number |
uint8 |
unsigned number |
double |
floating point number |
boolean / bool |
boolean value |
string |
string |
utf8 |
string |
date |
unsigned number, see below |
datetime |
unsigned number, see below |
timestamp |
unsigned number, see below |
interval |
signed number |
uuid |
string with binary data, see below |
any / yson |
value-dependent |
null |
# |
void |
# |
Time types
The YSON format has a time_mode option that controls the representation of the date, datetime, and timestamp types. Its possible values are:
binary(default) — uses an unsigned number representing the number of days / seconds / milliseconds since the Unix epoch.text— uses a string representation. The representations ofdate,datetime, andtimestampare as follows, respectively:
2022-01-02,2022-01-02T03:04:05Z,2022-01-02T03:04:05.123456Z.
UUID
The YSON format has a uuid_mode option that controls the representation of the uuid type. Its possible values are:
binary(default) — uses a 16-byte binary representation.text_yt— uses a string representation in the YTsaurus format consisting of 4 groups, for example,61626364-65666768-696a6b6c-6d6e6f70;text_yql— uses a string representation in the YQL format consisting of 5 groups and more closely resembling the RFC representation, for example,64636261-6665-6867-696a-6b6c6d6e6f70.
Decimal
The YSON format has a decimal_mode option that controls the representation of the decimal type. Its possible values are:
binary(default) — encoded as a binary string containing the binary representation of adecimalnumber.text— uses the textual representation of adecimalnumber.
Optional
The representation of the optional type depends on its inner type.
This is required for backward compatibility with columns that have required=%false set.
If T is an arbitrary type other than optional, then optional<T> is represented as follows:
Nullvalue ofoptionalis represented as#;- otherwise, the standard representation of a value of type
Tis used.
If T is an optional type, then optional<T> is represented as follows:
Nullvalue of the outeroptionalis represented as#;- otherwise, the
[ v ]representation is used (a YSON list of length 1), wherevis the YSON representation of a value of typeT.
Example values of type optional<int64>:
#
-42
Example values of type optional<optional<int64>>:
#
[ # ]
[ -42 ]
List
The list<T> type is encoded as a YSON list whose elements are encoded representations of elements of type T.
Example values of type list<int64>:
[]
[42; -1;]
Struct
The structure representation depends on the value of the complex_type_mode flag.
Named representation (default)
The representation described here applies when the YSON format option
complex_type_mode is not set or is set to complex_type_mode=named.
The struct is represented by a YSON dictionary where field names serve as keys and the contents of these fields are the values.
Example values for the struct<Foo:int64;Bar:optional<utf8>> type:
{Foo=42;Bar=#;}
{Foo=-5;Bar="minus five";}
Positional representation
If the YSON format option complex_type_mode=positional is set, a different representation is used.
A struct is encoded as a YSON list with the i-th position containing a YSON representation of the struct's i-th field.
The list may be shorter than the number of fields in the structure. In this case, the remaining types must be of type optional<T>,
and the fields are considered to have an empty optional value.
Example values for the struct<Foo:int64;Bar:optional<utf8>> type:
[42; #;]
[42]
[-5;"minus five";]
Tuple
The tuple type is encoded as a fixed-length YSON list. The i-th position contains the i-th field's encoded value.
Example values for the tuple<int64;optional<utf8>> type:
[42; #;]
[-5;"minus five";]
Variant
Unnamed variant
The unnamed option is represented by a YSON list of length 2 that includes the following elements:
- Alternative number (indexed at 0).
- An encoded value for the relevant alternative.
Example values for the variant<int64;optional<utf8>> type:
[0; 42]
[1; #]
[1; "foo bar";]
Named variant option
Named representation (default)
The representation described here applies when the YSON format option complex_type_mode is not set or is set to complex_type_mode=named.
The named option is represented by a YSON list of length 2 that includes the following elements:
- Alternative name.
- An encoded value for the relevant alternative.
Example values for the variant<Foo:int64;Bar:optional<utf8>> type:
[Foo; 42]
[Bar; #]
[Bar; "foo bar";]
Positional representation
If the format option complex_type_mode=positional is set.
The named option is represented by a YSON list of length 2 that includes the following elements:
- Index of alternative.
- An encoded value for the relevant alternative.
Example values for the variant<Foo:int64;Bar:optional<utf8>> type:
[0; 42]
[1; #]
[1; "foo bar";]
Dict
By default, the dict type is represented as a YSON list in which each item is a two-item YSON list containing a key and a value.
Example values of the dict<int32;string> type:
[[1;"one"];[4;"four"]]
[]
dict can be represented as a YSON map. However, a YSON map supports only strings as keys, whereas dict also supports other key types.
Dict with string keys
The representation of a dictionary with string keys depends on the value of the string_keyed_dict_mode flag.
Positional representation (default)
The representation described here applies when the YSON format option string_keyed_dict_mode is not set or is set to string_keyed_dict_mode=positional.
See above
Example values of the dict<string;int32> type:
[["one";1];["four";4]]
Named representation
If the YSON format option string_keyed_dict_mode=named is set, a different representation is used.
dict is encoded as a YSON map.
Example values of the dict<string;int32> type:
{one=1; four=4}
Tagged
The tagged type does not change the YSON representation of its element.
To change the default limit, open Settings → Table → Cell size limit. To change the limit for the current table, click the gear icon above the table.