# SpacetimeDB Data Types Supported: A Complete Guide to SATS and Rust Type Mapping

> Discover SpacetimeDB data types including Rust primitives, collections, and custom types. Learn how SATS maps to Rust types for seamless integration.

- Repository: [Clockwork Labs/SpacetimeDB](https://github.com/clockworklabs/SpacetimeDB)
- Tags: api-reference
- Published: 2026-03-09

---

**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`](https://github.com/clockworklabs/SpacetimeDB/blob/main/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 to `AlgebraicType::Bool`
- **Unsigned integers** – `u8`, `u16`, `u32`, `u64`, `u128`, and `u256` (from the `ethnum` crate) map to `U8` through `U256`
- **Signed integers** – `i8`, `i16`, `i32`, `i64`, `i128`, and `i256` (from `ethnum`) map to `I8` through `I256`
- **Floating-point** – `f32` and `f64` map to `F32` and `F64`
- **Strings** – Both owned `String` and borrowed `&str` map to `AlgebraicType::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`](https://github.com/clockworklabs/SpacetimeDB/blob/main/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 any `T` that implements `SpacetimeType`, stored as `Array<T>` in SATS
- **`Option<T>`** – Represents nullable fields, stored as the SATS `Option<T>` algebraic type
- **`Result<T, E>`** – Supported through a custom `impl<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`](https://github.com/clockworklabs/SpacetimeDB/blob/main/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 `struct` definitions, mapping fields to named or unnamed product components
- **Sum types** – Generated for `enum` definitions, 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 in **[`crates/lib/src/identity.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/lib/src/identity.rs)**)
- **`ConnectionId`** – A unique session identifier for active connections
- **`Timestamp`** – Logical transaction time for event ordering
- **`TimeDuration`** – Represents elapsed time between events
- **`Uuid`** – A 128-bit universally unique identifier
- **`ScheduleAt`** – 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:

```rust
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 `bool` to `u256`/`i256`, plus `String` and `&str`, implemented via `impl_primitives!` in [`crates/sats/src/typespace.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/sats/src/typespace.rs)
- **Generic containers** – `Vec<T>`, `Option<T>`, and `Result<T,E>` work out of the box through the `impl_st!` macro and custom trait implementations
- **User-defined types** – Structs and enums derive `SpacetimeType` to generate SATS product and sum types, processed by [`crates/bindings-macro/src/sats.rs`](https://github.com/clockworklabs/SpacetimeDB/blob/main/crates/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`](https://github.com/clockworklabs/SpacetimeDB/blob/main/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`](https://github.com/clockworklabs/SpacetimeDB/blob/main/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`](https://github.com/clockworklabs/SpacetimeDB/blob/main/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.