Configuration Reference¶
All settings are read from environment variables (or a .env file in the working directory).
No restart-free reloading — the server must be restarted for changes to take effect.
Database¶
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
postgresql+asyncpg://aimon:changeme@localhost:5431/aimonitoring |
Async SQLAlchemy connection string. Must use the +asyncpg driver suffix. |
BASE_URL |
http://localhost:8000 |
Public base URL of the server (used in generated links). |
Production credentials
The default password changeme triggers a startup warning. In production the server will refuse to start (ENVIRONMENT=production) unless DATABASE_URL is overridden with secure credentials.
Cloud SQL (Google Cloud)¶
When CLOUD_SQL_INSTANCE is set the server uses the Cloud SQL Python Connector instead of a direct TCP connection.
| Variable | Default | Description |
|---|---|---|
CLOUD_SQL_INSTANCE |
(unset) | Cloud SQL instance connection name, e.g. project:region:instance. Setting this enables the connector. |
CLOUD_SQL_DATABASE |
aimonitoring |
Database name inside the Cloud SQL instance. |
CLOUD_SQL_USER |
(empty) | Database user. Leave empty when using IAM authentication. |
CLOUD_SQL_IP_TYPE |
public |
IP type used by the connector — public or private. |
CLOUD_SQL_IAM_AUTH |
true |
Use IAM-based authentication (recommended). Set to false for password auth. |
Dashboard performance¶
The dashboard computes distribution statistics (histograms, means, std, etc.) over the most-recent N inference records rather than all historical data. This keeps response times low regardless of how many records are stored.
| Variable | Default | Description |
|---|---|---|
DASHBOARD_MAX_SAMPLES |
50000 |
Maximum inference rows used per dashboard panel. The most recent rows are selected so the view reflects current model behaviour. Counts and min/max in the response are always exact; distribution shape and mean/std are based on the sample (statistically representative at this size). Increase if you need higher precision; decrease to improve latency on slower hardware. |
What is exact vs. sampled¶
When the time window contains more records than DASHBOARD_MAX_SAMPLES each panel
includes a sample_info object:
| Statistic | Source | Notes |
|---|---|---|
total_count (record count) |
Exact — full population COUNT(*) |
Uses the (model_version_id, timestamp) index, no JSON read required. |
min / max |
Sample | Most-recent N records. Getting all-time exact min/max requires a full JSON-column scan (same cost as the unsampled query), which negates the performance gain. For monitoring, recent bounds are more meaningful than historical outliers. |
mean, std, median |
Sample | Statistically representative at 50k rows. |
| Histogram bucket counts | Sample | Shape is accurate; absolute counts reflect sample size. Buckets are 20 equal-width bins plus up to two outlier buckets (is_underflow / is_overflow in the API) for values below p1 / above p99, so up to 22 buckets are returned. |
| Category percentages | Sample | Ratios are unaffected by sample size. |
Drift detection¶
| Variable | Default | Description |
|---|---|---|
DRIFT_MAX_SAMPLES |
10000 |
Maximum inference or reference records loaded into memory for drift metric computation (KS, PSI, chi-squared). Statistical tests give reliable results well below this threshold. Increase for higher precision; at 10k the error vs. the true p-value is negligible for monitoring purposes. |
Reference data¶
| Variable | Default | Description |
|---|---|---|
REFERENCE_DATA_MAX_RECORDS |
50000 |
Hard cap on the number of records accepted in a single reference-data upload (POST …/reference-data). Requests exceeding this limit are rejected with HTTP 422. Uploading reference data is a replace operation — each successful upload replaces all previously stored reference records for that model version. |
Choosing a reference set size
Statistical drift tests (KS, PSI, chi-squared) produce stable results with as few as 1 000 – 5 000 reference records. 50 000 is conservative. Very large reference sets increase drift-job memory usage without meaningfully improving detection accuracy.
Security and multi-instance operation¶
| Variable | Default | Description |
|---|---|---|
ENVIRONMENT |
development |
production / prod enforces secrets and disables the API docs by default. |
AUTH_JWT_SECRET |
(none) | JWT signing secret. Required in production -- the server refuses to start without it (ephemeral secret in development, sessions then do not survive restarts). Generate with openssl rand -base64 32. |
SESSION_SECRET |
(none) | Session/OAuth state secret. Required in production (ephemeral secret in development). |
BOOTSTRAP_ADMIN_PASSWORD |
(generated) | Initial admin password (min. 12 characters, otherwise the server refuses to start). Recommended for the first start and effectively required on Cloud Run, where you cannot read files inside an instance. If unset, a password is generated and written to BOOTSTRAP_ADMIN_PASSWORD_FILE. |
BOOTSTRAP_ADMIN_PASSWORD_FILE |
./admin-initial-password.txt |
New file (mode 0600, never overwritten) receiving the generated initial admin password, relative to the server's working directory. The password is never logged, only the file path. If the file cannot be created (not writable, or it already exists), the password is printed once to stderr -- in containers usually the log stream, so set BOOTSTRAP_ADMIN_PASSWORD or a writable path instead. The admin account is only created after the password has been delivered. |
API_DOCS_ENABLED |
true / false in production |
Expose /docs, /redoc and /openapi.json. |
SECURITY_HEADERS_ENABLED |
true |
Add CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and HSTS (over HTTPS). |
RATE_LIMIT_ENABLED |
true |
Enable rate limiting. |
RATE_LIMIT_TRUSTED_PROXY_HOPS |
0 |
Trusted reverse proxies in front of the server; 1 on Cloud Run accessed directly, typically 2 behind an external HTTPS load balancer. Client IP is the N-th X-Forwarded-For entry from the right (an external HTTPS load balancer sends X-Forwarded-For: <client>, <load-balancer-ip>); client-supplied entries on the left are ignored. Check the header your deployment actually receives. If unset behind a proxy, all users share one rate-limit bucket. |
RATE_LIMIT_STORAGE_URI |
memory:// |
Rate limit storage backend, e.g. redis://host:6379 (the Redis client must be installed separately). |
SCHEDULER_ENABLED |
true |
Run the drift job scheduler inside the API process. Set false on API instances when scheduled jobs run in the worker (python -m yaai.server.worker, which ignores this setting). |
See Deployment for running more than one instance (worker, advisory lock, job reconciliation).
Environment file¶
Place a .env file in the directory where the server starts:
DATABASE_URL=postgresql+asyncpg://user:password@db-host:5432/aimonitoring
DASHBOARD_MAX_SAMPLES=100000
DRIFT_MAX_SAMPLES=20000
REFERENCE_DATA_MAX_RECORDS=50000
All variables are optional — unset variables use the defaults shown above.