Tuning tman for Vite & webpack
Builds want the cores and the RAM; dev servers must never get a timeout.
Recommended starting caps
| cap | start at | what it answers |
|---|---|---|
stall | 10m | hang backstop — no output and no CPU/IO activity for this long |
max-time | 20m | wall-clock budget — the only cap that bounds a run that is working but will never finish |
max-mem | unset — opt in only if it has hurt you | RSS ceiling across the process tree |
max-parallel | 2 | slots per name-and-directory bucket |
These are starting points derived from how Vite & webpack behaves, not measurements of your machine. Every one of them should be replaced by a number you took from your own runs — the last section on this page is how.
alias "build" {
command "npx"
args "vite" "build"
max-time "20m"
}
alias "dev" {
command "npx"
args "vite"
max-parallel 1
}Bundlers split cleanly into two commands with opposite supervision needs, and conflating them is the most common configuration mistake in this whole section.
The build: no memory ceiling by default
A production build is supposed to saturate your cores and can legitimately want several gigabytes — minification and source maps over a large graph are not frugal operations. This is exactly why tman ships no default max-mem or max-cpu: culling a build out of the box would break tman run -- vite build in a project with no config at all.
Set one only after a build has actually hurt you, and set it above the observed peak. What the build does want is max-time, because a bundler wedged on a circular dependency or a pathological plugin will otherwise sit there indefinitely.
The dev server: dedup, not deadline
Never put a wall-clock cap on
vite / webpack serve. It is designed not to exit, somax-timeguarantees a kill and an exit 124 that means nothing. Use--nameinstead: the dedup lock is what you actually want, because it stops an agent starting a second copy on top of the first.
The real hazard with a dev server under an agent is duplication. The agent starts one, the tool call returns, the agent forgets, and twenty minutes later it starts another — now two servers want port 5173, and the one that lost is either dead or, worse, silently serving stale output on a different port. A dedup lock refuses the second outright:
tman run --name dev -- npx vite # the second call refuses
tman run --name dev --replace -- npx vite # or kills the first and waits for the name
--replacedoes not just kill and start — it waits for the old runner to hand the name back, up to--queue-timeout, and refuses to start if it is still held. That is the difference between replacing a server and briefly running two.
And when the agent's machine suspends
A dev server is the process most likely to still be running tomorrow. Every tman command sweeps children whose runner has died, so a laptop that suspended overnight comes back to a machine that cleans itself up on the next tman list rather than to a fan running at full speed.
Turn the starting point into a real number
Everything above is derived from how this tool behaves, not from your machine. The numbers that matter come from your own runs, and getting them takes one command:
tman status --json | jq '.runs[] | {name, exit, duration_ms}'Set max-time from the slowest successful run you are willing to wait for, with real headroom — a cap that fires on healthy work teaches everyone to raise the cap, and after a few rounds of that it bounds nothing. Set stall from the longest stretch the command legitimately produces no output and no CPU, then double it.
Exit 124, 125, and 126 are findings, not flakes. 124 is a wall-clock timeout, 125 a stall, 126 a resource cull. Widening the cap that fired is the right response only after you know why it fired — the first two times a suite trips
max-mem, the interesting question is what is holding the memory.
Frequently asked
Should I set max-mem on a Vite or webpack production build?
Not by default. A production build is supposed to saturate cores and can legitimately want several gigabytes — which is why tman ships no default memory ceiling at all. Add one only after a build has actually caused a problem, and set it above the peak you measured.
How do I stop an agent starting a second dev server?
Give the run a --name. A same-name run in the same directory refuses by default; with --replace it kills the existing one and waits for the runner to hand the name back before starting, so you never briefly have two servers on the same port.