This guide explains how to scale OpenClaw to support multiple users simultaneously, with proper resource management, load balancing, and user isolation.
Scaling OpenClaw for multiple users requires careful consideration of resource allocation, user isolation, load distribution, and performance optimization. This guide covers various scaling strategies from simple horizontal scaling to advanced multi-tenant architectures.
Important: OpenClaw is designed primarily for single-user personal assistant scenarios. For multi-user deployments, consider running separate instances per user.
Before scaling, evaluate your current resource usage:
# Check current resource usage
docker stats openclaw-gateway
# Monitor resource usage over time
docker stats --no-stream | grep openclaw
# Check logs for resource-related errors
docker logs openclaw-gateway | grep -i "memory\|oom\|resource"
# Check disk usage
du -sh ~/.openclaw/*
| Component | Minimum | Recommended | Production |
|---|---|---|---|
| CPU | 1 core | 2 cores | 4 cores |
| Memory | 2GB | 4GB | 8GB |
| Disk | 10GB | 20GB | 50GB+ |
| Network | 100 Mbps | 1 Gbps | 1 Gbps+ |
Update your Docker Compose configuration with resource limits:
version: '3.8'
services:
openclaw-gateway:
image: ${OPENCLAW_IMAGE:-openclaw:local}
container_name: openclaw-gateway
restart: unless-stopped
ports:
- "${OPENCLAW_GATEWAY_PORT:-18789}:18789"
volumes:
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
environment:
- HOME=/home/node
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
# Multi-user configuration
- OPENCLAW_MAX_CONCURRENT_USERS=50
- OPENCLAW_USER_RATE_LIMIT=10
- OPENCLAW_SESSION_TIMEOUT_MINUTES=120
# Resource limits
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '1.0'
memory: 2G
networks:
- openclaw-net
For multiple users, run separate OpenClaw instances:
version: '3.8'
services:
# Instance 1
openclaw-1:
image: ${OPENCLAW_IMAGE:-openclaw:local}
container_name: openclaw-instance-1
restart: unless-stopped
ports:
- "18789:18789"
volumes:
- ./instance-1/config:/home/node/.openclaw
- ./instance-1/workspace:/home/node/.openclaw/workspace
environment:
- HOME=/home/node
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN_1}
- OPENCLAW_INSTANCE_ID=instance-1
deploy:
resources:
limits:
cpus: '1.0'
memory: 2G
networks:
- openclaw-net
# Instance 2
openclaw-2:
image: ${OPENCLAW_IMAGE:-openclaw:local}
container_name: openclaw-instance-2
restart: unless-stopped
ports:
- "18790:18789"
volumes:
- ./instance-2/config:/home/node/.openclaw
- ./instance-2/workspace:/home/node/.openclaw/workspace
environment:
- HOME=/home/node
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN_2}
- OPENCLAW_INSTANCE_ID=instance-2
deploy:
resources:
limits:
cpus: '1.0'
memory: 2G
networks:
- openclaw-net
# Instance 3
openclaw-3:
image: ${OPENCLAW_IMAGE:-openclaw:local}
container_name: openclaw-instance-3
restart: unless-stopped
ports:
- "18791:18789"
volumes:
- ./instance-3/config:/home/node/.openclaw
- ./instance-3/workspace:/home/node/.openclaw/workspace
environment:
- HOME=/home/node
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN_3}
- OPENCLAW_INSTANCE_ID=instance-3
deploy:
resources:
limits:
cpus: '1.0'
memory: 2G
networks:
- openclaw-net
# Nginx load balancer
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- openclaw-1
- openclaw-2
- openclaw-3
networks:
- openclaw-net
volumes:
openclaw_shared:
networks:
openclaw-net:
driver: bridge
Create an Nginx configuration for load balancing:
cat > nginx.conf << 'EOF'
events {
worker_connections 1024;
}
http {
# Upstream servers
upstream openclaw_backends {
least_conn;
server openclaw-1:18789 weight=1 max_fails=3 fail_timeout=30s;
server openclaw-2:18789 weight=1 max_fails=3 fail_timeout=30s;
server openclaw-3:18789 weight=1 max_fails=3 fail_timeout=30s;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=user_rate_limit:10m rate=10r/s;
# HTTP to HTTPS redirect
server {
listen 80;
server_name openclaw.yourdomain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
server_name openclaw.yourdomain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Rate limiting
limit_req zone=user_rate_limit burst=20 nodelay;
# Main location
location / {
proxy_pass http://openclaw_backends;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
# Health check
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}
EOF
Run a separate OpenClaw instance for each user:
# Directory structure
/opt/openclaw/
├── user1/
│ ├── config/
│ └── workspace/
├── user2/
│ ├── config/
│ └── workspace/
└── user3/
├── config/
└── workspace/
Each user gets:
~/.openclaw/openclaw.json)For lighter multi-user scenarios, use OpenClaw’s built-in user separation:
{
"multiUser": {
"enabled": true,
"perChannelAgents": true,
"crossChannelMemory": false,
"maxUsers": 100
}
}
For improved session handling across instances:
version: '3.8'
services:
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- openclaw-net
openclaw-gateway:
# ... existing config ...
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
- redis
networks:
- openclaw-net
volumes:
redis_data:
Create a script to manage multiple instances:
cat > scripts/manage_instances.sh << 'EOF'
#!/bin/bash
# Multi-instance management script for OpenClaw
INSTANCE_DIR="/opt/openclaw"
MAX_INSTANCES=10
# Create a new instance
create_instance() {
local instance_name=$1
if [ -z "$instance_name" ]; then
echo "Usage: create_instance <instance_name>"
return 1
fi
# Create directory structure
mkdir -p ${INSTANCE_DIR}/${instance_name}/{config,workspace}
# Generate gateway token
local token=$(openssl rand -hex 32)
echo "OPENCLAW_GATEWAY_TOKEN=${token}" > ${INSTANCE_DIR}/${instance_name}/.env
echo "Instance '${instance_name}' created"
echo "Gateway token: ${token}"
echo "Access URL: http://localhost:18789/?token=${token}"
}
# Start an instance
start_instance() {
local instance_name=$1
if [ -z "$instance_name" ]; then
echo "Usage: start_instance <instance_name>"
return 1
fi
cd ${INSTANCE_DIR}/${instance_name}
docker compose up -d
echo "Instance '${instance_name}' started"
}
# Stop an instance
stop_instance() {
local instance_name=$1
if [ -z "$instance_name" ]; then
echo "Usage: stop_instance <instance_name>"
return 1
fi
cd ${INSTANCE_DIR}/${instance_name}
docker compose down
echo "Instance '${instance_name}' stopped"
}
# List all instances
list_instances() {
echo "OpenClaw Instances:"
echo "==================="
for dir in ${INSTANCE_DIR}/*/; do
if [ -d "$dir" ]; then
local name=$(basename "$dir")
echo "- ${name}"
fi
done
}
# Get instance status
instance_status() {
local instance_name=$1
if [ -z "$instance_name" ]; then
echo "Usage: instance_status <instance_name>"
return 1
fi
cd ${INSTANCE_DIR}/${instance_name}
docker compose ps
}
# Parse command
case $1 in
create)
create_instance $2
;;
start)
start_instance $2
;;
stop)
stop_instance $2
;;
list)
list_instances
;;
status)
instance_status $2
;;
*)
echo "Usage: $0 {create|start|stop|list|status}"
echo " create <name> - Create a new instance"
echo " start <name> - Start an instance"
echo " stop <name> - Stop an instance"
echo " list - List all instances"
echo " status <name> - Show instance status"
;;
esac
EOF
chmod +x scripts/manage_instances.sh
Create a monitoring script:
cat > scripts/monitor_scaling.sh << 'EOF'
#!/bin/bash
# Scaling monitoring script for OpenClaw
echo "=== OpenClaw Scaling Report ==="
echo "Timestamp: $(date)"
echo
echo "--- Instance Status ---"
docker compose ps
echo
echo "--- Resource Usage ---"
docker stats --no-stream
echo
echo "--- Disk Usage ---"
du -sh /opt/openclaw/*/
echo
echo "--- Recent Logs ---"
docker compose logs --tail=20
echo
echo "========================="
EOF
chmod +x scripts/monitor_scaling.sh
docker statsnginx -tdocker compose logs nginxcurl http://openclaw-1:18789Any questions?
Feel free to contact us. Find all contact information on our contact page.