SpacetimeDB Data Types Supported: A Complete Guide to SATS and Rust Type Mapping
SpacetimeDB supports all Rust primitives, standard collections like Vec<T> and Option<T>, and user-defined structs or enums by mapping them to the Spacetime Algebraic Type System (SATS) via the SpacetimeType trait.
SpacetimeDB stores Rust values in database tables by translating them into SATS (Spacetime Algebraic Type System) representations. Any Rust type that implements the SpacetimeType trait—whether primitive, generic, or custom—can be used as a table column or reducer argument. This article covers every data type supported by SpacetimeDB based on the implementation in clockworklabs/SpacetimeDB.
Primitive Scalar Types Supported
SpacetimeDB provides first-class support for all standard Rust scalar types, including fixed-width integers, floating-point numbers, and strings. These primitives are implemented in crates/sats/src/typespace.rs through the impl_primitives! macro, which maps each Rust type to its corresponding AlgebraicType variant.
The following primitive types are supported:
bool– Maps toAlgebraicType::Bool- Unsigned integers –
u8,u16,u32,u64,u128, andu256(from theethnumcrate) map toU8throughU256 - Signed integers –
i8,i16,i32,i64,i128, andi256(fromethnum) map toI8throughI256 - Floating-point –
f32andf64map toF32andF64 - Strings – Both owned
Stringand borrowed&strmap toAlgebraicType::String
Each primitive implements the SpacetimeType trait directly, allowing immediate use in table schemas without additional boilerplate.
Compound Collection Types
Beyond scalars, SpacetimeDB supports generic collections and nested types through implementations in crates/sats/src/typespace.rs, specifically via the impl_st! macro and specialized trait blocks.
The supported compound types include:
Vec<T>– Represents variable-length arrays of anyTthat implementsSpacetimeType, stored asArray<T>in SATSOption<T>– Represents nullable fields, stored as the SATSOption<T>algebraic typeResult<T, E>– Supported through a customimpl<T,E> SpacetimeType for Result<T,E>block, allowing error types to be serialized
These generic implementations recursively resolve the type of their type parameters, enabling arbitrarily deep nesting such as Vec<Option<u64>> or Option<Vec<String>>.
Custom Structs and Enums via Derive Macros
User-defined types become valid SpacetimeDB columns through the #[derive(SpacetimeType)] macro. This procedural macro, defined in crates/bindings-macro/src/sats.rs, inspects your struct or enum definition and generates the corresponding SATS representation.
The macro distinguishes between two algebraic constructs:
- Product types – Generated for
structdefinitions, mapping fields to named or unnamed product components - Sum types – Generated for
enumdefinitions, mapping variants to sum alternatives with optional payloads
Each variant is represented through the SatsTypeData enum in the macro, distinguishing between Product (struct) and Sum (enum) representations.
SpacetimeDB-Specific Identifier Types
SpacetimeDB defines several domain-specific identifier types that carry special semantic meaning within the database. These are ordinary structs that derive SpacetimeType and are defined in the core library:
Identity– Represents a user's public key (defined incrates/lib/src/identity.rs)ConnectionId– A unique session identifier for active connectionsTimestamp– Logical transaction time for event orderingTimeDuration– Represents elapsed time between eventsUuid– A 128-bit universally unique identifierScheduleAt– Scheduling metadata for timed reducers
These types can be used as primary keys, indexed columns, or reducer arguments just like standard primitives.
Practical Example: Defining Custom Data Types
The following Rust module demonstrates how to combine primitives, collections, and custom types in a SpacetimeDB application:
use spacetimedb::{SpacetimeType, Table, ReducerContext};
/// A point in 2-D space – primitive fields only.
#[derive(SpacetimeType, Clone, Debug)]
pub struct Point {
x: u64,
y: u64,
}
/// An enum that can be stored directly as an index key because it has no payload.
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Direction {
North,
South,
East,
West,
}
/// A richer enum with payloads – each variant may carry its own data.
#[derive(SpacetimeType, Clone, Debug)]
pub enum Message {
Ping,
Pong,
Move { to: Point },
Turn { dir: Direction },
}
/// Table that stores a `Message`. The `#[table(..)]` macro automatically derives `SpacetimeType`.
#[spacetimedb::table]
pub struct MsgLog {
#[primary_key] id: u64,
payload: Message,
}
/// Simple reducer that inserts a new row.
#[spacetimedb::reducer]
pub fn log_message(ctx: &ReducerContext, msg: Message) {
ctx.db.msg_log().insert(MsgLog { id: ctx.new_id(), payload: msg });
}
In this example, Point, Direction, and Message are all valid column types because the derive macro expands them to SATS product or sum definitions. The MsgLog table can be queried, indexed, or filtered like any other table.
Summary
- Primitive coverage – SpacetimeDB supports all Rust scalars from
booltou256/i256, plusStringand&str, implemented viaimpl_primitives!incrates/sats/src/typespace.rs - Generic containers –
Vec<T>,Option<T>, andResult<T,E>work out of the box through theimpl_st!macro and custom trait implementations - User-defined types – Structs and enums derive
SpacetimeTypeto generate SATS product and sum types, processed bycrates/bindings-macro/src/sats.rs - Specialized identifiers –
Identity,Timestamp,Uuid, and related types provide domain-specific semantics for authentication and scheduling - Recursive composition – All types can be nested arbitrarily, allowing complex schemas like enums containing structs containing vectors of primitives
Frequently Asked Questions
What primitive data types does SpacetimeDB support?
SpacetimeDB supports the complete set of Rust primitives: bool, u8 through u256, i8 through i256, f32, f64, and both String and &str. The 256-bit integer types come from the ethnum crate. These are mapped to SATS algebraic types in crates/sats/src/typespace.rs using the impl_primitives! macro.
Can I use custom structs and enums as column types in SpacetimeDB?
Yes. Any struct or enum that derives SpacetimeType can be used as a table column or reducer argument. The derive macro, located in crates/bindings-macro/src/sats.rs, automatically generates the SATS representation as either a product type (for structs) or sum type (for enums).
How does SpacetimeDB handle optional or nullable fields?
Use the standard Rust Option<T> type. SpacetimeDB implements SpacetimeType for Option<T> in crates/sats/src/typespace.rs, mapping it to the SATS Option<T> algebraic type. This allows any column to represent nullability without requiring database-specific wrapper types.
What are SpacetimeDB identifier types and when should I use them?
Identifier types like Identity, ConnectionId, Timestamp, TimeDuration, Uuid, and ScheduleAt are domain-specific structs defined in the SpacetimeDB core library. Use Identity for public keys and user identification, ConnectionId for session tracking, and Timestamp or TimeDuration for temporal logic. These types derive SpacetimeType and can be used as primary keys or indexed columns.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →