Skip to main content

Storage

Chronos uses pluggable storage adapters for persistent state. All adapters implement the same interface, allowing you to swap backends with zero code changes.

Storage Interface​

type Storage interface {
// Sessions
CreateSession(ctx context.Context, s *Session) error
GetSession(ctx context.Context, id string) (*Session, error)
UpdateSession(ctx context.Context, s *Session) error
ListSessions(ctx context.Context, agentID string, limit, offset int) ([]*Session, error)

// Memory
PutMemory(ctx context.Context, m *MemoryRecord) error
GetMemory(ctx context.Context, agentID, key string) (*MemoryRecord, error)
ListMemory(ctx context.Context, agentID string, kind string) ([]*MemoryRecord, error)
DeleteMemory(ctx context.Context, id string) error

// Audit logs
AppendAuditLog(ctx context.Context, log *AuditLog) error
ListAuditLogs(ctx context.Context, sessionID string, limit, offset int) ([]*AuditLog, error)

// Traces
InsertTrace(ctx context.Context, t *Trace) error
GetTrace(ctx context.Context, id string) (*Trace, error)
ListTraces(ctx context.Context, sessionID string) ([]*Trace, error)

// Event ledger (append-only)
AppendEvent(ctx context.Context, e *Event) error
ListEvents(ctx context.Context, sessionID string, afterSeq int64) ([]*Event, error)

// Checkpoints
SaveCheckpoint(ctx context.Context, cp *Checkpoint) error
GetCheckpoint(ctx context.Context, id string) (*Checkpoint, error)
GetLatestCheckpoint(ctx context.Context, sessionID string) (*Checkpoint, error)
ListCheckpoints(ctx context.Context, sessionID string) ([]*Checkpoint, error)

// Lifecycle
Migrate(ctx context.Context) error
Close() error
}

The interface has 21 methods total. Every method is scoped to the tenant carried by its context.Context (see Multi-Tenancy); callers that never set a tenant operate under storage.DefaultTenant.

Adapters​

SQLite (Development)​

Single-file database with full interface implementation. Ideal for development, testing, and single-node deployments.

import (
"context"
"log"

"github.com/spawn08/chronos/storage/adapters/sqlite"
)

store, err := sqlite.New("myapp.db")
// or, for tests, an in-memory database:
// store, err := sqlite.New(":memory:")
if err != nil {
log.Fatal(err)
}
defer store.Close()
if err := store.Migrate(context.Background()); err != nil { // creates all tables
log.Fatal(err)
}

PostgreSQL (Production)​

Full-featured adapter for multi-node production deployments.

import "github.com/spawn08/chronos/storage/adapters/postgres"

store, err := postgres.New("postgres://user:pass@host:5432/chronos?sslmode=require")

In-memory​

Map-backed adapter with no external dependencies. Suitable for unit tests only (state is lost on process exit).

import "github.com/spawn08/chronos/storage/adapters/memory"

store := memory.New() // *Store implements storage.Storage; New takes no args and returns no error
defer store.Close()

Redis​

High-throughput key-value storage using sorted sets for indexing, built on redis/go-redis/v9.

import "github.com/spawn08/chronos/storage/adapters/redis"

store, err := redis.New("localhost:6379", "", 0) // addr, password, db

MongoDB​

Document-oriented storage, built on the official go.mongodb.org/mongo-driver.

import "github.com/spawn08/chronos/storage/adapters/mongo"

store, err := mongo.New("mongodb://localhost:27017", "chronos") // uri, database

DynamoDB​

Serverless storage for AWS deployments, built on aws-sdk-go-v2 with SigV4-signed requests. Leave accessKey/secretKey empty to use the default AWS credential chain (env, shared config, IAM role); pass a non-empty endpoint (e.g. http://localhost:8000) to target DynamoDB Local.

import "github.com/spawn08/chronos/storage/adapters/dynamo"

store, err := dynamo.New("", "chronos-table", "us-east-1", "", "") // endpoint, tableName, region, accessKey, secretKey

Note: unlike the other adapters, dynamo.New and mongo.New/redis.New are Go-level constructors only — the YAML storage.backend config (below) does not yet select them; wire them up with agent.New(...).WithStorage(store) in code.

VectorStore Interface​

For RAG pipelines and knowledge base search:

type VectorStore interface {
Upsert(ctx context.Context, collection string, embeddings []Embedding) error
Search(ctx context.Context, collection string, query []float32, topK int, opts ...SearchOption) ([]SearchResult, error)
Delete(ctx context.Context, collection string, ids []string) error
CreateCollection(ctx context.Context, name string, dimension int) error
Close() error
}

Search accepts optional SearchOptions; storage.WithFilter(map[string]any{...}) restricts results to embeddings whose metadata matches every key/value pair (exact-match AND). Qdrant, pgvector, Pinecone, and ChromaDB apply the filter server-side; LanceDB, Milvus, Weaviate, and RedisVector apply it client-side over the returned window. See the multi-tenancy guide.

Vector Store Adapters​

AdapterImport PathConstructor
Qdrantstorage/adapters/qdrantqdrant.New(baseURL string) *Store
Pineconestorage/adapters/pineconepinecone.New(host, apiKey string) *Store
Weaviatestorage/adapters/weaviateweaviate.New(endpoint, apiKey string) *Store
Milvusstorage/adapters/milvusmilvus.New(endpoint, token string) *Store
Redis Vectorstorage/adapters/redisvectorredisvector.New(addr string) (*Store, error)
pgvectorstorage/adapters/pgvectorpgvector.New(db *sql.DB) *Store (requires the vector Postgres extension)
ChromaDBstorage/adapters/chromadbchromadb.New(baseURL string) *Store
LanceDBstorage/adapters/lancedblancedb.New(baseURL, apiKey, dbName string) *Store

YAML Configuration​

Storage can be configured in YAML:

defaults:
storage:
backend: sqlite
dsn: chronos.db

agents:
- id: production-agent
storage:
backend: postgres
dsn: ${DATABASE_URL}

Supported storage.backend values in YAML today: sqlite, postgres (alias postgresql), and none/memory (no persistence). The redis, mongo, and dynamo adapters exist as Go packages (see above) but are not yet wired into the YAML backend switch — construct them directly and attach them with agent.New(...).WithStorage(store).

Data Types​

Session​

type Session struct {
ID string
TenantID string // omitted when using DefaultTenant
AgentID string
Status string // "running", "paused", "completed", "failed"
Metadata map[string]any
CreatedAt time.Time
UpdatedAt time.Time
}

MemoryRecord​

type MemoryRecord struct {
ID string
TenantID string
SessionID string // empty for long-term memory
AgentID string
UserID string
Kind string // "short_term" or "long_term"
Key string
Value any
CreatedAt time.Time
}

AuditLog​

type AuditLog struct {
ID string
TenantID string
SessionID string
Actor string
Action string
Resource string
Detail map[string]any
CreatedAt time.Time
}

Trace​

type Trace struct {
ID string
TenantID string
SessionID string
ParentID string
Name string
Kind string // "node", "tool_call", "model_call", "approval"
Input any
Output any
Error string
StartedAt time.Time
EndedAt time.Time
}

Event​

type Event struct {
ID string
TenantID string
SessionID string
SeqNum int64
Type string // "chat_message", "chat_summary", "node_executed", etc.
Payload any // JSON-serializable
CreatedAt time.Time
}

Checkpoint​

type Checkpoint struct {
ID string
TenantID string
SessionID string
RunID string
NodeID string
State map[string]any
SeqNum int64
CreatedAt time.Time
}