Built on a simple idea.
Every meaningful thing that happens in your system is a fact. An order was placed. A payment was confirmed. A customer was onboarded. These things happened — and they don't un-happen. FactStore gives you a reliable, ordered record of them, without ever throwing that history away.
You can create multiple isolated logical stores to keep different parts of your system cleanly separated — similar to how you'd use separate schemas in a relational database. Within each store, FactStore gives you flexible consistency semantics: use traditional aggregate-based streams when they fit, define boundaries dynamically when they don't. The choice is yours.
Core Capabilities
Three primitives. Endless possibilities.
Append with confidence
Every append is atomic and idempotent. Express exactly the consistency you need per operation — from simple unconditional writes to multi-subject conditional appends. Safe to retry. No surprises.
Query the way your domain thinks
Read facts by subject, filter by tags, or query by time range — forward or backward, with or without limits. Access patterns that fit your domain, not the other way around.
Stream in real time
Consume facts as an ordered, resumable stream. Start from the beginning, from the end, or pick up exactly where you left off. Built for projections, integrations, and event-driven workflows.
Designed for how you actually work
FactStore gives you well-defined primitives — append, query, stream — and lets you decide how to use them. No prescribed patterns, no rigid boundaries. Just clear semantics and the flexibility to build the way your domain demands.
- Open Source: Apache 2.0 licensed. Audit the code, self-host anywhere, no vendor lock-in.
- Flexible consistency: Use traditional aggregate streams, Dynamic Consistency Boundaries, or mix both — FactStore does not decide for you.
- Atomic and idempotent: Every append is transactional. Idempotency keys make retries safe in distributed systems.
- Multiple logical stores: Create isolated stores to model domain boundaries — like separate schemas in a relational database.
- Protocol-agnostic payloads: Store facts as bytes. JSON, Avro, Protobuf — your choice.
# Create a store for your customer domain
factstore store create customers
# Append a fact — tags are derived from the payload
factstore fact append \
'{"name": "Alice", "status": "active"}' \
--store customers \
--subject customer-42 \
--type CustomerOnboarded \
--tag status=active
# Stream facts in real time
factstore fact subscribe \
--store customers --from beginning
A complete toolkit
FactStore is more than a library. It ships with everything you need to get up and running.
HTTP & gRPC Server
A lightweight, cloud-native server exposing the full FactStore API over REST and gRPC. Deploy on-premise or in the cloud.
Kotlin Client SDK
An idiomatic, coroutine-native client for JVM applications. Full API coverage with clean, type-safe abstractions.
Command-Line Interface
A native binary for scripting, exploration, and local development. Manage stores and stream facts directly from your terminal.
Web Explorer
A browser-based UI for browsing stores, querying facts by subject or tags, and watching live fact streams in real time.
Client SDKs for additional languages are on the roadmap. FactStore's gRPC API means you can integrate from any environment today.
Ready to explore FactStore?
Read the documentation, browse the source, or try it locally with the in-memory implementation — no infrastructure needed.