Why vmup batches expire after 5 minutes
Learn how vmup's 5-minute TTL, remote sweeper, prune --all, and local cleanup remove uploaded batches and partial directories.
A batch is throwaway context for an agent turn. vmup defaults to 5 minutes so ~/vmup does not accumulate screenshots from last week. You can raise TTL; you cannot turn expiry off with a flag (use a large --ttl or stop the sweeper if you must keep files). To delete every remote batch now, run vmup prune --all.
After upload, human output prints the absolute expiry beside the agent folder. Upload JSON exposes the same value as expiresAt. vmup does not add expiry text to the copied prompt or path.
Recipes: Clean up batches.
How batches disappear
Per-batch marker. When upload finalization begins, the remote host computes its current epoch time plus the resolved TTL. vmup publishes that timestamp to .<batch-id>.expires beside the partial directory, then renames the completed directory into place. The marker stays outside the agent folder.
Remote sweeper. ~/vmup/.cleanup.sh is a bash script installed over SSH. Crontab runs it every minute. For a marked batch, the script compares the remote clock with that batch’s timestamp. This lets a five-minute batch and a thirty-minute batch coexist under one sweeper. For an unmarked batch created by an older vmup version, the script falls back to its installed -mmin cutoff.
The sweeper is versioned. vmup check reports installed, outdated, or missing; installed requires the current executable and its cron entry. Upgrade an old or unscheduled script with vmup check --sweeper. An old global-cutoff script can delete a long-lived batch before its printed expiry.
The script only touches agents-* directories one level under the remote root. It will not rm ~/vmup itself or your home directory.
Client sleep. After a successful upload, vmup spawns bash -c 'sleep T && ssh … rm -rf <batch> <marker>' detached. T is max(60, ttlMinutes * 60) seconds. If the laptop sleeps, the process dies, and this path does nothing. The remote sweeper remains the source of truth.
Prune. vmup prune is a third path: you decide, now, from this machine. Default prune honors stored expiries, applies its resolved age cutoff to unmarked legacy batches, and drops leftover *.partial dirs. vmup prune --all deletes every agents-* batch and marker immediately, including ones still inside TTL. vmup prune --id <batchId> deletes one batch and its marker. Not --all and --id together.
TTL resolution
Minutes, not hours, as of 0.3.0. Old configs with ttl_hours still work: hours × 60, and only if ttl_minutes is absent. Same for VMUP_TTL_HOURS.
Order: --ttl → VMUP_TTL_MINUTES → VMUP_TTL_HOURS → profile → top-level config → 5.
clampTtlMinutes: non-finite or <= 0 → 5; otherwise round and at least 1.
--ttl on an upload sets that batch’s absolute marker and the client fallback delay. It does not rewrite .cleanup.sh, and a current sweeper does not need a rewrite because it reads the marker. On vmup prune, --ttl changes only the fallback age cutoff for unmarked legacy batches.
Partial dirs
Failed uploads try to rm agents-….partial. The sweeper and default prune remove leftover partial directories after 15 minutes, longer than the ten-minute per-file upload timeout. This prevents the five-minute batch default from deleting a slow transfer. --all still deletes live batches and partials immediately.
Local cache
~/.cache/vmup/ is not TTL’d by the remote script. Successful uploads delete the session dir. Failures and --keep-local leave it. vmup prune --local removes batch dirs there older than 24 hours. update-check.json in the same cache root is not a batch dir and is left alone.
How a batch is built
Collect files, stage them under a batch id, stream them over ssh into a partial remote dir, rename into place, and copy the prompt to the clipboard.
Direct SSH vs ssh_host
Choose direct SSH (host, user, key, port) or an OpenSSH alias (ssh_host) from ~/.ssh/config. vmup still calls ssh.