Ecosystem adapters · Go · Python · TypeScript
Real frameworks.
Zero generic CRUD.
We built out-of-tree RiffDB adapters for four demanding open-source systems: MLflow, LangGraph, OpenFGA, and Better Auth. None of them use SQL, runtime transaction callbacks, or database-side framework plugins. Each compiles the framework’s domain operations into an exact RiffDB contract and dispatches exclusively through generated SDKs.
MLflow
Unifies experiment tracking, out-of-order distributed trace ingestion, pattern search, and columnar trace metrics in one ACID store.
Python · Agent CheckpointsLangGraph
Passes all 8 upstream conformance suites (81 tests) with idempotent superstep writes, atomic thread copy, and bounded pruning.
Go · ReBAC AuthorizationOpenFGA
Passes the complete official OpenFGA datastore suite with compiler-sealed tuple decisions and bytewise changelog pagination.
TypeScript · Identity & SessionsBetter Auth
Compiles configured auth models into atomic signup commands, consume-once verification tokens, and secret-classified credential queries.
MLflow: OLTP, OLAP, and search without the ETL pipeline.
Modern AI observability is a hybrid workload. An MLflow tracking server ingests high-concurrency experiment runs, 100-tag atomic batches, and distributed trace spans that arrive out of order, while simultaneously serving LIKE/ILIKE text search and time-bucketed latency and token aggregations.
On traditional infrastructure, teams pair PostgreSQL for run state with ClickHouse or OpenSearch for trace analytics and maintain fragile CDC pipelines between them. With RiffDB, the entire AbstractStore surface runs against one contract-first engine.
- Out-of-order span ingestion
IngestTraceSpansusesinit_or_mutateacrossTraceandTraceSpanin one partition commit, so child spans can arrive before parent spans orstart_trace()without foreign-key failures or read-time merges. - Zero-ETL trace analytics
query_trace_metricsqueries contract-declared scalar columnar projections (TraceAnalytics,SpanAnalytics,AssessmentAnalytics) and hourly event rollups (SpanModelRollup) with P50/P95/P99 quantiles andmin/max/mean/summeasures. - Indexed pattern and partition-set searchExperiment, run, logged-model, and trace searches compile to bounded RiffQL plans with trigram long-pattern indexes and cross-experiment partition-set execution.
// Columnar OLAP over live traces
columnar_projection TraceAnalytics {
source entity Trace
fields (
experiment_id, timestamp_ms,
execution_time_ms, status
)
}
// Hourly rollup from commits
projection SpanModelRollup {
source event SpanIngested
key (
organization_id,
hour(start_time_utc)
)
measure spans = count()
measure latency = sum(duration_ms)
frontier transactionally_ordered
}LangGraph: Crash-safe state for multi-agent graphs.
Stateful agent workflows fan out parallel tool calls, checkpoint intermediate channel values at every superstep, fork threads for human-in-the-loop branching, and prune historical state. If a network drop triggers a retry mid-step, a naive checkpointer can duplicate channel writes or leave parent-child checkpoint links half-written.
riffdb-langgraph implements both synchronous and asynchronous BaseCheckpointSaver interfaces and passes all eight upstream capability suites in langgraph-checkpoint-conformance.
- Idempotent superstep persistence
putandput_writesexecute as compiled single-partition commands with deterministic idempotency keys, so transport retries never duplicate task writes or corrupt channel state. - Atomic thread branching and pruning
copy_thread,delete_thread,delete_for_runs, andpruneuse bounded collection commands to clone or cascade-delete checkpoint graphs atomically. - Credentials stay outside application URIsConnection URIs name only the logical profile while TLS trust anchors and scoped capability credentials load from protected environment configuration.
from langgraph.graph import StateGraph
from riffdb_langgraph import (
RiffDBCheckpointSaver,
)
with RiffDBCheckpointSaver(
"riffdb://langgraph-prod"
) as checkpointer:
graph = builder.compile(
checkpointer=checkpointer
)
result = graph.invoke(
{"messages": ["plan"]},
config={
"configurable": {
"thread_id": "t-01"
}
},
)OpenFGA: Zanzibar tuple integrity without race conditions.
Fine-grained authorization engines live or die on write-path invariants: writing a relationship tuple that already exists or deleting one that is already absent must fail the entire batch atomically, and changelog consumers need strict bytewise continuation tokens across tuple mutations.
riffdb-openfga implements OpenFGA’s storage.OpenFGADatastore interface in Go and passes the complete official storage/test.RunAllTests suite against a live RiffDB server.
- Compiler-sealed conditional tuple writesUsing
observe_or_initializeanddecide, the contract enforces OpenFGA’s conflict policies (fail on duplicate write, fail on missing delete, or idempotent ignore) inside one atomic command without read-then-write races. - Bytewise UTF-8 changelog intervalsA single declared
text_key(..., binary_utf8_v1)index serves strict lower/upper interval queries in canonical UTF-8 order, letting callers reuse returned IDs directly as continuation tokens. - Zero SQL in the authorization pathEvery tuple mutation, authorization model version, assertion write, and store query runs through generated Go bindings backed by the Rust driver host.
observe_or_initialize TupleState(
store_id, tuple_key
) as state initialize {
active: false,
revision: 0,
}
decide state {
when state.active == expected =>
apply {
set state.active = requested
set state.revision =
state.revision + 1
}
when state.active == requested =>
no_effect
else => reject TupleConflict {
tuple_key: tuple_key
}
}Better Auth: Userland identity, database-enforced authority.
RiffDB deliberately keeps end-user identity, passwords, sessions, and OAuth flows out of the database kernel so applications can use best-of-breed auth libraries like Better Auth. At the same time, auth tables are the worst place in a SaaS stack for unguarded CRUD, race-prone verification tokens, or accidental credential exposure.
@riffdb/better-auth pairs a build-time schema materializer (riffdbProfileAdapter) with a profile-bound runtime dispatcher that maps Better Auth’s auth flows onto compiled RiffDB commands and RiffQL queries.
- Atomic user, account, and session graphsEmail/password signups and OAuth account links commit in a single compiled command with transactional uniqueness across email and provider identifiers.
- Consume-once verification tokensVerification consumption deletes and returns the token in one atomic command while enforcing server-observed
transaction_timeexpiry at the commit boundary. - Compiler-enforced secret fieldsPassword hashes, session tokens, and verification digests carry
secretclassification in the contract. Only named queries with explicitrevealsproofs can read them, and RiffDB automatically excludes secret-bearing operations from MCP tools.
import { betterAuth } from "better-auth";
import {
riffdbAdapter,
} from "@riffdb/better-auth";
export const auth = betterAuth({
database: riffdbAdapter({
driver,
organizationId,
}),
advanced: {
database: {
generateId: "uuid",
},
},
emailAndPassword: {
enabled: true,
},
});The adapter pattern
No backdoors required.
Every integration on this page obeys the same rules as user-written application code. There is no internal adapter SPI, no raw storage handle, and no escape hatch around the contract compiler.
When a framework lacked an idempotency key or needed hybrid analytics, we solved it in the contract language and query engine: adding sealed init_or_mutate and decide transitions, scalar columnar projections, temporal rollups, and driver-level retry identity preservation.
Managed RiffDB
Be first in line.
We’re working toward a managed service. Join the early-access list for material project updates and the first invitations.