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_URL | 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_PATH | 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_DIR | the dashboard compiled into a release binary (the embedded-dashboard feature); ./web/out otherwise | 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_NAME | none | Your app’s name, shown on OAuth consent screens and linked-repo pages. happyview.toml: [instance] app_name. Instance setting app_name. |
LOGO_URI, TOS_URI, POLICY_URI | none | Links published in OAuth client metadata. Instance settings logo_uri, tos_uri, policy_uri; an uploaded logo wins over logo_uri. |
CLIENT_URI | none | client_uri in OAuth client metadata. Instance setting client_uri. |
RUST_LOG | 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_URL | 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_TMPDIR, 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_SECRET | 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 sessions and tokens, keys, plugin secrets, script variables and the attestation key. Without a valid one, app sign-in, atproto spaces and service identity don’t work; an invalid value is logged and ignored. |
SUPERADMIN_DID | 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. |
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: | The key’s id in signatures. Read only when ATTESTATION_ is set; otherwise the stored key’s id is used, else did:web:<PUBLIC_URL host>#attestation. |
ATTESTATION_ | games. | The signature’s $type. Read only when ATTESTATION_ is set. |
Network
Section titled “Network”| Variable | Default | What it does |
|---|---|---|
JETSTREAM_URL | wss: | 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_URL | https: | The relay backfill asks which accounts hold a collection. |
PLC_URL | https: | 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_. |
BACKFILL_ | 3 | Accounts fetched at once from one PDS. Instance setting backfill_. |
BACKFILL_ | 100 | DIDs resolved at once. Instance setting backfill_. |
BACKFILL_ | 28 | Days a finished backfill’s per-account detail is kept. 0 keeps it. Instance setting backfill_. |
BACKFILL_ | 50000 | Units of work discovered ahead of fetching. A unit is one account under one collection. |
BACKFILL_ | 4 | Record scripts run at once for one batch of a backfill, 1 to 32. A value outside the range is moved inside it. |
BACKFILL_SOURCE | crawl | crawl fetches from each PDS, replay reads a Jetstream archive, and auto replays when the Jetstream has an archive and otherwise crawls. |
BACKFILL_ | 8 | Archive segments read at once, 1 to 64. |
BACKFILL_ | <temp>/ | Where archive segments are kept while replaying. |
BACKFILL_ | 12 | How far back from the archive’s newest data a network replay reads account and sync markers. 0 reads the job’s 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 them once, at boot, so a raised value reaches the pool only after a restart.
Plugins
Section titled “Plugins”| Variable | Default | What it does |
|---|---|---|
PLUGIN_DIR | ./plugins | Where installed plugins are kept. Under dev, <project>/. |
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: | 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. Each source is installed once, ever: one an operator later removes stays removed. |
PLUGIN_URLS | none | Plugins to load from manifest URLs at every boot, as id|url, optionally followed by |sha256:<hash>, separated by commas. Unlike HAPPYVIEW_, each is loaded again from its URL at every start. |
PLUGIN_ | none | A plugin’s secret, used when the instance holds none for that plugin. <ID> is the plugin’s id upper-cased, with every other character as _. |
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_. |
SCRIPT_ | 10 | Seconds a query, procedure, record or label script may run, from 1 to 300. Instance setting script_. |
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>/. |
JOB_ | 1 | Background jobs run at once, up to 32. |
HOSTNAME | happyview | Names this instance’s job worker in each job’s claimed_by. |
HAPPYVIEW_ | HOSTNAME, then the system’s hostname, then a random id | Names this process in stored script metrics, trimmed and cut to 128 characters. Give each instance sharing a database its own. |
SCRIPT_ | true | true or false. Whether scripts’ timings are recorded for the Script performance page. Instance setting script_. |
FEATURE_ | false | true turns on atproto spaces, which are off by default. Instance setting feature.. |
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.
Space inspector
Section titled “Space inspector”The space inspector lets operators with spaces:inspect read private space contents under a time-limited access grant. These variables come from pull requests #350 and #371, pending on alpha.
| Variable | Default | What it does |
|---|---|---|
SPACE_ | false | true, in any case, turns the space inspector on. Instance setting feature., the Enable Space Inspector switch. |
SPACE_ | 60 | The longest an access grant can last, in minutes. A value that isn’t a whole number means 60. Below 5 is raised to 5, and above 525600 (one year) is lowered to it. Instance setting space_. |
A grant asks for 60 minutes by default, or the maximum if that’s shorter.
Logging, retention and telemetry
Section titled “Logging, retention and telemetry”| Variable | Default | What it does |
|---|---|---|
EVENT_ | 30 | Days event log entries, job logs and stored script metrics are kept. 0 keeps them. Protected events follow SPACE_ instead. Instance setting event_. |
SPACE_ | 365, or 0 while EVENT_ is 0 | Days protected events are kept, and ended access grants with them. 0 keeps them. Events tied to a grant that still exists are kept whatever their age. Instance setting space_. |
DEAD_ | 30 | Days a resolved dead letter is kept. 0 keeps them. An unresolved one is never removed. |
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_. |
TELEMETRY_ | https: | 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_ | none | Which network dev is on. hpy happyview dev --network local sets it to local. With any other value, or none, dev prints a warning that writes reach your real PDS. |
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_name | APP_NAME |
logo_uri, tos_uri, policy_uri, client_uri | LOGO_URI, TOS_URI, POLICY_URI, CLIENT_URI |
backfill_, backfill_, backfill_ | BACKFILL_ |
backfill_ | BACKFILL_ |
event_ | EVENT_ |
space_ | SPACE_ |
feature., space_ | SPACE_, SPACE_ |
script_, script_ | SCRIPT_, SCRIPT_ |
script_ | SCRIPT_ |
verbose_ | VERBOSE_ |
feature. | FEATURE_ |
GET /admin/settings lists every setting with where its value came from: database, env, project, or platform for a fixed setting. The logo, the XRPC proxy, rate-limit costs and telemetry are also stored as settings, through their own endpoints and dashboard pages.
Settings a hosting platform fixes
Section titled “Settings a hosting platform fixes”A hosting platform can fix instance settings so the operator can’t change them. It sets PLATFORM_LOCKED_SETTINGS to a comma-separated list of setting keys, such as space_access_log_retention_days,space_inspector_max_grant_minutes.
| Variable | Default | What it does |
|---|---|---|
PLATFORM_ | none | Setting keys from the table above that the hosting platform fixes. |
A fixed setting:
- reads its environment variable, whatever is stored in the database;
- answers
PUTandDELETE /admin/settings/{key}with409 Conflict; - lists in
GET /admin/settingswith sourceplatform, and any stored value for it is left out.
Boot fails when a fixed setting’s variable is unset. It also fails when a fixed space_access_log_retention_days or space_inspector_max_grant_minutes isn’t a whole number above 0. A key the running version doesn’t have is logged as a warning and ignored.
happyview.toml
Section titled “happyview.toml”The keys a project’s happyview.toml can set. 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 | Default | What it does |
|---|---|---|---|
[happyview] version | string | none | The HappyView version hpy runs. A different running version only warns. |
[instance] app_name | string | none | Supplies APP_NAME. |
[instance] superadmin | DID | none | Supplies SUPERADMIN_DID. |
[interpreters]. | { did, name, channel | version } | none | An interpreter, by language id. channel is latest, beta or alpha; version pins an exact one. Exactly one of them. |
[libraries]. | { did, name, channel | version } | none | A library, by namespace, as for interpreters. |
[dev] port | integer, 1 to 65535 | none | Supplies PORT under dev. |
[dev] backfill | boolean | false | Supplies HAPPYVIEW_ under dev. |
[network_lexicons] include | list of NSIDs | empty | Network lexicons to track. |
[labels] subscribe | list of DIDs | empty | Labelers to subscribe to. |
[jetstream] protocol | auto, v2 or v1 | none | Supplies JETSTREAM_. |
[jetstream] compression | boolean | none | Supplies JETSTREAM_. |
[lexicons."<NSID>"] backfill | boolean | false | Backfill this record lexicon’s collection once. |
[lexicons."<NSID>"] indexed | boolean | true | false stops indexing the collection, keeping what’s indexed. |
[lexicons."<NSID>"] token_cost | integer | the cost set for the lexicon’s type | How much of an API client’s rate-limit budget one call to this endpoint uses. |
[scripts."<trigger>"] description | string | none | Shown with the script in the dashboard. |
[scripts."<trigger>"] outbound_xrpcs | list of strings | the methods found in the script’s source | The XRPC methods the script calls, recorded with it and listed by the admin API. A service auth call to a procedure script is refused when the list names any method other than the one called. |
A deploy ignores [happyview], [instance], [interpreters], [libraries], [dev] and [jetstream]; see Deploying.
In v3, [lexicons."<NSID>"] takes no target_collection or action. A file that still sets either fails to load with happyview.toml:2: unknown field `target_collection` . A query or procedure names its collection in its script; see Upgrading to v3.
© HappyProto

