Getting Started
Orisun is an event database for decisions that must stay correct as facts change: preserve the event history a command depends on, commit only when its declared context is still current, and publish committed events sequentially within each boundary without running a separate broker.
This guide follows the current main branch. The latest tagged release is
0.10.0; SaveEventsV2 is documented here for the upcoming release.
You can run Orisun as a release binary, a Docker image, or an embedded Go package. Docker Compose is convenient for trying the full stack, but production deployments can run the binary directly under systemd, Nomad, Kubernetes, Fly, Render, or any process supervisor.
This guide starts a standalone server. If you want Orisun inside a Go process, go to Go Embedding.
Before you start​
You need:
- an Orisun release binary or Docker
grpcurlfor the verification command- a boundary name for your application events
- a separate boundary for Orisun admin state
The examples use:
| Boundary | Purpose |
|---|---|
orders | application events |
orisun_admin | users, credentials, and admin projections |
Fastest local path​
Use SQLite first when you want the shortest feedback loop. Until
SaveEventsV2 has a tagged release, follow this page from a current main
checkout:
- Build
orisun-sqlitewith the commands under Install a binary. - Start it with the SQLite binary example.
- Verify the server with grpcurl.
- Create the
ordersboundary with Create the application boundary. - Save the first event with Save your first event.
You can move to PostgreSQL later without changing the EventStore API.
Choose how to run​
| Runtime | Use when | Start here |
|---|---|---|
| Release binary | You want to deploy Orisun directly as a server process. | Install a binary |
| Docker image | You want a packaged container or Docker Compose for local setup. | Run SQLite with Docker |
| Embedded Go package | You want Orisun inside your service process. | Go Embedding |
Release downloads and the unversioned registry tags currently resolve to the
0.10 line, before SaveEventsV2. Use a current source build for the V2 steps
until the next release is published.
Choose a backend​
| Backend | Best for | Multi-node | Binary | Docker Hub image | GHCR image |
|---|---|---|---|---|---|
| SQLite | Embedded apps, edge services, development, single-node production | No | orisun-sqlite | orisunlabs/orisun:sqlite | ghcr.io/orisunlabs/orisun:sqlite |
| PostgreSQL | Clustered deployments, larger datasets, shared database platforms | Yes | orisun-pg | orisunlabs/orisun:pg | ghcr.io/orisunlabs/orisun:pg |
| FoundationDB | Distributed transactional key-value deployments | Yes | orisun-fdb | orisunlabs/orisun:fdb | ghcr.io/orisunlabs/orisun:fdb |
All backends expose the same EventStore and Admin gRPC APIs. FoundationDB support is beta.
Choose NATS mode​
Orisun starts embedded NATS JetStream by default. That is the simplest path for local development, standalone binaries, containers, and embedded Go services.
If you already operate a JetStream-enabled NATS server, set ORISUN_NATS_URL:
ORISUN_NATS_URL=nats://localhost:4222
Embedded Go callers can also use Orisun's in-process NATS connection and JetStream handles directly, or pass caller-owned NATS handles. See Go Embedding.
SQLite is single-node only. Keep ORISUN_NATS_CLUSTER_ENABLED=false for SQLite deployments.
When to choose SQLite​
Choose SQLite when one active Orisun node is enough and operational simplicity matters more than clustering. SQLite mode is complete: it stores the event log, admin state, index metadata, publisher checkpoints, projector checkpoints, and JSON criteria indexes. Event logs live in one {boundary}.db file per boundary; derived operational state lives in one {boundary}_metadata.db file per boundary.
When to choose PostgreSQL​
Choose PostgreSQL when you need multiple Orisun nodes, want database-level operational tooling, or expect the event log to grow beyond a single-node operational profile.
Install a binary​
Download a release asset for your OS, architecture, and backend from GitHub Releases. Asset names follow this pattern:
| Binary | Includes |
|---|---|
orisun-pg-<os>-<arch> | PostgreSQL |
orisun-sqlite-<os>-<arch> | SQLite only |
orisun-fdb-linux-<arch> | FoundationDB only; beta; Linux only |
For example, on Linux amd64:
VERSION=0.10.0
curl -L \
"https://github.com/OrisunLabs/Orisun/releases/download/v${VERSION}/orisun-sqlite-linux-amd64" \
-o orisun-sqlite
chmod +x ./orisun-sqlite
The v0.10.0 binary is the current stable server and predates
SaveEventsV2. Use it only with the deprecated V1 write shape. To follow the
V2 write examples on this page before the next release, build a current main
checkout:
./build.sh linux amd64 dev pg
./build/orisun-pg-linux-amd64
./build.sh linux amd64 dev sqlite
./build/orisun-sqlite-linux-amd64
Run SQLite from a binary​
SQLite is the fastest way to start a local or single-node Orisun server without a separate database.
mkdir -p ./data/orisun/sqlite ./data/orisun/nats
ORISUN_BACKEND=sqlite \
ORISUN_SQLITE_DIR=./data/orisun/sqlite \
ORISUN_NATS_STORE_DIR=./data/orisun/nats \
ORISUN_NATS_CLUSTER_ENABLED=false \
ORISUN_ADMIN_BOUNDARY=orisun_admin \
ORISUN_ADMIN_USERNAME=admin \
ORISUN_ADMIN_PASSWORD=changeit \
./orisun-sqlite
SQLite production deployments should use ORISUN_SQLITE_SYNCHRONOUS=FULL
(the recommended setting). NORMAL is only for deployments that knowingly trade
crash/power-loss durability for write throughput.
Run PostgreSQL from a binary​
PostgreSQL mode expects an existing PostgreSQL database. Create the database and schemas with your normal database tooling, then start Orisun with connection settings:
ORISUN_BACKEND=postgres \
ORISUN_PG_HOST=localhost \
ORISUN_PG_PORT=5432 \
ORISUN_PG_USER=postgres \
ORISUN_PG_PASSWORD='password@1' \
ORISUN_PG_NAME=orisun \
ORISUN_PG_ADMIN_SCHEMA=admin \
ORISUN_ADMIN_BOUNDARY=orisun_admin \
ORISUN_ADMIN_USERNAME=admin \
ORISUN_ADMIN_PASSWORD=changeit \
ORISUN_NATS_STORE_DIR=./data/orisun/nats \
./orisun-pg
Run SQLite with Docker​
Create docker-compose.yml:
services:
orisun:
image: orisunlabs/orisun:sqlite
environment:
ORISUN_BACKEND: sqlite
ORISUN_SQLITE_DIR: /var/lib/orisun/sqlite
ORISUN_NATS_CLUSTER_ENABLED: "false"
ORISUN_ADMIN_BOUNDARY: orisun_admin
ORISUN_ADMIN_USERNAME: admin
ORISUN_ADMIN_PASSWORD: changeit
ports:
- "5005:5005"
- "8991:8991"
volumes:
- orisun-data:/var/lib/orisun
restart: unless-stopped
volumes:
orisun-data:
Start the server:
docker compose up -d
Run PostgreSQL with Docker Compose​
Create docker-compose.yml:
services:
postgres:
image: postgres:17.5-alpine3.22
environment:
POSTGRES_DB: orisun
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password@1
ports:
- "5434:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
orisun:
image: orisunlabs/orisun:pg
environment:
ORISUN_PG_HOST: postgres
ORISUN_PG_PORT: 5432
ORISUN_PG_USER: postgres
ORISUN_PG_PASSWORD: password@1
ORISUN_PG_NAME: orisun
ORISUN_PG_ADMIN_SCHEMA: admin
ORISUN_ADMIN_BOUNDARY: orisun_admin
ORISUN_ADMIN_USERNAME: admin
ORISUN_ADMIN_PASSWORD: changeit
ports:
- "5005:5005"
- "8991:8991"
volumes:
- orisun-data:/var/lib/orisun/data
depends_on:
- postgres
restart: unless-stopped
volumes:
postgres-data:
orisun-data:
Start the stack:
docker compose up -d
Verify the API​
The examples use the default admin:changeit credentials.
AUTH='Authorization: Basic YWRtaW46Y2hhbmdlaXQ='
grpcurl -H "$AUTH" localhost:5005 list
Expected services include:
orisun.Admin
orisun.EventStore
Change ORISUN_ADMIN_PASSWORD before production use.
Create the application boundary​
A fresh installation contains only the admin boundary. Create the application boundary through the event-backed Admin API before writing application events. Use the placement for the backend you started:
# SQLite
grpcurl -H "$AUTH" \
-d '{"name":"orders","description":"Order events","placement":{"backend":"sqlite","namespace":"orders"}}' \
localhost:5005 orisun.Admin/CreateBoundary
# PostgreSQL
grpcurl -H "$AUTH" \
-d '{"name":"orders","description":"Order events","placement":{"backend":"postgres","namespace":"public"}}' \
localhost:5005 orisun.Admin/CreateBoundary
CreateBoundary returns PROVISIONING. Wait until GetBoundary reports
BOUNDARY_LIFECYCLE_STATUS_ACTIVE before sending the first write. If a
clustered node briefly returns FAILED_PRECONDITION, retry while its local
runtime installation converges:
grpcurl -H "$AUTH" \
-d '{"name":"orders"}' \
localhost:5005 orisun.Admin/GetBoundary
PostgreSQL application placements are catalog state; they are not configured through environment mappings.
Save your first event​
This first write is deliberately unconditional, so it omits consistency:
grpcurl -H "$AUTH" -d @ localhost:5005 orisun.EventStore/SaveEventsV2 <<EOF
{
"boundary": "orders",
"events": [
{
"event_id": "018f2d5e-0001-7000-8000-000000000001",
"event_type": "OrderPlaced",
"data": "{\"customer_id\":\"c-1\",\"amount\":45}",
"metadata": "{\"source\":\"checkout\"}"
}
]
}
EOF
The response contains the committed log position:
{
"log_position": {
"commit_position": 1,
"prepare_position": 0
}
}
Orisun stores the API event_type value in event data as the canonical eventType JSON key and derives returned event types from that key. You do not need to duplicate it in your payload, and later queries or indexes can match eventType with normal content criteria.
Application commands that read before writing should not remain
unconditional. Preserve each complete query and its latest matching position
in SaveEventsV2.consistency; the Tutorial builds that full loop.
Release artifacts​
Orisun publishes both release binaries and Docker images.
Binary assets are attached to each GitHub release:
| Asset | Backend |
|---|---|
orisun-pg-linux-amd64, orisun-pg-darwin-arm64, ... | PostgreSQL |
orisun-sqlite-linux-amd64, orisun-sqlite-darwin-arm64, ... | SQLite only |
orisun-fdb-linux-amd64, orisun-fdb-linux-arm64 | FoundationDB only; beta; requires native FDB client libraries |
Docker images are published to Docker Hub and GitHub Container Registry with the same backend flavor tags:
| Tag | Backend |
|---|---|
orisunlabs/orisun:pg | PostgreSQL |
orisunlabs/orisun:sqlite | SQLite only |
orisunlabs/orisun:fdb | FoundationDB only, beta, includes the FDB client library |
orisunlabs/orisun:<version>-pg | PostgreSQL-compatible release |
orisunlabs/orisun:<version>-sqlite | SQLite-only release |
orisunlabs/orisun:<version>-fdb | FoundationDB-only release |
Use the same tag names under ghcr.io/orisunlabs/orisun, for example ghcr.io/orisunlabs/orisun:0.10.0-fdb.
Next steps​
- Learn the consistency model in Command Context Consistency.
- Read and subscribe with the EventStore API.
- Review production settings in Configuration.