PayG keepAlive=false boxes not auto-pausing at documented 1h idle timeout .. observed 2h+ still idle

Open
#161 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
node.js, typescript

Research direction

Start with /docs/box/overall/pricing.md and /docs/box/overall/how-it-works.md, then rerun the two reproduction tests using @upstash/box 0.4.1 and the listed Box API calls. Compare the observed idle-to-paused timing with the documented one-hour timeout and trace whether the issue is account-specific or affects PayG boxes generally. Done means the behavior and documentation agree, or the timing discrepancy is clearly explained.

Written by the indexing model from the issue text.

Description

Summary

Pay-As-You-Go boxes with keepAlive: false are not auto-pausing at the documented 1-hour idle timeout. We have empirical data of status: "idle" boxes still alive 120+ minutes after their last activity, with no automatic transition to paused. The docs at /docs/box/overall/pricing.md (and /docs/box/overall/how-it-works.md) state PayG idle timeout is "1 hour", the actual observed behavior is at least 2 hours, possibly longer.

This is not blocking us (keepAlive: false idle boxes accrue essentially zero compute cost regardless), but the docs/reality mismatch caused us several hours of confusion while investigating.

Reproduction

Test 1, POLLED box (Box.list every 5 minutes, in case polling is the issue):

const box = await Box.create({ runtime: "node", apiKey, keepAlive: false });
await box.exec.command("echo started"); // single command to confirm box is responsive

// Poll via Box.list (which per #105 should NOT reset the idle timer)
for (let i = 1; i <= 24; i++) {
  await new Promise(r => setTimeout(r, 5 * 60_000));
  const all = await Box.list({ apiKey });
  const me = all.find(b => b.id === box.id);
  console.log(`t=${i*5}min status=${me?.status} last_activity=${me?.last_activity_at}`);
}

Observed: status stays "idle" for the full 120 minutes. last_activity_at is the initial echo and never updates from the Box.list polls (consistent with #105 reply, Box.list does NOT count as activity). The test script terminates without ever observing a transition to paused.

Test 2, UNTOUCHED box (zero polling, single direct GET after 60+ min):

const box = await Box.create({ runtime: "node", apiKey, keepAlive: false });
await box.exec.command("echo started");
// Wait 60+ minutes, then a single direct HTTP GET to verify state
const res = await fetch(`https://us-east-1.box.upstash.com/v2/box/${box.id}`, { headers: { "X-Box-Api-Key": apiKey } });
const data = await res.json();
console.log(data.status, "alive_min:", (Date.now()/1000 - data.created_at)/60);

Observed at t=60+ min: status: "idle", last_activity_at unchanged at the initial echo, keep_alive field absent (so keepAlive is false as expected).

Behavior summary

Test After 5 min After 30 min After 60 min After 120 min
Polled box (Box.list every 5 min) idle idle idle idle
Untouched box (no polls at all) idle idle idle (still being measured) n/a

Per maintainer reply on #105, the activities that reset the idle timer are: box.exec.command, box.files.*, git operations through the Box API, SSH sessions, scheduled runs. Box.list and GET /v2/box/{id} are not listed. We verified last_activity_at stays unchanged across our polls, so the timer is in fact not being reset, yet the box doesn't auto-pause within the documented 1-hour window.

What we expected

Per /docs/box/overall/pricing.md:

Pay as You Go idle timeout: "1 hour"

Per /docs/box/overall/how-it-works.md:

"If a box sits idle with no active commands, it automatically transitions to Paused after an idle timeout."

We expected the polled and untouched boxes to transition to paused around the 60-minute mark.

Suggested fixes

Either:

  1. Update the docs to reflect the actual auto-pause timing on PayG (whatever it actually is, appears to be 2+ hours).
  2. Or, if 1 hour is the intended target, audit why auto-pause is not firing in this account.

Environment

  • @upstash/box: 0.4.1
  • Node.js: 20.19
  • Box runtime: node, size small
  • Account: PayG plan, [email protected]
  • Test box IDs (already cleaned up): working-shrew-01354, neat-hornet-89278
Dominant language
TypeScript
Stars
45
Forks
7
Avg merge
2d 22h
Merged PRs (30d)
10

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from upstash/box

All issues in upstash/box

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.