Patch Changes
- b242acf: Cut idle database round trips on serverless deployments.
- The Netlify keep-warm scheduled function is now opt-out and its cadence configurable (
AGENT_NATIVE_DISABLE_KEEP_WARM,AGENT_NATIVE_KEEP_WARM_SCHEDULE), and the expensive background-function warm can be dropped on its own (AGENT_NATIVE_DISABLE_KEEP_WARM_BACKGROUND). Previously a once-a-minute wake was hardcoded, so a scale-to-zero database (Neon, Aurora Serverless v2, paused-compute Supabase) never autosuspended and burned its compute quota with zero users online. Defaults are unchanged; an unparseable cron fails the build rather than silently reverting to the old cadence. - Thread ACL checks no longer load the conversation blob.
resolveThreadAccesswas loading the fullchat_threadsrow — includingthread_data— for the access decision, discarding it, and reading the same row again, so every agent-chat request downloaded the conversation twice. The share dialog and collab routes got the same projected-load fix. - The SQL-backed SSE relay now backs off from 500ms toward 2s after a run has been quiet for several polls, and probes
reapIfStaleon its own 5s cadence instead of the 500ms status cadence — a reap cannot match a row younger than 15s, so it was issuing ~30 rounds of round trips before it could do anything. Streaming cadence is unchanged. - The in-process backstop sweep timers can be turned off with
AGENT_NATIVE_DISABLE_INPROCESS_SWEEPSwhere a durable scheduler already drives the same recovery. On serverless these timers run per warm container, so their query rate scaled with instance count rather than with load. - Domain auto-join no longer probes
organizationson every authenticated request. It short-circuits free email providers (which can never match, since an org may not claim one as itsallowed_domain) and caches a no-match per domain, invalidated whenallowed_domainis written. Previously this ran once per request for every account not already in a domain-matched org, with no fixed point. - Session-token and org-membership resolution are cached across requests behind short TTLs plus write invalidation, instead of one round trip each per request.
getAllSettingsis memoized per request and now seeds the single-key settings cache. - Added
shared/ttl-cache.tsas the single bounded-TTL cache primitive and moved the hand-rolled one intriggers/condition-evaluator.tsonto it. Failed reads are never cached anywhere, so an unreadable table can't be served as "absent". - On-demand
ensureTable()schema probes are answered from one batched introspection pass per database (two queries) instead of one query per table, column, and index — up to ~390 serial round trips per cold start before this. The snapshot is keyed per database client, so the hosted multi-app gateway can never be answered with another app's schema, and an unreadableinformation_schemafalls back to per-object probes rather than being read as "the schema is empty".AGENT_NATIVE_SKIP_ENSURE_TABLES=1skips the probe-and-DDL machinery entirely for deployments that run real migrations. - Default resources are seeded once per database instead of once per process, behind a durable marker. Previously every cold start re-issued ~10
INSERT … ON CONFLICT DO NOTHINGwrites plus two migration scans for rows that had existed since day one. Note the behavior change: a default resource the user deletes is no longer silently recreated on the next cold start. - Expired agent-scratch cleanup no longer blocks resource reads.
resourceGet/resourceGetByPath/resourceListeach awaited aDELETEbefore their ownSELECT, which doubled the round trips, took row locks inside a user-facing request, and could fail the read outright. useDbSyncnow appliesactionInvalidatePredicateto the framework-prefix invalidate too. An app's opt-out list was silently conditional: honoured for batches carrying anactionevent, ignored for batches carrying onlydb/collab/settings/screen-refresh.
- The Netlify keep-warm scheduled function is now opt-out and its cadence configurable (