Configuration reference
HappyView takes its configuration from three places. When one value is set in more than one, the first in this list wins:
- Instance settings, saved in the dashboard (mostly under System > General) or through
PUT /admin/settings/{key}. Only the keys listed below work this way. - The process environment. A variable set to an empty value still counts as set.
happyview.toml, for the few variables a project file can supply, marked in the tables.
Anything none of them sets takes its default. Running happyview with no arguments (serving) also loads a .env file into the environment; happyview dev, test, check and types don’t.
Server
Section titled “Server”| Variable | Default | What it does |
|---|---|---|
PUBLIC_ | required | The URL the instance is reached at. Boot fails without it. |
HOST | 0.0.0.0 | Address to listen on. |
PORT | 3000 | Port to listen on. An unreadable value means 3000. happyview.toml: [dev] port, under dev only. |
BASE_ | none | Serve under a path prefix, such as /happyview. A trailing / is trimmed; / alone means none. A value that doesn’t start with / stops boot. |
STATIC_ | the built-in dashboard | Serve the dashboard from this directory instead. |
HAPPYVIEW_ | none | A project directory to build and serve at boot. A directory that doesn’t exist stops boot. |
HAPPYVIEW_ | HappyView/<version> (+<PUBLIC_URL>) | The User-Agent on outbound requests. |
APP_ | none | Your app’s name, shown on OAuth consent screens and linked-repo pages. happyview.toml: [instance] app_name. Instance setting app_name. |
LOGO_, TOS_, POLICY_ | none | Links published in OAuth client metadata. Instance settings logo_uri, tos_uri, policy_uri; an uploaded logo wins over logo_uri. |
CLIENT_ | none | client_uri in OAuth client metadata. Instance setting client_uri. |
RUST_ | see below | The log filter. |
RUST_LOG’s default depends on the command: happyview=debug,tower_http=debug,sqlx=warn when serving, happyview=info,tower_http=warn,sqlx=warn under dev, warn for check and types, error for test.
Database
Section titled “Database”| Variable | Default | What it does |
|---|---|---|
DATABASE_ | required | sqlite://… or postgres://…. Boot fails without it. |
DATABASE_ | from the URL | sqlite or postgres. |
DATABASE_ | 16 (SQLite), 32 (Postgres) | The main connection pool’s size. |
BACKFILL_ | sized from the backfill concurrency, at most 16 (SQLite) or 256 (Postgres) | The backfill pool’s size. At least 1. |
SQLITE_ | 67108864 (64 MiB) | Largest size the WAL is trimmed to after a checkpoint. -1 means no limit. |
SQLITE_ | NORMAL | NORMAL or FULL. |
SQLITE_ | 60 | Seconds between WAL checkpoints. 0 turns them off. |
SQLITE_ | 64 MiB | WAL size that triggers a checkpoint early. 0 turns it off. |
SQLITE_, then TMPDIR | the system’s | Where a scheduled VACUUM’s free-space check looks, as SQLite does. |
RECORD_ | zstd | zstd or none. Compresses record bodies on SQLite. |
ZSTD_ | 5000 | Records a collection needs before a compression dictionary is trained for it. |
RECORD_ | 600 | Seconds between compression passes. |
Secrets and sign-in
Section titled “Secrets and sign-in”| Variable | Default | What it does |
|---|---|---|
SESSION_ | none | Signs the dashboard’s session cookie. Must be at least 32 bytes; generate one with openssl rand -base64 48. When it’s unset, too short, or the placeholder change-me-in-production, the instance still starts, but nobody can sign in to the dashboard, and the dashboard shows why. |
TOKEN_ | none | Base64 of exactly 32 bytes (openssl rand -base64 32). Encrypts stored OAuth tokens and keys. Without a valid one, app sign-in, spaces and service identity don’t work; an invalid value is logged and ignored. |
SUPERADMIN_ | none | A DID given the superadmin privilege at every boot. A value that isn’t a DID stops boot; empty means unset. Once set, the first person to sign in is no longer given superadmin. happyview.toml: [instance] superadmin. |
PLATFORM_ | none | The SHA-256, as 64 hex characters, of the key a hosting platform uses for /admin/platform. See Platform. |
COOKIE_ | none | Other origins allowed to use the dashboard’s session cookie, separated by commas or spaces. Instance setting cookie_integration_origins, which is checked when saved. |
DEFAULT_ | 100 | Request budget for a new API client. |
DEFAULT_ | 2.0 | Requests per second a new API client’s budget refills by. |
ATTESTATION_ | stored, else generated | A hex secp256k1 key for attestation signing. |
ATTESTATION_ | did:web:<PUBLIC_URL host>#attestation; did:web:localhost#attestation when ATTESTATION_PRIVATE_KEY is set | The key’s id in signatures. |
ATTESTATION_ | games.gamesgamesgamesgames.attestation | The signature’s $type. |
Network
Section titled “Network”| Variable | Default | What it does |
|---|---|---|
JETSTREAM_ | wss://jetstream1.us-east.bsky.network | The Jetstream to follow. |
JETSTREAM_ | auto | auto, v2 or v1. happyview.toml: [jetstream] protocol. |
JETSTREAM_ | true | true or false (also 1/0, yes/no, on/off). happyview.toml: [jetstream] compression. |
JETSTREAM_ | 8 | Records processed in parallel, 1 to 64. |
RELAY_ | https://bsky.network | The relay backfill asks which accounts hold a collection. |
PLC_ | https://plc.directory | The PLC directory DIDs are resolved through. |
Backfill
Section titled “Backfill”| Variable | Default | What it does |
|---|---|---|
BACKFILL_ | 10 | PDSes fetched from at once. Instance setting backfill_concurrent_pds. |
BACKFILL_ | 3 | Accounts fetched at once from one PDS. Instance setting backfill_concurrent_dids_per_pds. |
BACKFILL_ | 100 | DIDs resolved at once. Instance setting backfill_concurrent_resolution. |
BACKFILL_ | 28 | Days a finished backfill’s per-account detail is kept. 0 keeps it. Instance setting backfill_retention_days. |
BACKFILL_ | 50000 | Accounts discovered ahead of fetching. |
BACKFILL_ | crawl | crawl fetches from each PDS; replay reads a Jetstream archive; auto picks. |
BACKFILL_ | 8 | Archive segments read at once, 1 to 64. |
BACKFILL_ | <temp>/happyview-replay | Where archive segments are kept while replaying. |
BACKFILL_ | 12 | Hours of archive replayed before the live feed takes over. 0 replays the whole range. |
JETSTREAM_ | none | Key for the Jetstream archive replay reads. |
The three concurrency settings take effect on the next backfill; the backfill connection pool is sized from the environment at boot.
Plugins
Section titled “Plugins”| Variable | Default | What it does |
|---|---|---|
PLUGIN_ | ./plugins | Where installed plugins are kept. Under dev, <project>/.happyview/plugins. |
PLUGIN_ | plugin-cache beside a SQLite database; none on Postgres | Where compiled plugins are cached on disk, so a restart doesn’t recompile them. It must belong to the user HappyView runs as and be private to it, or the cache stays in memory. |
PLUGIN_ | https://api.happyproto.at | The plugin registry. Empty or off stops HappyView reading a registry. |
HAPPYVIEW_ | none | Plugins to install on the first boot whose value lists them, separated by commas. |
PLUGIN_ | none | Plugins to load from URLs at boot, as id|url|sha256:<hash>, separated by commas. |
Scripts and jobs
Section titled “Scripts and jobs”| Variable | Default | What it does |
|---|---|---|
SCRIPT_ | 1000000 | Instructions a query, procedure, record or label script may run, from 1000 to 1000000000. Instance setting script_instruction_limit. |
SCRIPT_ | 10 | Seconds a query or procedure script may take, from 1 to 300. Instance setting script_wall_clock_seconds. |
HAPPYVIEW_ | none | A .env-style file whose values are added to scripts’ ctx.env, re-read on every run. dev sets it to <project>/.env, test to <project>/.env.test. |
JOB_ | 1 | Background jobs run at once, up to 32. |
HOSTNAME | happyview | Names this instance’s job worker in each job’s claimed_by. |
FEATURE_ | false | true turns on spaces. Instance setting feature.spaces_enabled. |
An out-of-range script limit in the environment is logged and the default is used; one saved as an instance setting is refused when saved. See Limits.
Logging, retention and telemetry
Section titled “Logging, retention and telemetry”| Variable | Default | What it does |
|---|---|---|
EVENT_ | 30 | Days event log entries are kept. 0 keeps them. Instance setting event_log_retention_days. |
DEAD_ | 30 | Days dead letters are kept. 0 keeps them. |
RECORD_ | 72 | Hours a deleted record’s tombstone is kept. 0 keeps them. |
VERBOSE_ | false | true logs every record script run and skip. It writes a lot. Instance setting verbose_event_logging. |
TELEMETRY_ | https://telemetry.happyview.dev/v1/snapshot | Where telemetry reports go, when it’s turned on. |
TELEMETRY_ | none | Set only by a hosting platform: it turns telemetry on and locks its settings. Lowercase letters, digits and -, at most 64 characters; anything else stops boot. |
Development only
Section titled “Development only”| Variable | Default | What it does |
|---|---|---|
HAPPYVIEW_ | false | Whether dev backfills. Exactly true or false. happyview.toml: [dev] backfill. |
HAPPYVIEW_ | file events | Poll for changes every this many milliseconds, 50 to 60000, instead of using file events. For dev and test --watch. |
happyview dev lists the defaults dev fills in.
Instance settings
Section titled “Instance settings”These keys can be saved as instance settings, and then win over the environment. System > General in the dashboard edits most of them; PUT /admin/settings/{key} sets any of them, and DELETE returns a key to its environment value. Both need settings:manage.
| Setting | Environment variable |
|---|---|
app_ | APP_NAME |
logo_, tos_, policy_, client_ | LOGO_URI, TOS_URI, POLICY_URI, CLIENT_URI |
backfill_, backfill_, backfill_ | BACKFILL_CONCURRENT_* |
backfill_ | BACKFILL_RETENTION_DAYS |
event_ | EVENT_LOG_RETENTION_DAYS |
script_, script_ | SCRIPT_INSTRUCTION_LIMIT, SCRIPT_WALL_CLOCK_SECONDS |
verbose_ | VERBOSE_EVENT_LOGGING |
cookie_ | COOKIE_INTEGRATION_ORIGINS |
feature.spaces_ | FEATURE_SPACES_ENABLED |
GET /admin/settings lists every setting with where its value came from: database, env or project. The logo, the XRPC proxy, rate-limit costs and telemetry are also stored as settings, through their own endpoints and dashboard pages.
happyview.toml
Section titled “happyview.toml”A project’s happyview.toml. Every table is optional, and an unknown key anywhere is an error reported with its line. Project structure explains how they’re used.
| Key | Type | What it does |
|---|---|---|
[happyview] version | string | The HappyView version hpy runs. A different running version only warns. |
[instance] app_name | string | Supplies APP_NAME. |
[instance] superadmin | DID | Supplies SUPERADMIN_DID. |
[interpreters]."<language>" | { did, name, channel | version } | An interpreter, by language id. channel is latest, beta or alpha; version pins an exact one. Exactly one of them. |
[libraries]."<namespace>" | { did, name, channel | version } | A library, by namespace, as for interpreters. |
[dev] port | integer, 1–65535 | Supplies PORT under dev. |
[dev] backfill | boolean, default false | Supplies HAPPYVIEW_DEV_BACKFILL under dev. |
[network_lexicons] include | list of NSIDs | Network lexicons to track. |
[labels] subscribe | list of DIDs | Labelers to subscribe to. |
[jetstream] protocol | auto, v2 or v1 | Supplies JETSTREAM_PROTOCOL. |
[jetstream] compression | boolean | Supplies JETSTREAM_COMPRESSION. |
[lexicons."<NSID>"] backfill | boolean, default false | Backfill this record lexicon’s collection once. |
[lexicons."<NSID>"] target_collection | NSID | The collection a query or procedure works on. |
[lexicons."<NSID>"] action | create, update, delete or upsert (default) | What a procedure without a script does. |
[lexicons."<NSID>"] indexed | boolean, default true | false stops indexing the collection, keeping what’s indexed. |
[lexicons."<NSID>"] token_cost | integer | How much of an API client’s rate-limit budget one call to this endpoint uses. |
[scripts."<trigger>"] description | string | Shown with the script in the dashboard. |
[scripts."<trigger>"] outbound_xrpcs | list of strings | The XRPC methods the script calls, recorded with it and listed by the admin API. HappyView doesn’t enforce it. |
[modules."<name>"] | { language, path, capabilities } | A compiled script module: language is rust, path its crate inside the project, capabilities what it’s granted. |
A deploy ignores [happyview], [instance], [interpreters], [libraries], [dev] and [jetstream]; see Deploying.
© HappyProto

