← Lab Notebook · 29 May 2026 · 5 min read

OpenClaw on Android (Termux + proot Ubuntu)

Date: May 4–5, 2026 Status: Failed (instructive)


Summary

Field Value
Experiment OpenClaw on Android — Telegram + Gemini
Goal Run a self-hosted AI agent on a phone, controllable via Telegram, without a PC or cloud server
Device Moto G23 (stock Android, no root)
Software Termux (F-Droid) → proot-distro Ubuntu → Node.js 22 → OpenClaw 2026.5.3-1
Model google/gemini-3.1-pro-preview (defaulted by onboarding wizard)
Channel Telegram bot (via BotFather token)
Outcome Install succeeded. Gateway started. Telegram registered. But Node.js event loop on the phone starved (P99 delay ~17s), causing inbound messages to be dropped by the debounce buffer before reaching the agent. Cleanly uninstalled.

Resources


Setup Steps

1. Termux

  1. Installed F-Droid on the Moto G23.
  2. Installed Termux via F-Droid (Play Store version is outdated and broken).
  3. Updated Termux package index:
pkg update && pkg upgrade -y

2. proot Ubuntu

Termux on stock Android can't run OpenClaw directly (Node + native deps are unhappy without a real Linux). Solution: run an Ubuntu userland inside proot.

pkg install proot-distro
proot-distro install ubuntu
proot-distro login ubuntu

3. System update + Node.js 22

Inside Ubuntu proot:

apt update && apt upgrade -y
apt install -y curl git
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
node -v
npm -v

4. Install OpenClaw

npm install -g openclaw@latest
openclaw --version

5. Android network interface workaround

Node's os.networkInterfaces() crashes on proot Android. The guide's hijack monkey-patches it to return an empty object, letting OpenClaw boot:

cat <<EOF > /root/hijack.js
const os = require('os');
os.networkInterfaces = () => ({});
EOF

echo 'export NODE_OPTIONS="-r /root/hijack.js"' >> ~/.bashrc
source ~/.bashrc

Note: this affects every Node process started from that shell. Blunt but functional.

6. Onboarding wizard

openclaw onboard

Wizard prompts (selections made):

  • Gateway Bind: 127.0.0.1 (loopback only — safe default)
  • Model provider: Gemini (default offered by wizard; Anthropic and others available)
  • API key: pasted Gemini API key from Google AI Studio
  • Channel: Telegram (added bot token from @BotFather)

7. Launch gateway

openclaw gateway --verbose

Dashboard accessible at:

http://127.0.0.1:18789

Get the gateway auth token in a second Ubuntu shell:

cat ~/.openclaw/openclaw.json

What Went Wrong

Symptom

Telegram bot was online (visible in BotFather, responding to BotFather's own checks but not to me). Sent /status and Hi from Telegram — no replies.

Diagnosis

Multiple openclaw status --all runs revealed:

  • Gateway reachable on initial ping (281 ms) but timing out on deep status (8000 ms timeout)
  • Agent stuck: 1 total · 1 bootstrapping · 0 active
  • Telegram channel showed OK / token configured / accounts 1/1 — config was correct

Root cause (from -verbose logs)

liveness warning: reasons=event_loop_delay,event_loop_utilization
  eventLoopDelayP99Ms=17716.7
  eventLoopDelayMaxMs=17716.7
  eventLoopUtilization=1
fetch timeout after 14986ms ... timer delayed 8416ms,
  likely event-loop starvation
telegram ingress: chatId=8514027423 dropped after 182ms
  buffer=inbound-debounce

Plain English: the Node.js event loop on the phone was frozen for ~17 seconds at a time. Inbound Telegram messages hit the debounce buffer and were dropped before the agent could process them. The model never got involved — the bottleneck was the gateway itself starving for CPU.

Why this happened

  • OpenClaw is a heavy Node app expecting laptop/desktop hardware.
  • Stack: Android → Termux → proot → Ubuntu → Node 22 → OpenClaw + 7 plugins. Each layer adds overhead.
  • Moto G23 (entry-level CPU + 4 GB RAM) can't keep the event loop responsive under that load.
  • Switching to Claude wouldn't have helped — the bottleneck is before the model call.

Cleanup (Removal)

Stop and uninstall

# Inside Ubuntu proot
pkill -9 -f openclaw
ps aux | grep -i openclaw    # confirm only grep itself remains
npm uninstall -g openclaw
rm -rf ~/.openclaw
rm -rf /tmp/openclaw

# Also Claude Code if installed
npm uninstall -g @anthropic-ai/claude-code
rm -rf ~/.claude

Remove the hijack workaround

rm -f /root/hijack.js
# Then edit ~/.bashrc and remove:
#   export NODE_OPTIONS="-r /root/hijack.js"

Verify nothing is left behind

which openclaw                                              # should print nothing
find / -iname "*openclaw*" 2>/dev/null                      # should print nothing
find / -iname "*clawdbot*" -o -iname "*clawhub*" 2>/dev/null # should print nothing

In this experiment, the find commands turned up cache files in /tmp/jiti/ and /tmp/node-compile-cache/openclaw, plus a stray /root/openclaw.log. Removed with:

rm -f /root/openclaw.log
rm -rf /tmp/node-compile-cache/openclaw
rm -rf /tmp/jiti/dist-*openclaw*
rm -rf /tmp/jiti/dist-clawhub-spec-*
rm -rf /tmp/openclaw-0

Credential hygiene

  • Telegram → @BotFather → /revoke → pick the bot. Old token now useless even if leaked.
  • Google AI Studio → API Keys → delete the Gemini key created for this experiment.

Decision: kept Ubuntu, kept Termux

Ubuntu and Node remain installed for future experiments. Could have nuked Ubuntu with proot-distro remove ubuntu but chose not to.


Lessons Learned

  • OpenClaw on Termux+proot on a budget Android phone is technically installable but practically too slow for live message handling. The published guide will get you to "running gateway," not to "working assistant."
  • Diagnosing event-loop starvation requires -verbose logs. The TUI status output makes things look healthier than they are; only the raw log shows the real story.
  • Always start the gateway in the foreground first when debugging. nohup'd background processes hide the symptoms.
  • When a process won't stop and the lock claims another PID is alive, pkill -9 -f <name> + delete lock file is the canonical recovery.
  • OpenClaw + Claude via subscription (claude-cli backend) is officially allowed for personal use, but it requires an interactive TTY login flow that's awkward through proot. API key path is more reliable on phone.
  • For the same setup on a real Linux machine (e.g. ThinkPad T490s), none of these issues would appear — same install steps, no proot, no event-loop starvation.

Reproducing on Better Hardware

If revisiting on the ThinkPad T490s, skip Termux + proot entirely:

# Native Ubuntu / Zorin
sudo apt update && sudo apt install -y curl git
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt install -y nodejs

npm install -g openclaw@latest
openclaw onboard --install-daemon
openclaw gateway --port 18789 --verbose

No hijack.js needed. systemd is real, so --install-daemon actually works. Telegram polling will keep up. This would convert the failed experiment into a working setup.

← Back to lab notebook