System status variables
The System status page reflects read-only snapshots of process environment variables. Update values by exporting them in your shell or editing
.env, then restart the app so Next.js and background workers load the new configuration.
Managing variables
- Temporary override:
export VAR_NAME=value && yarn dev - Persistent change: edit
.env(or.env.local) and restart the application. - Secrets: prefer
.env.localor deployment-specific secret managers so changes stay out of version control.
The sections below cover the System status panel and local operational telemetry controls, along with the default values bundled with the platform. Follow the related links for deeper feature documentation where available.
Module telemetry
The Module telemetry admin page lives at /backend/config/module-telemetry. It reports module-level resource usage collected in the current process and any fresh local process telemetry files. Data is stored in 5-minute buckets; each bucket includes its own interval so older persisted buckets remain readable if the interval changes later.
Telemetry stages:
startup: a bucket that overlaps the first 5 minutes after telemetry starts.running: buckets after startup.
Metric semantics:
- Calls and CPU are summed across selected buckets.
- Heap / hour and RSS / hour are positive growth pressure normalized by the selected time window.
- Heap and RSS growth are not live memory gauges. They track positive deltas observed after module operations, so they can grow even when current process memory later drops.
SF_MODULE_RESOURCE_USAGE
Default: true
Enables local module resource attribution for API routes, event subscribers, queue workers, and custom tracked operations. Disable only when debugging the tracker itself or when no local telemetry should be collected.
SF_MODULE_RESOURCE_USAGE_SNAPSHOT
Default: true outside tests
Writes best-effort local process telemetry files under .saasframe/module-resource-usage so the admin page can include fresh data from sibling processes after restarts or worker activity.
SF_MODULE_RESOURCE_USAGE_DIR
Default: ./.saasframe/module-resource-usage
Overrides the directory used for local process telemetry files.
SF_MODULE_RESOURCE_HEAVY_P95_MS
Default: 5000
Threshold for flagging modules with slow p95 operation duration.
SF_MODULE_RESOURCE_HEAVY_CPU_MS
Default: 25000
Threshold for flagging modules with high accumulated CPU time.
SF_MODULE_RESOURCE_HEAVY_HEAP_BYTES
Default: 262144000
Threshold for flagging modules with high positive heap growth.
SF_MODULE_RESOURCE_HEAVY_RSS_BYTES
Default: 262144000
Threshold for flagging modules with high positive RSS growth.
SF_MODULE_RESOURCE_HEAVY_ERRORS
Default: 10
Threshold for flagging modules with repeated tracked operation errors.
Profiling filters
SF_PROFILE
Default: (unset)
Enables the backend tree profiler for requests matching the provided comma-separated filters. Useful for inspecting slow paths in server handlers. Related docs: Profiling.
NEXT_PUBLIC_SF_PROFILE
Default: (unset)
Activates the tree profiler in the browser bundle so client-rendered flows can emit the same snapshots. Set alongside SF_PROFILE when debugging end-to-end latency.
SF_CRUD_PROFILE
Default: (unset)
Targets CRUD factory operations with fine-grained profiling filters. Enables [crud:profile] payloads for measuring database access patterns.
SF_QE_PROFILE
Default: (unset)
Turns on hybrid query engine profiling. Use it to verify whether requests hit the JSONB index or fall back to relational queries.
Logging
QUERY_ENGINE_DEBUG_SQL
Default: false
Logs every SQL statement dispatched by the hybrid query engine. Enable temporarily when troubleshooting filters or sorting behaviour. Related docs: Query index.
LOG_VERBOSITY
Default: (unset)
Overrides structured log verbosity (debug, trace, etc.) across the backend. Leave blank to inherit module defaults or per-service settings.
LOG_LEVEL
Default: (unset)
Fallback log level when verbosity is not specified. Common values: info, warn, error.
Cache controls
ENABLE_CRUD_API_CACHE
Default: false
Toggles the CRUD API response cache layer. When enabled, GET requests served by the CRUD factory reuse cached payloads within the TTL window.
CACHE_STRATEGY
Default: memory
Selects the cache backend. Supported values include memory (in-process) and sqlite. Related docs: Cache tuning.
CACHE_TTL
Default: (unset)
Optional override for cache time-to-live in milliseconds. Leave blank to use per-handler defaults.
CACHE_SQLITE_PATH
Default: ./.saasframe/cache/cache.db
Filesystem path for the SQLite cache file used when CACHE_STRATEGY=sqlite. Ensure the process has write permissions at this location.
Authentication
SF_PASSWORD_MIN_LENGTH
Default: 6
Minimum length enforced for new passwords (onboarding, user CRUD, password reset, CLI). To keep the frontend requirement hint aligned, set NEXT_PUBLIC_SF_PASSWORD_MIN_LENGTH to the same value.
SF_PASSWORD_REQUIRE_DIGIT
Default: true
Require at least one digit in new passwords. Mirror in NEXT_PUBLIC_SF_PASSWORD_REQUIRE_DIGIT to surface the requirement in frontend helpers.
SF_PASSWORD_REQUIRE_UPPERCASE
Default: true
Require at least one uppercase letter in new passwords. Mirror in NEXT_PUBLIC_SF_PASSWORD_REQUIRE_UPPERCASE for frontend display.
SF_PASSWORD_REQUIRE_SPECIAL
Default: true
Require at least one special character in new passwords. Mirror in NEXT_PUBLIC_SF_PASSWORD_REQUIRE_SPECIAL for frontend display.
Query index maintenance
SCHEDULE_AUTO_REINDEX
Default: true
Schedules background reindex jobs automatically when coverage gaps are detected. Disable if you prefer to handle reindexing manually through the CLI or queue workers.
OPTIMIZE_INDEX_COVERAGE_STATS
Default: false
Caches coverage statistics instead of recalculating them on every read. Suitable for large datasets where immediate precision is less critical.
FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES
Default: true
Allows the hybrid engine to serve results even when coverage is partial. Responses include an x-om-partial-index header so admins can schedule a rebuild. Related docs: Query index.
QUERY_INDEX_WARMUP_ENABLED
Default: true
Kill switch for the query_index.coverage.warmup sweep fired after login. Set to false to disable the proactive warmup entirely and rely solely on the query engine's lazy, on-demand coverage refresh. Related docs: Query index.
QUERY_INDEX_WARMUP_THROTTLE_MS
Default: 300000 (5 minutes)
Minimum time between warmup sweeps for the same entity type and tenant, checked both against an in-process cache and the persisted coverage snapshot so a process restart doesn't repeat the full sweep.
QUERY_INDEX_WARMUP_CONCURRENCY
Default: 10
Number of coverage.refresh events dispatched per chunk during the warmup sweep. Lower this alongside QUERY_INDEX_WARMUP_STAGGER_MS to reduce peak concurrent database connections on memory-constrained deployments.
QUERY_INDEX_WARMUP_STAGGER_MS
Default: 0 (unchanged burst behaviour)
Delay in milliseconds added between successive warmup chunks. A non-zero value (e.g. 2000) spreads the post-login coverage burst over time instead of firing every stale entity type at once, lowering peak RSS/connection usage without changing the total number of refreshes.
Entity compatibility
ENTITIES_BACKCOMPAT_EAV_FOR_CUSTOM
Default: false
Mirrors custom-entity writes into the legacy EAV tables. Enable only when migrating integrations that still depend on the older schema.