Introduction
OpenClaw runs on Node.js, and by default the V8 engine's heap memory limit is approximately 1.5GB on 64-bit systems. When you notice the OpenClaw process consuming increasing amounts of memory, or even causing system lag or getting killed by the OOM (Out of Memory) killer, the troubleshooting methods in this article will help you identify the cause and resolve the issue.
1. Quick Memory Status Assessment
1.1 Checking Current Memory Usage
# Method 1: Via OpenClaw health endpoint
curl -s http://localhost:18789/health/detail | jq '.memory'
# Example response:
# {
# "heapUsed": "185MB",
# "heapTotal": "256MB",
# "rss": "310MB",
# "external": "12MB"
# }
# Method 2: Directly check process memory
ps aux | grep openclaw | grep -v grep
# Method 3: Use top/htop for real-time monitoring
top -p $(pgrep -f "openclaw up")
1.2 Memory Metric Definitions
| Metric | Meaning | Normal Range |
|---|---|---|
| RSS | Actual physical memory usage | < 500MB |
| Heap Used | V8 heap memory in use | < 300MB |
| Heap Total | V8 heap total allocated | < 512MB |
| External | C++ object memory | < 50MB |
If Heap Used continues to grow without dropping back, a memory leak is likely.
2. Node.js Memory Limit Configuration
2.1 Setting the Maximum Heap Size
# Method 1: Set via environment variable
export NODE_OPTIONS="--max-old-space-size=512"
openclaw restart
# Method 2: Set in the configuration file (PM2)
# ecosystem.config.js
{
env: {
NODE_OPTIONS: "--max-old-space-size=512"
}
}
# Method 3: Systemd
# /etc/systemd/system/openclaw.service
# Environment=NODE_OPTIONS=--max-old-space-size=512
Recommended memory limit settings:
| Server Memory | Suggested max-old-space-size | Notes |
|---|---|---|
| 512MB | 256 | Low-spec VPS, requires lean configuration |
| 1GB | 384 | Entry-level, supports 2-3 channels |
| 2GB | 512 | Standard configuration |
| 4GB+ | 1024 | Plenty of headroom, suitable for multi-channel high concurrency |
2.2 Enabling Garbage Collection Optimization
# Expose GC to allow manual triggering
export NODE_OPTIONS="--max-old-space-size=512 --expose-gc"
# More aggressive GC strategy (reduces memory at slight performance cost)
export NODE_OPTIONS="--max-old-space-size=512 --gc-interval=100"
3. Conversation History Cleanup
Conversation history is one of the primary causes of memory growth. Each active conversation retains context in memory.
3.1 Configuring Conversation Context Limits
// ~/.config/openclaw/openclaw.json5
{
"conversation": {
// Maximum messages retained per conversation
"maxMessages": 50,
// Conversation idle timeout (seconds); memory is freed after timeout
"idleTimeout": 1800,
// Maximum concurrent conversations
"maxConcurrent": 100,
// Context window strategy: sliding (sliding window) or summarize (summary)
"contextStrategy": "sliding"
}
}
3.2 Manually Clearing Conversation Cache
# Clear all inactive conversations via API
curl -X POST http://localhost:18789/admin/cleanup \
-H "Content-Type: application/json" \
-d '{"type": "conversations", "olderThan": "1h"}'
# Restart the service (clears all in-memory conversations)
openclaw restart
3.3 Scheduled Automatic Cleanup
# Create a scheduled cleanup script
cat > /usr/local/bin/openclaw-cleanup.sh << 'EOF'
#!/bin/bash
curl -sf -X POST http://localhost:18789/admin/cleanup \
-H "Content-Type: application/json" \
-d '{"type": "conversations", "olderThan": "2h"}'
echo "[$(date)] Conversation cache cleanup completed" >> /var/log/openclaw-cleanup.log
EOF
chmod +x /usr/local/bin/openclaw-cleanup.sh
# Run every hour
echo "0 * * * * /usr/local/bin/openclaw-cleanup.sh" | crontab -
4. Memory Leak Detection
4.1 Using Node.js Built-In Diagnostics
# Enable heap snapshot capability on startup
export NODE_OPTIONS="--max-old-space-size=512 --heapsnapshot-signal=SIGUSR2"
openclaw restart
# Generate a heap snapshot when memory is growing
kill -USR2 $(pgrep -f "openclaw up")
# The snapshot file is generated in the working directory and can be analyzed with Chrome DevTools
# Open Chrome -> F12 -> Memory -> Load the snapshot file
4.2 Monitoring Memory Growth Trends
#!/bin/bash
# Save as memory-monitor.sh
# Records memory usage every minute for trend analysis
LOG_FILE="/var/log/openclaw-memory.csv"
# Write header
if [ ! -f "$LOG_FILE" ]; then
echo "timestamp,rss_kb,heap_used,heap_total" > "$LOG_FILE"
fi
while true; do
TIMESTAMP=$(date +%Y-%m-%dT%H:%M:%S)
RSS=$(ps -o rss= -p $(pgrep -f "openclaw up") 2>/dev/null)
HEALTH=$(curl -sf http://localhost:18789/health/detail 2>/dev/null)
if [ -n "$RSS" ] && [ -n "$HEALTH" ]; then
HEAP_USED=$(echo "$HEALTH" | jq -r '.memory.heapUsed')
HEAP_TOTAL=$(echo "$HEALTH" | jq -r '.memory.heapTotal')
echo "$TIMESTAMP,$RSS,$HEAP_USED,$HEAP_TOTAL" >> "$LOG_FILE"
fi
sleep 60
done
4.3 Identifying Memory Leak Characteristics
By analyzing the logs above, you can determine whether a memory leak exists:
- Normal behavior: Memory returns to a stable baseline after GC, showing a sawtooth pattern
- Memory leak: Memory rises continuously, with the post-GC baseline also steadily increasing
- One-time growth: A one-time increase when loading many skills or connecting multiple channels, stabilizing afterward
5. Heap Snapshot Analysis
5.1 Generating a Heap Snapshot
# Method 1: Trigger via signal
kill -USR2 $(pgrep -f "openclaw up")
# The snapshot file is generated in the current working directory
# Method 2: Using v8-profiler (requires code-level support)
# Typically used during development debugging
5.2 Analyzing with Chrome DevTools
- Open Chrome browser
- Navigate to
chrome://inspect - Click "Open dedicated DevTools for Node"
- Switch to the Memory tab
- Load the
.heapsnapshotfile - Sort by "Retained Size" to find the objects consuming the most memory
5.3 Common Memory Leak Sources
| Leak Source | Symptom | Solution |
|---|---|---|
| Unremoved event listeners | EventEmitter objects growing | Ensure removeListener is called |
| Unbounded global caches | Map/Object growing continuously | Set cache limits with LRU eviction |
| Unclosed WebSockets | Socket objects accumulating | Check disconnect cleanup logic |
| Large conversation contexts | String objects consuming heavy memory | Limit context length |
| Skill plugin leaks | Third-party code issues | Disable plugins one by one to isolate |
6. Low-Memory Device Optimization
If you are running OpenClaw on a Raspberry Pi, low-spec VPS, or other memory-constrained devices, the following configurations can significantly reduce memory usage.
6.1 Lean Configuration
// ~/.config/openclaw/openclaw.json5 - Low-memory optimized
{
"conversation": {
"maxMessages": 20,
"idleTimeout": 600,
"maxConcurrent": 20,
"contextStrategy": "sliding"
},
"skills": {
// Only load essential skills
"autoLoad": false,
"whitelist": ["basic-chat"]
},
"channels": {
// Only enable necessary channels
},
"cache": {
"maxSize": "50MB"
}
}
6.2 Using Swap as a Buffer
# Create a 1GB swap file
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Make it permanent
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Adjust swappiness (set to 10 to prefer physical memory)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
6.3 Using Lightweight Models
Choosing smaller models can reduce the memory overhead of context processing:
{
"models": {
"primary": {
"provider": "ollama",
"model": "phi3:mini" // Approximately 2GB VRAM/RAM
}
}
}
7. PM2 Auto-Restart on Memory Limit
Use PM2's memory limit feature to automatically restart when memory exceeds the threshold:
// ecosystem.config.js
module.exports = {
apps: [{
name: "openclaw",
script: "openclaw",
args: "up",
max_memory_restart: "400M",
env: {
NODE_OPTIONS: "--max-old-space-size=512"
}
}]
};
# Apply the configuration
pm2 start ecosystem.config.js
# Check memory usage and restart count
pm2 describe openclaw | grep -E "memory|restart"
8. Memory Issue Troubleshooting Flowchart
High Memory Usage
│
├── RSS > 500MB?
│ ├── Yes → Check Heap Used
│ │ ├── Heap Used growing continuously → Memory leak
│ │ │ ├── Generate heap snapshot for analysis
│ │ │ ├── Disable skills one by one to isolate
│ │ │ └── Check conversation context limits
│ │ └── Heap Used stable → External memory
│ │ └── Check MCP Server or native modules
│ └── No → Within normal range
│
└── Killed by OOM Killer?
├── Add swap space
├── Set --max-old-space-size
├── Reduce concurrent conversations
└── Upgrade server memory
With these methods, you should be able to diagnose and resolve most OpenClaw memory-related issues. If a memory leak persists, consider filing an Issue on the OpenClaw GitHub repository with your heap snapshot analysis results.