Developer Infrastructure · Database

IcyDB

Database capabilities for canisters — without losing determinism.

IcyDB is a schema-first persistence and query runtime for Internet Computer canisters. It gives Rust canisters typed entities, stable-memory storage, indexes, fluent queries, and a focused SQL surface, while keeping the security, determinism, and performance decentralized execution demands.

RustSchema-firstStable memoryMIT / Apache-2.0

What it is

Familiar database concepts, deterministic by design

Canisters need structured data, but traditional databases bring joins, hidden execution, and unbounded queries that don't fit a deterministic, resource-metered runtime. IcyDB gives developers typed data models, indexing, querying, and aggregation backed by stable memory — deliberately avoiding joins, subqueries, and hidden plans in favour of bounded, single-entity query models.

Schema macros are the authority: accepted schema snapshots drive row layouts, index catalogs, reconciliation, SQL DDL, and observability. Primary keys can be scalar or composite, and strong relations are explicit and validated at write time.

Capabilities

What IcyDB provides

01

Typed entities & schemas

Schema macros declare canisters, stores, entities, fields, indexes, enums, validators, sanitizers, and explicit relations.

02

Stable-memory storage

Choose one explicit contract per store: durable stable, volatile heap, or journaled cached-stable.

03

Indexes & fluent queries

Secondary, multi-field, unique, filtered, and deterministic expression indexes, with a fluent Rust query API.

04

Reduced single-entity SQL

SELECT, INSERT, UPDATE, DELETE, DDL, aggregates, and introspection — useful for canister-local reads and writes.

05

Pagination & aggregates

Continuation-based pagination and grouped aggregation with HAVING, CASE, and common scalar functions.

06

Built-in observability

Generated observability endpoints, explain tooling, and metrics for deterministic planning and execution.

Query from Rust

Typed, fluent, deterministic

The runtime prelude gives canister code a fluent, typed query builder. With the default sql feature, the same entity is also reachable through reduced single-entity SQL.

rust
use icydb::prelude::*;

pub fn top_users() -> Result<Vec<User>, icydb::Error> {
    db!()
        .load::<User>()
        .filter_eq("active", true)
        .order_desc("score")
        .limit(10)
        .entities()
}

In scope

A focused, canister-friendly SQL subset

  • SELECT, EXPLAIN, DESCRIBE, SHOW
  • INSERT, UPDATE, DELETE with RETURNING
  • CREATE / DROP INDEX, ALTER TABLE
  • WHERE, ORDER BY, LIMIT, OFFSET, DISTINCT
  • Aggregates, grouped aggregates, HAVING, CASE

Out of scope by design

What it deliberately omits

  • Joins and subqueries
  • Common table expressions (CTEs)
  • Window functions
  • Quoted identifiers
  • Broad unbounded pattern matching

Structured data, on-chain

Explore the schema macros, SQL contract, and query practice docs on GitHub.