Field Types
ConvergeDB supports a fixed set of field types. Scalar and fixed-length types are stored inline within the entity row. Variable-length types (arrays, VarString, VarBytes) use a two-zone layout where only the actual data is stored, avoiding wasted space.
Scalar types
Section titled “Scalar types”| ConvergeDB type | C# type | Size (bytes) | Range |
|---|---|---|---|
u8 | byte | 1 | 0 to 255 |
u16 | ushort | 2 | 0 to 65,535 |
u32 | uint | 4 | 0 to 4,294,967,295 |
u64 | ulong | 8 | 0 to 2^64-1 |
u128 | UInt128 | 16 | 0 to 2^128-1 |
i8 | sbyte | 1 | -128 to 127 |
i16 | short | 2 | -32,768 to 32,767 |
i32 | int | 4 | -2^31 to 2^31-1 |
i64 | long | 8 | -2^63 to 2^63-1 |
f32 | float | 4 | IEEE 754 single |
f64 | double | 8 | IEEE 754 double |
bool | bool | 1 | true or false |
String types
Section titled “String types”ConvergeDB offers two string storage strategies: variable-length (default) and fixed-length (opt-in).
VarString (default)
Section titled “VarString (default)”string fields default to VarString storage. Only the actual UTF-8 byte length is stored, using the two-zone layout: a 4-byte directory entry in the fixed zone and packed byte data in the data zone.
[Field(0, MaxLength = 256)] public string Bio { get; set; }This maps to VarString(256) on the server. A 20-character bio uses roughly 24 bytes, not 258.
Fixed-length String
Section titled “Fixed-length String”For short, predictable strings (currency codes, tags, identifiers), you can opt into fixed-length inline storage with FixedLength = true. This reserves 2 + MaxLength bytes in every entity row regardless of actual content.
[Field(0, MaxLength = 4, FixedLength = true)] public string CurrencyCode { get; set; }This maps to String(4) on the server. Every entity reserves 6 bytes (2-byte length prefix + 4 bytes).
When to use which
Section titled “When to use which”| Use VarString (default) when | Use FixedLength when |
|---|---|
| Content length varies widely | Content length is predictable and short |
| MaxLength is large (> ~32 bytes) | MaxLength is small (< ~16 bytes) |
| Most entities use a fraction of MaxLength | Most entities use close to MaxLength |
Byte array types
Section titled “Byte array types”The same two strategies apply to byte[] fields.
VarBytes (default)
Section titled “VarBytes (default)”[Field(0, MaxLength = 1024)] public byte[] Payload { get; set; }Maps to VarBytes(1024). Only actual byte length is stored.
Fixed-length Bytes
Section titled “Fixed-length Bytes”[Field(0, MaxLength = 16, FixedLength = true)] public byte[] Hash { get; set; }Maps to Bytes(16). Reserves 2 + 16 = 18 bytes inline in every entity row.
Summary table
Section titled “Summary table”| ConvergeDB type | C# declaration | Storage | Zone |
|---|---|---|---|
VarString(max_len) | [Field(N, MaxLength = X)] string | Actual byte length only | Data zone |
String(max_len) | [Field(N, MaxLength = X, FixedLength = true)] string | 2 + max_len bytes always | Fixed zone |
VarBytes(max_len) | [Field(N, MaxLength = X)] byte[] | Actual byte length only | Data zone |
Bytes(max_len) | [Field(N, MaxLength = X, FixedLength = true)] byte[] | 2 + max_len bytes always | Fixed zone |
The maximum allowed value for MaxLength is 65,535 bytes. MaxLength is always in bytes, not characters (UTF-8 is variable-width).
Composite types
Section titled “Composite types”Structs
Section titled “Structs”Struct fields allow one level of nesting. Define a sub-struct with [ConvergenceStruct]:
[ConvergenceStruct]public partial struct Position{ [Field(0)] public float X { get; set; } [Field(1)] public float Y { get; set; } [Field(2)] public float Z { get; set; }}Sub-struct fields may only contain scalars, fixed-length strings, or fixed-length bytes. VarString, VarBytes, nested structs, and arrays within structs are not supported.
See Structs and Arrays for full details.
Arrays
Section titled “Arrays”Array fields hold a variable number of elements up to a declared maximum:
[ConvergenceEntity("Inventory")]public partial struct Inventory{ [Field(0, MaxCount = 50)] public ulong[] SlotIds { get; set; }
public ReadOnlyMemory<byte> EntityId { get; init; }}Supported element types include all scalars, fixed-length strings, fixed-length bytes, and [ConvergenceStruct] types. Arrays of arrays are not supported.
The maximum element count is 1024. See Limits.
Two-zone layout
Section titled “Two-zone layout”Fields that use variable-length storage (arrays, VarString, VarBytes) use a two-zone row layout:
- Fixed zone — scalars, fixed-length strings/bytes, structs, and a 4-byte directory entry per variable-length field. This zone has a constant size per kind.
- Data zone — packed variable-length data for arrays, VarString, and VarBytes. Only actual content is stored.
For kinds with no variable-length fields, the data zone is empty and there is zero overhead.
Zero defaults
Section titled “Zero defaults”All fields default to zero bytes when an entity is created or when a new field is added to an existing kind. This means:
- Numeric types default to
0 - Booleans default to
false - Strings default to empty (
"") - Byte arrays default to empty
- Arrays default to zero elements