Counting visitors…
Browse all docs
Start · 9Find your path through RunifoldLearn Runifold in 45 minutesUnderstand the complete Runifold platformYour first trustworthy runChoose the right execution APIChoose crates and Cargo featuresBuild common Runifold applicationsRunifold frequently asked questionsTroubleshoot Runifold applications
Execution kernel · 7Understand RunContextCoordinate external effects safelyBound work with budgets and cancellationHandle errors and retries safelyEvents, journals, and execution evidenceDesign capability-safe executionRecover safely from checkpoints
Models & providers · 7Route across models without duplicate outputChoose and configure a providerUse the provider-neutral model protocolBuild on the Provider Runtime contractUse OpenAI control-plane and Realtime APIsTest and benchmark provider adaptersSet up OpenAI, Anthropic, Gemini, and Ollama
Agents · 7Build and configure an AgentGive an Agent typed toolsAdd conversations and semantic memoryDelegate to child Agents safelyReturn structured Rust valuesStream without losing semanticsGround an Agent with retrieval
Durable workflows · 7Compose deterministic workflowsMake workflows durableOperate durable workflow workersCoordinate timers, signals, and durable waitsRun multi-tenant workflow infrastructureRun parallel branches and safe racesVersion and evolve durable workflows
Integrations · 7Connect through MCPChoose stores and persistence boundariesExpose durable work through MCP TasksBuild and evaluate retrieval pipelinesUse MCP Resources, Prompts, and SamplingCache MCP responses without crossing authorityDeploy Runifold in a Rust web service
Quality & operations · 10Test without the networkEvaluate quality and prevent regressionsObserve the complete run treeRun safely in browsers and at the edgeRead reliability claims preciselyRun reproducible evaluations in CIOperate Runifold with SLOsGovern Task retention and deletionArchive audit evidence to S3-compatible WORM storageManage compatibility and trusted releases
Docs/Integrations
NEW TO RUNIFOLD?Build the complete mental model in 45 minutes
Integrations

Choose stores and persistence boundaries

Select SQLite, PostgreSQL, pgvector, Qdrant, or in-memory stores by durability, distribution, recovery, and tenancy needs.

Practical guide·16 min

Store by responsibility

Runifold defines narrow Store contracts instead of one global database object. Journals append Run evidence; Effect stores coordinate external writes; Checkpoint and Workflow stores preserve durable execution; Conversation stores preserve transcripts; vector stores retrieve semantic documents.

Choose a backend for each required guarantee. Sharing one database deployment does not mean collapsing these semantic boundaries.

NeedSuitable starting point
deterministic unit testin-memory implementation
one process with crash recoverySQLite
distributed Workers and tenancyPostgreSQL
semantic retrieval in existing Postgrespgvector
dedicated vector serviceQdrant

Persist and update a checkpoint with SQLite

Cargo.toml
[dependencies]
runifold = { version = "=0.9.0", features = ["sqlite-bundled"] }
serde_json = "1"
use runifold::{
    Budget, BudgetTracker, CapabilitySet, Checkpoint, CheckpointId,
    CheckpointStore, RunContext, sqlite::SqliteStore,
};
use serde_json::json;
 
let store = SqliteStore::open("runifold.db")?;
let run = RunContext::root(
    BudgetTracker::new(Budget::default()),
    CapabilitySet::new(),
);
let first = Checkpoint::initial(
    CheckpointId::new(),
    run.run_id(),
    "example.order",
    1,
    json!({ "state": "received" }),
);
store.compare_and_swap(&first, None)?;
 
let current = store.load(first.id)?;
let next = current.next(json!({ "state": "validated" }))?;
store.compare_and_swap(&next, Some(current.revision))?;

None means create-only. An update supplies the exact revision it read and a checkpoint whose revision is one greater. A conflict is a concurrency signal: discard the proposed write, reload, and decide again from current state. Do not hide it with an unconditional overwrite.

SQLite

runifold-store-sqlite provides durable Effects, Checkpoints, and Journals. Use it for local applications, desktop services, a single Worker process, and integration tests that need real transactions and restart evidence.

Choose the bundled feature when you want Cargo to build SQLite. Keep one explicit database path, configure filesystem durability for your risk level, and test process-crash recovery. SQLite does not turn independent machines into a distributed lease system.

PostgreSQL

runifold-store-postgres provides conversation and semantic-memory storage plus distributed Workflow state. PostgreSQL supplies atomic transitions, store-authoritative time, row locking, SKIP LOCKED claims, tenant isolation, budget ledgers, retention, and tombstone audit.

Treat database availability as part of the execution contract. Bound connection waits, surface lease loss separately from application failure, and deploy schema changes compatibly with active Workers.

Vector stores

runifold-retrieval defines provider-neutral embeddings, documents, retrievers, and vector-store contracts. The in-memory index supports tests and small static corpora. pgvector and Qdrant adapters support persistent search.

Persist document identity, namespace, source metadata, embedding model, and index version. Retrieval results are untrusted evidence: keep attribution, apply tenant filters before ranking, and evaluate recall independently from answer quality.

Migration and recovery

Before changing a Store:

  1. name which contract and data set is moving;
  2. preserve stable IDs and tenant scope;
  3. define dual-read or cutover behavior;
  4. test interrupted migration and rollback;
  5. verify old Workers cannot write incompatible state;
  6. retain audit evidence required for ambiguous Effects or terminal Tasks.

Backups prove that bytes can be restored. Recovery tests prove the restored state still satisfies Runifold's ownership and idempotency invariants.

Choose and operate the backend

SituationStart withMove when
unit testsin-memory storenever for persistence claims
one service instance or desktop appSQLitemultiple active writers need leases/fairness
distributed workflow workersPostgreSQLthis is the intended distributed boundary
small immutable semantic corpusin-memory vector indexcorpus, durability, or sharing grows
existing Postgres retrievalpgvectorisolate only when workload requires it
dedicated vector workloadQdrantchosen from measured operational needs

For SQLite, put the database on durable local storage, back up the database and WAL consistently, and test reopen after forced process termination. For PostgreSQL, size the pool below database connection limits, bound acquisition time, use store-authoritative time for leases, and deploy schema changes before workers that require them.

Storage troubleshooting

SymptomLikely causeCheck
checkpoint conflictstale revision or competing writerloaded revision and owner identity
SQLite busy timeoutlong transaction or too many writerstransaction duration and process topology
lease lossheartbeat missed or database stalleddatabase time, pool wait, heartbeat interval
resumed usage is lowerincomplete restore logicpersisted usage and budget restoration
cross-tenant resultmissing tenant predicateauthorization-to-query binding before lookup
retrieval dimension errormixed embedding contractsmodel, dimensions, normalization, index version

Never log connection strings, checkpoint payloads, transcripts, or pre-signed archive URLs. The data layer contains application content even when telemetry is properly redacted.