Ctrl Plane

Bun Store

SQL store using Bun ORM with PostgreSQL and SQLite support.

The Bun store uses the Bun ORM to persist data in PostgreSQL or SQLite. It is the recommended store for production SQL deployments.

When to use

  • Production deployments — battle-tested SQL databases with ACID transactions.
  • PostgreSQL environments — full query power, JSON operators, CTEs.
  • SQLite for development — single-file database, no server needed.
  • Teams familiar with SQL — leverage existing database expertise.

Configuration

import "github.com/xraph/ctrlplane/store/bun"

s, err := bun.New(bun.Config{
    Driver: bun.DriverPostgreSQL,
    DSN:    "postgres://user:pass@localhost:5432/ctrlplane?sslmode=disable",
})
FieldEnvDefaultDescription
DriverCP_BUN_DRIVERpostgresDatabase driver (postgres or sqlite)
DSNCP_BUN_DSNConnection string
MaxOpenConnsCP_BUN_MAX_OPEN_CONNS25Maximum open connections
MaxIdleConnsCP_BUN_MAX_IDLE_CONNS5Maximum idle connections
ConnMaxLifetimeCP_BUN_CONN_MAX_LIFETIME5mConnection max lifetime
ConnMaxIdleTimeCP_BUN_CONN_MAX_IDLE_TIME1mConnection max idle time

PostgreSQL

s, err := bun.New(bun.Config{
    Driver:       bun.DriverPostgreSQL,
    DSN:          "postgres://localhost:5432/ctrlplane?sslmode=disable",
    MaxOpenConns: 25,
})

SQLite

s, err := bun.New(bun.Config{
    Driver: bun.DriverSQLite,
    DSN:    "file:ctrlplane.db?cache=shared&_pragma=journal_mode(WAL)",
})

With the app

cp, err := app.New(
    app.WithStore(s),
)

Internals

AspectDetail
ORMBun v1 with struct-based models
MigrationsBun migrator with Go-defined migrations
SerializationBun model structs with db: tags
TransactionsDatabase-level ACID transactions
MigrateCreates tables, indexes, constraints
Pingdb.PingContext(ctx)
CloseCloses the connection pool

Model structs

Each entity has a Bun model struct with db: tags that map to database columns:

type instanceModel struct {
    bun.BaseModel `bun:"table:instances,alias:i"`

    ID           string `bun:"id,pk"`
    TenantID     string `bun:"tenant_id,notnull"`
    Name         string `bun:"name,notnull"`
    Slug         string `bun:"slug,notnull"`
    // ...
}

Conversion functions (toInstanceModel / fromInstanceModel) translate between domain entities and database models.

Connection pooling

The Bun store configures the database/sql connection pool with the settings from Config. For PostgreSQL, use connection pooling (PgBouncer) in production for high-concurrency workloads.

Limitations

  • External dependency — requires a running PostgreSQL or SQLite database.
  • Schema migrations — must run Migrate() before first use.
  • SQLite concurrency — SQLite has limited write concurrency (WAL mode helps).

Comparison

FeatureMemoryBadgerBunMongoDB
SetupNonePath onlyDSNURI
PersistenceNoYesYesYes
Multi-processNoNoYesYes
Query flexibilityLowLowHighHigh
Best forTestsEmbeddedProduction SQLProduction NoSQL

On this page