Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Reduce remote app-server resident footprint - make the updater opt-out and publish minimum hardware requirements

Abierto
#546 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
18/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
linux, node.js, typescript

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

enhancement needs-triage tui
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 option
  • mcode app-server daemon --help — no updater-related option
  • config.yaml — only logLevel, defaultModel, dataContribution, memory.enabled, skipWindowsHardSafetyChecks, skipParentDeathGuard, provider
  • MCODE_* / MINIMAX_* environment variables — none appear in the app-server chunk
  • The autoUpdate setting 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:

  • ExecStartPost runs mcode app-server daemon bootstrap instead of calling it outside the unit, so the updater inherits the unit's MemoryHigh / MemoryMax.
  • NODE_OPTIONS=--max-old-space-size=192 is injected via /etc/environment, /etc/pam.d/sshd (session optional pam_env.so), and root's shell profiles.
  • MemoryHigh=400M, MemoryMax=700M, OOMPolicy=stop on 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
Lenguaje dominante
TypeScript
Estrellas
2.1k
Forks
271
Merge medio
9 h 58 min
PR fusionados (30 d)
54

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de MiniMax-AI/minimax-code

Todos los issues de MiniMax-AI/minimax-code

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.