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, 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”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 | 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.
Since the release that removes them, [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

