From 32a699eaee27455ff0c249a67f236a0d5e0768da Mon Sep 17 00:00:00 2001 From: ilbertt Date: Tue, 29 Sep 2026 17:09:38 +0200 Subject: [PATCH 1/3] docs: explain when app background work stops --- .../src/components/apps/app-activation.tsx | 14 +++++++++++--- .../components/deploy/deploy-dialog-content.tsx | 2 +- apps/www/public/llms.txt | 7 +++++-- packages/cli/src/commands/apps/update.ts | 2 +- packages/cli/src/commands/run/[command].ts | 6 ++++++ skills/deploy-to-nibrun/SKILL.md | 4 ++++ 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/apps/dashboard/src/components/apps/app-activation.tsx b/apps/dashboard/src/components/apps/app-activation.tsx index 63b4871bc..4d2aa9ca0 100644 --- a/apps/dashboard/src/components/apps/app-activation.tsx +++ b/apps/dashboard/src/components/apps/app-activation.tsx @@ -10,9 +10,17 @@ import type { AppSummary } from '#queries/apps.ts'; */ export function AppActivation({ app }: { app: AppSummary }) { return ( -
- Activation - {activationSummary(app)} +
+
+ Activation + {activationSummary(app)} +
+ {app.activation === 'on-request' && ( +

+ Background jobs and timers do not run while the app sleeps. Outbound work does not keep it + awake. Activation cannot currently be changed through the dashboard, CLI or API. +

+ )}
); } diff --git a/apps/dashboard/src/components/deploy/deploy-dialog-content.tsx b/apps/dashboard/src/components/deploy/deploy-dialog-content.tsx index 343cb9de6..ce1dda14a 100644 --- a/apps/dashboard/src/components/deploy/deploy-dialog-content.tsx +++ b/apps/dashboard/src/components/deploy/deploy-dialog-content.tsx @@ -79,6 +79,6 @@ export function DeployDialogContent({ function describeDeploy(newApp: boolean): string { return newApp - ? 'The binary is uploaded to the store, then released as what the app runs.' + ? 'New apps sleep after five minutes without incoming traffic. Background jobs and timers do not run while asleep; activation cannot currently be changed.' : 'The app is released again with whatever this leaves it set to. A binary replaces the one it runs; without one, it keeps it.'; } diff --git a/apps/www/public/llms.txt b/apps/www/public/llms.txt index 42844574d..b11eb7b82 100644 --- a/apps/www/public/llms.txt +++ b/apps/www/public/llms.txt @@ -66,8 +66,11 @@ listen on it, on `0.0.0.0`. One microVM per app: no horizontal scaling, no load balancing. A deploy stops the old VM before starting the new one, so it is a few seconds of downtime rather than blue/green. An app sleeps -after five minutes idle and wakes on the next request in ~120 ms. It fits a single-binary app that -owns its own state; it does not fit anything that has to be several machines. +after five minutes without incoming traffic and wakes on the next request in ~120 ms. +Background jobs, timers, scheduled emails and outbound polling do not run while it sleeps. +Owners cannot change activation through the CLI, API or dashboard. Apps that need background +work to run on schedule are not currently a fit. It fits a single-binary app that owns its own +state; it does not fit anything that has to be several machines. ## Links diff --git a/packages/cli/src/commands/apps/update.ts b/packages/cli/src/commands/apps/update.ts index c69a5e75a..0c9752c8d 100644 --- a/packages/cli/src/commands/apps/update.ts +++ b/packages/cli/src/commands/apps/update.ts @@ -10,7 +10,7 @@ import { updateApp } from '#lib/update.ts'; export const command = defineCommand('apps update', { description: - 'Change how the app starts and run it again on the binary it already has. Nothing is uploaded, and whatever no flag names is left as it is.', + 'Change how the app starts and run it again on the binary it already has. Nothing is uploaded, and whatever no flag names is left as it is. Activation cannot currently be changed: on-request apps sleep without incoming traffic, and background jobs and timers do not run while asleep.', options: { args: { schema: z.string().optional(), diff --git a/packages/cli/src/commands/run/[command].ts b/packages/cli/src/commands/run/[command].ts index 320861e47..1c69aacff 100644 --- a/packages/cli/src/commands/run/[command].ts +++ b/packages/cli/src/commands/run/[command].ts @@ -80,6 +80,12 @@ export const command = defineCommand('run [command]', { ? await completeOptions({ api, options: given, binarySource, args }) : given; + if (resolved.app === undefined) { + ui.step( + 'New apps sleep after five minutes without incoming traffic. Background jobs and timers do not run while asleep; activation cannot currently be changed.', + ); + } + emit(await deploy({ ...resolved, api, ui, binary, args, detach })); }, }); diff --git a/skills/deploy-to-nibrun/SKILL.md b/skills/deploy-to-nibrun/SKILL.md index c7bc0d91d..4cb910ec8 100644 --- a/skills/deploy-to-nibrun/SKILL.md +++ b/skills/deploy-to-nibrun/SKILL.md @@ -232,6 +232,10 @@ nib apps update --app my-app --extra-public-port --env 'ANNOUNCED_IP=${NIBRUN_PU Worth saying out loud before recommending it: +- **New apps sleep after five minutes without incoming traffic.** The next request wakes them. + Background jobs, timers, scheduled emails and outbound polling do not run while an app sleeps, + and outbound work does not keep it awake. Owners cannot change activation through the CLI, API + or dashboard. An app that needs background work to run on schedule is not currently a fit. - **One microVM per app, one size.** No horizontal scaling, no load balancing, no resizing. - **A deploy is a replace.** The old VM is stopped before the new one starts, because they share one volume — so there are a few seconds of downtime, and no blue/green or canary. From 2fb738261f78b761d43caec1fd67ac4b41a05eb6 Mon Sep 17 00:00:00 2001 From: ilbertt Date: Tue, 29 Sep 2026 17:51:47 +0200 Subject: [PATCH 2/3] docs(dashboard): shorten the activation note --- apps/dashboard/src/components/apps/app-activation.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/dashboard/src/components/apps/app-activation.tsx b/apps/dashboard/src/components/apps/app-activation.tsx index 4d2aa9ca0..975367058 100644 --- a/apps/dashboard/src/components/apps/app-activation.tsx +++ b/apps/dashboard/src/components/apps/app-activation.tsx @@ -17,8 +17,7 @@ export function AppActivation({ app }: { app: AppSummary }) {
{app.activation === 'on-request' && (

- Background jobs and timers do not run while the app sleeps. Outbound work does not keep it - awake. Activation cannot currently be changed through the dashboard, CLI or API. + Background work pauses during sleep. Activation isn’t configurable.

)} From cf45f5362130023154ed36163bb069fbd6a866bc Mon Sep 17 00:00:00 2001 From: ilbertt Date: Tue, 29 Sep 2026 17:53:34 +0200 Subject: [PATCH 3/3] docs(dashboard): qualify the activation limitation --- apps/dashboard/src/components/apps/app-activation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dashboard/src/components/apps/app-activation.tsx b/apps/dashboard/src/components/apps/app-activation.tsx index 975367058..815d4e192 100644 --- a/apps/dashboard/src/components/apps/app-activation.tsx +++ b/apps/dashboard/src/components/apps/app-activation.tsx @@ -17,7 +17,7 @@ export function AppActivation({ app }: { app: AppSummary }) { {app.activation === 'on-request' && (

- Background work pauses during sleep. Activation isn’t configurable. + Background work pauses during sleep. Activation isn’t configurable for now.

)}