Node.js uses libuv for its event loop, and libuv maintains a thread pool for operations that can't be done asynchronously at the OS level: DNS lookups, file system operations, and some crypto functions. By default, this pool has 4 threads. Each thread allocates a stack (typically 512 KB on ARM32), plus associated kernel structures.
On the Moto E2's single-core Snapdragon 410, having 4 threads provides zero parallelism benefit. The CPU can only execute one thread at a time. The extra 3 threads just sit idle, consuming ~1.5 MB of stack allocations and adding context-switch overhead.
Set the environment variable before starting Node.js:
# In your start script or .bashrc:
export UV_THREADPOOL_SIZE=1For PocketClaw, this is set in the gateway start script ($PREFIX/bin/start-openclaw):
# In start-openclaw script:
export UV_THREADPOOL_SIZE=1
export NODE_OPTIONS='-r $HIJACK --expose-gc --no-warnings --max-old-space-size=112 --max-semi-space-size=2'
exec $PREFIX/bin/node22-icu $PREFIX/lib/node_modules/openclaw/dist/cli.js gateway run --port 9000# Check the thread count of the Node.js process:
ps -T -p $(pgrep -f openclaw-gateway) | wc -l
# Expected: fewer threads than with UV_THREADPOOL_SIZE=4
# Verify the environment variable is set:
cat /proc/$(pgrep -f openclaw-gateway)/environ | tr '\0' '\n' | grep UV_THREADPOOL
# Expected: UV_THREADPOOL_SIZE=1
# Verify gateway still handles requests:
curl -s http://localhost:9000/api/status | head -1
# Expected: JSON response with status| Metric | Before | After |
|---|---|---|
| libuv threads | 4 | 1 |
| RAM saved | 0 | ~2 MB |
| Performance impact | baseline | none measurable |