MyClawTrade

Ops errors

systemd watchdog for a Python trading bot

systemctl status can say active while the scan loop is wedged on a hung HTTP call. A watchdog kills that process so systemd can start a clean one.

This is operations, not a strategy. Auto-restart on a live key can hammer the exchange. Keep paper-trade on until the unit stays quiet for a full scan interval. See systemd and journalctl first.

What Restart= does not do

Restart=on-failure only fires if the process exits. A bot blocked on requests.get with no timeout is still PID-alive. systemd thinks it is fine. You are not scanning.

Watchdog unit

[Unit]
Description=OpenClaw trading bot
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
User=YOURUSER
WorkingDirectory=/home/YOURUSER/bots/openclaw
ExecStart=/home/YOURUSER/bots/openclaw/.venv/bin/python main.py
Restart=on-failure
RestartSec=15
EnvironmentFile=/home/YOURUSER/bots/openclaw/.env
WatchdogSec=180
NotifyAccess=main

[Install]
WantedBy=multi-user.target

Pet it from Python

import os, time
from systemd import daemon

def maybe_watchdog():
    usec = os.environ.get("WATCHDOG_USEC")
    if not usec:
        return
    daemon.notify("WATCHDOG=1")

# inside the scan loop, after a successful poll:
maybe_watchdog()

Install systemd-python in the venv. Ping after the poll succeeds, not at the top of a while True that never reaches the exchange. A ping on a hung request is how you fake health.

If you refuse the extra package, write to the notify socket yourself:

import os, socket
s = os.environ.get("NOTIFY_SOCKET")
if s:
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    sock.connect(s)
    sock.sendall(b"WATCHDOG=1")
    sock.close()

Prove it

sudo systemctl daemon-reload
sudo systemctl restart openclaw
systemctl show openclaw -p WatchdogUSec -p WatchdogTimestamp
journalctl -u openclaw -f

To test the kill: comment out the ping, wait WatchdogSec, watch journalctl for Watchdog timeout then a restart. Do this on paper-trade only.

Common mistakes

What usually went wrong

  • WatchdogSec shorter than the scan interval — the bot is healthy and still gets killed every loop.
  • Ping in a thread that does not do I/O — the hung request thread never matters; systemd stays happy.
  • Restart=always + WatchdogSec=30 on a live key — a timeout bug becomes an order storm. Paper-trade. Then lengthen the watchdog.
  • No StartLimitBurst — systemd will restart forever. You will not notice until the bill or the ban.

A watchdog restart is not “the bot recovered.” It is “the last process was declared dead.” Check journalctl before you turn paper-trade off. Trading can lose money. Not financial advice.

Get the full walkthrough

The paid guide includes the source, config template, and deploy script. 50% off: $19.99 (was $39.99). One-time.

Get the ebook — $19.99

Educational product. Trading can lose money. Not financial advice.

Keep reading

systemd and journalctl for a Python trading botOps errors Daily loss limit and kill switch explainedRisk Daily Telegram status for a Python botTactical