Skip to content

Service

rhoopr edited this page May 21, 2026 · 5 revisions

Service

kei install registers kei to start at boot and run continuously. This page explains what runs after kei install, what each platform writes, and how to inspect or control the worker from native tools.

For install commands, see Install.

What kei service run does

The command launched by every platform service manager is kei service run. That's kei sync with one default change: when no config sets a watch interval, it polls iCloud once per day, 86400 seconds, instead of running once and exiting.

Set the interval in TOML:

[watch]
interval = 3600

service run uses the same config file path rules as other commands. Docker passes --config /config/config.toml by default.

The worker handles 2FA, session refresh, and graceful shutdown the same way foreground watch mode does. SIGINT/SIGTERM on Linux/macOS and SCM stop requests on Windows flush in-flight downloads, persist state, and exit cleanly.

Per-platform artifacts

Linux (systemd)

The unit file runs /path/to/kei service run. Per-user installs land at ~/.config/systemd/user/kei.service; system-wide installs land at /etc/systemd/system/kei.service with User= set to the operator account.

systemctl --user cat kei.service
systemctl --user status kei.service
journalctl --user -u kei.service -f
systemctl --user restart kei.service

Drop --user for system-wide installs.

The unit is Type=notify with WatchdogSec=120. kei sends readiness and watchdog pings; systemd manages the PID directly. Restart=on-failure with RestartSec=10s keeps the worker alive across crashes.

Linux units generated by kei install also include:

Environment=MALLOC_ARENA_MAX=2

This is a glibc allocator setting. It lowers virtual memory reservations for long-running, multi-threaded watch processes. Resident memory stays about the same. If you write your own systemd unit and care about VSZ, include the same line.

Exit codes for supervisors

Supervisors should treat non-zero sync exits as failures. Code 2 is the one that matters most operationally: the sync started and state was preserved, but some assets failed. Alert or retry instead of counting it as a clean run.

Code Meaning
0 Sync finished cleanly, or kei stopped after prompting for 2FA.
1 Fatal startup, filesystem, CloudKit, or internal error.
2 Partial sync. Some assets failed, so the library isn't current yet.
3 Authentication failed before sync could run. Fix credentials or session state.
4 Apple returned a terminal auth state, such as a locked account or password reset requirement.

Restart=on-failure, Docker restart policies, launchd, and Windows SCM all see codes 1, 2, 3, and 4 as failures at the process-manager layer. That's what you usually want for unattended syncs. If you override that behavior, keep a separate alert on exit 2 or on the sync report's failed count.

Clap also uses exit 2 for invalid arguments before sync starts. A fixed service or container command should only hit code 2 after a started sync goes partial.

macOS (launchd)

The plist is ~/Library/LaunchAgents/com.rhoopr.kei.plist. It runs as your user and writes stdout/stderr to ~/Library/Logs/kei/stdout.log and ~/Library/Logs/kei/stderr.log.

launchctl list com.rhoopr.kei
tail -f ~/Library/Logs/kei/stderr.log
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.rhoopr.kei.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.rhoopr.kei.plist

Windows (SCM)

The service name is com.rhoopr.kei. It runs as your Windows user account, with the account password stored in LSA at install time.

Get-Service com.rhoopr.kei
sc.exe qc com.rhoopr.kei
Start-Service com.rhoopr.kei
Stop-Service  com.rhoopr.kei

SCM starts it at boot and restarts it on failure.

Checking status

kei status starts with a cross-platform service summary:

Service: running (systemd user, pid 12345, since 2026-05-08 14:32 UTC)

Common variants:

  • Service: not installed
  • Service: running (<backend>, pid <n>, since <utc>)
  • Service: <state> (<backend>, ...)
  • Service: installed (<backend>, <reason>)
  • Service: running in container (process supervisor: docker)

kei service status shows the platform-tuned form. Use it when you want manager-specific detail.

Updating after a kei upgrade

Replacing the binary in place is enough. The service artifact continues to point at the same path. Restart the service to pick up the new binary:

  • Linux: systemctl --user restart kei.service
  • macOS: launchctl kickstart -k gui/$(id -u)/com.rhoopr.kei
  • Windows: Restart-Service com.rhoopr.kei

If the binary moved, run kei uninstall && kei install.

Removing the service

kei uninstall removes only the platform artifact. State, config, and credentials are kept. Pass --purge to wipe ~/.config/kei along with the service entry.

Commands

Getting Started

Features

Clone this wiki locally