Reduce remote app-server resident footprint - make the updater opt-out and publish minimum hardware requirements
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 18/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- linux, node.js, typescript
- 领域
- cli, infrastructure, performance
调研方向
Start by locating the TypeScript app-server daemon entry point that parses mcode app-server daemon bootstrap and the internal gate a.managedUpdaterEnabled ?? !0; also read the daemon update-loop spawn and the config.yaml schema. Scope (a) first: add a supported --no-managed-updater flag or updater.enabled key, then verify mcode app-server daemon --help lists it and no updater process/state file appears after bootstrap. The probe script in the issue is the acceptance check; (b)-(d) need separate packaging and documentation changes.
由索引模型根据 Issue 内容生成。
描述
Product or interface
CLI - interactive TUI
Use case and problem
(This also affects the Desktop app, which drives the same remote app-server over SSH.)
If only one of the four items below can be addressed, please make it (a) — making the updater opt-out. It is the single largest avoidable cost, and it is the one that scales with the number of hosts rather than with the amount of work being done.
I run MiniMax Code against several remote Linux hosts over SSH. The remote app-server installation is what actually executes the agent's work, so its footprint is the thing I have to budget for on every host I connect.
Measured on a 2 GB / 2 vCPU CentOS Stream 9 host, with the official installer and the official systemd unit, mcode 0.6.13:
$ ps -eo pid,rss,args | grep app-server
734348 162016 minimax-code app-server --instance-id dedicated-persistent-1
734403 230220 minimax-code app-server --updater-generation ef2a3f92-... cli.js
737522 219888 minimax-code app-server
$ du -sh /root/.minimax /root/.minimax-code
387M /root/.minimax
540M /root/.minimax-code
Three separate problems, in descending order of how much they cost me:
1. The updater is a permanently resident process that sleeps 99% of its life.
$ cat /root/.minimax/app-server-control/app-server-updater.state.json
{"status":"running","pid":734403,"lastCheckAtMs":1793001898033,
"nextCheckAtMs":1793005498853, ...}
nextCheckAtMs - lastCheckAtMs is 3601 seconds. So this process holds 230 MB resident forever in order to perform one HTTP check against the npm registry once per hour, then go back to sleep. On a 2 GB host that is >11% of total RAM spent on a timer.
I went looking for a way to turn it off and could not find one:
mcode app-server --help— no updater-related optionmcode app-server daemon --help— no updater-related optionconfig.yaml— onlylogLevel,defaultModel,dataContribution,memory.enabled,skipWindowsHardSafetyChecks,skipParentDeathGuard,providerMCODE_*/MINIMAX_*environment variables — none appear in the app-server chunk- The
autoUpdatesetting that does exist is a TUI-session-level flag and does not affect the remote daemon's updater
Reading the bundled daemon source, the gate is a.managedUpdaterEnabled ?? !0 — an internal dependency-injection parameter with no CLI flag or environment-variable surface. daemon bootstrap unconditionally spawns app-server daemon update-loop as a detached child.
2. The per-host installation is ~930 MB, and most of it is duplicated.
387M /root/.minimax # daemon package: packages/app-server-daemon 339M
540M /root/.minimax-code # CLI package: runtime/node-v24.19.0-linux-x64 201M
The daemon package and the CLI package are installed side by side and each carries its own copy of the runtime. The node binary in runtime/ (201 MB) is what actually executes both processes, so the app-server-daemon release tree appears to ship a second copy of everything the CLI package already has.
3. The process the Desktop app spawns per connection escapes process-level controls.
PID 737522 is the client process the Desktop app starts over SSH. Its parent chain is sshd → sshd-session → app-server, and its cgroup is:
0::/user.slice/user-0.slice/session-145.scope
— not the mcode-app-server.service unit. So a MemoryMax= on the unit does not apply to it, and it does not pick up NODE_OPTIONS from /etc/environment:
PID 734348 NODE_OPTIONS=--max-old-space-size=192 (in unit cgroup)
PID 734403 NODE_OPTIONS=--max-old-space-size=192 (in unit cgroup)
PID 737522 NODE_OPTIONS=(not set) (in session scope)
This is why a per-host MemoryMax cannot fully bound the footprint: the piece that scales with the number of connected clients is the piece outside the limit.
The same applies to the updater: it is spawned detached by daemon bootstrap and only stays inside the unit cgroup because I moved the bootstrap call into ExecStartPost. Anyone who starts the daemon by other means gets an unbounded updater.
Desired behavior
a) Make the updater opt-out, and let it idle cheaply.
At minimum, expose the existing internal flag as a supported surface, e.g.:
mcode app-server daemon bootstrap --no-managed-updater
or a config key:
updater:
enabled: false
Even when enabled, the updater should not need a full agent runtime resident to poll a registry every hour. A ~230 MB process that performs one HTTP request per hour could either run the check as a short-lived oneshot (timer-driven, exits immediately) or release its heap between checks.
b) Share one runtime between the CLI package and the daemon package.
If the daemon package can use the node already present in /root/.minimax-code/runtime, the per-host install drops from ~930 MB to roughly ~700 MB, and more importantly the two copies cannot drift apart.
c) Let the Desktop app's remote client inherit the host's resource limits.
When the app-server spawns the per-connection client, that process should land in a cgroup the administrator controls, and should inherit the same NODE_OPTIONS the daemon itself received. Today the only lever an administrator has is systemd unit configuration, and it does not reach this process.
d) Publish minimum hardware requirements for the remote app-server.
The download documentation lists only macOS 12+ / Windows 10+. There is no published CPU, memory, or disk guidance for the remote app-server, which makes it hard to decide whether a host can host one. A line like "1 GB RAM and 1 GB free disk per remote host" would be enough to start.
Platform
Linux
Alternatives and additional context
What I have already done as a workaround, in case it is useful as a reference for what an official configuration surface would need to replace:
ExecStartPostrunsmcode app-server daemon bootstrapinstead of calling it outside the unit, so the updater inherits the unit'sMemoryHigh/MemoryMax.NODE_OPTIONS=--max-old-space-size=192is injected via/etc/environment,/etc/pam.d/sshd(session optional pam_env.so), and root's shell profiles.MemoryHigh=400M,MemoryMax=700M,OOMPolicy=stopon the unit.
I also hit a separate issue while doing this — pkill -f "minimax-code app-server" inside ExecStartPre matches the /bin/sh -c command line of the unit itself, so the unit kills itself on every start (Control process exited, code=killed, status=15/TERM, NRestarts climbing forever). The [m]inimax-code bracket form avoids the self-match. That one is filed separately as #545.
The probe below collects all of the above (footprint, per-process RSS / cgroup / threads, updater interval, and the absence of any updater switch). It runs on any host with the official installer:
#!/bin/sh
# MCode remote app-server footprint probe
# Usage: sh mcode-footprint.sh
# Prints RSS/cgroup/interval facts for the local MCode app-server installation.
echo "===== 1. install footprint ====="
du -sh /root/.minimax /root/.minimax-code 2>/dev/null
du -sh /root/.minimax/packages/app-server-daemon 2>/dev/null
du -sh /root/.minimax-code/runtime 2>/dev/null
echo ""
echo "===== 2. running mcode processes ====="
ps -eo pid,ppid,rss,args | grep -E "app-server" | grep -v grep
echo ""
echo "===== 3. per-process cgroup + rss + threads ====="
for p in $(pgrep -f "app-server" 2>/dev/null); do
echo "--- PID $p ---"
echo " rss : $(awk '/VmRSS/{print $2}' /proc/$p/status) kB"
echo " cgroup : $(cat /proc/$p/cgroup | head -1)"
echo " threads : $(ls /proc/$p/task | wc -l)"
echo " cmdline : $(tr '\0' ' ' < /proc/$p/cmdline | head -c 180)"
done
echo ""
echo "===== 4. updater check interval ====="
cat /root/.minimax/app-server-control/app-server-updater.state.json 2>/dev/null
echo ""
python3 -c "
import json,time
try:
d=json.load(open('/root/.minimax/app-server-control/app-server-updater.state.json'))
lc=d.get('lastCheckAtMs',0); nc=d.get('nextCheckAtMs',0)
print(' check interval: %s s' % round((nc-lc)/1000))
print(' updater uptime: %s s' % round((int(time.time()*1000)-d.get('startedAtMs',0))/1000))
except Exception as e:
print(' (no updater state:', e, ')')
"
echo ""
echo "===== 5. is there any way to disable the updater? ====="
echo "--- config.yaml keys ---"
cat /root/.minimax/config.yaml 2>/dev/null | head -20
echo "--- mcode app-server --help ---"
/root/.minimax/packages/app-server-daemon/bin/mcode app-server --help 2>&1 | head -25
echo "--- mcode app-server daemon --help ---"
/root/.minimax/packages/app-server-daemon/bin/mcode app-server daemon --help 2>&1 | head -25
echo ""
echo "===== 6. machine capacity ====="
free -m | head -2
df -h / | tail -1
- 主要语言
- TypeScript
- 星标
- 2k
- 派生
- 259
- 平均合并
- 9 小时 58 分钟
- 30 天内合并 PR
- 54
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
MiniMax-AI/minimax-code 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
MiniMax-AI/minimax-code#507 ·
维护者通常 1 天内回复
-
bug needs-triage tui
难度 2/5 1-3 小时 新手友好度 72/100
MiniMax-AI/minimax-code#481 · 1 条评论 ·
维护者通常 1 天内回复
-
bug cli documentation needs-triage
难度 2/5 1-3 小时 新手友好度 84/100
MiniMax-AI/minimax-code#299 · 3 条评论 ·
维护者通常 1 天内回复
-
bug desktop needs-triage
难度 4/5 3-5 天 新手友好度 30/100
MiniMax-AI/minimax-code#545 ·
维护者通常 1 天内回复
-
tui
难度 4/5 3-5 天 新手友好度 30/100
MiniMax-AI/minimax-code#544 · 1 条评论 ·
维护者通常 1 天内回复
查看 MiniMax-AI/minimax-code 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 76/100
awslabs/visual-asset-management-system#804 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
restatedev/sdk-typescript#813 ·
-
bug desktop P1 session XS
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
Merit-Systems/x402scan#1312 ·
-
type:bug
难度 2/5 1-3 小时 新手友好度 78/100
Azure/apiops-cli#331 ·
维护者通常 3 天内回复