Polymarket Bot Deployment: VPS Setup, Key Safety, and Operations (2026)
Deploying a Polymarket bot is an operations problem before it is a trading problem: the code that finds edges matters less than the setup that keeps it running through reconnects, rate limits, and 3 a.m. failures. The production baseline: a VPS with stable connectivity, a proxy key in environment variables (never your main key), process supervision that restarts cleanly, tight clock sync, and a kill switch you have actually tested.
What does the baseline stack look like?
| Layer | Choice | Why |
|---|---|---|
| Host | VPS (any major provider) | Always-on; stable IP for rate limits |
| Runtime | Python 3.11+, venv or container | Reproducible dependencies |
| Process | systemd unit or Docker restart policy | Auto-restart on crash |
| Config | Environment variables | No keys on disk in plain text |
| Logging | Structured logs to file + rotation | Post-mortems need history |
| Monitoring | Dead-man’s-switch ping or uptime check | Silence must alert someone |
How do I handle keys safely?
The proxy pattern does the heavy lifting:
- Main EOA key: cold storage, never on the server
- Proxy key: the only signing key on the VPS, funded with working collateral
- Rotation path: a second proxy ready to take over if the first is compromised
# /etc/systemd/system/pm-bot.env (root-readable only)
PM_PROXY_KEY=0x...
PM_PROXY_ADDRESS=0x...
PM_CLOB_HOST=https://clob.polymarket.com
Rules: chmod 600 the env file, never log key material, never commit configs, and
keep dev and prod on separate proxies so a debugging mistake can’t touch real
capital.
What does the systemd unit look like?
[Unit]
Description=Polymarket bot
After=network-online.target
[Service]
EnvironmentFile=/etc/systemd/system/pm-bot.env
WorkingDirectory=/opt/pm-bot
ExecStart=/opt/pm-bot/.venv/bin/python main.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Restart=always with a short delay covers crashes; your code must still handle
graceful shutdown (SIGTERM → cancel open orders → flatten or persist state) so a
redeploy doesn’t strand orders on the book.
What breaks deployments in practice?
- Clock drift — signed requests need fresh timestamps; enable NTP sync
(
systemd-timesyncdor chrony) or face random signature rejections - Silent rate-limit death — a 429 loop without backoff burns your bucket; log
Poly-RateLimit-Remainingand alert on sustained decline - Unhandled reconnect state — after a WebSocket drop, reconcile books and positions before resuming; a bot that trusts pre-crash state doubles positions
- Momentum-less restarts — the bot forgets its open orders after restart; persist an order ledger locally and reconcile against the API on boot
- Alert-less silence — the most expensive failure is the quiet one; ping a monitoring endpoint every cycle so absence of signal is itself a signal
What does the kill switch need to do?
One flag — a file, an API endpoint, a Telegram command — that:
- Cancels all open orders (
DELETE /cancel-all) - Halts new signal generation
- Optionally flattens positions (your choice; document it)
- Leaves the process alive for post-mortem
Test it monthly. A kill switch that has never fired is a hypothesis, not a control.
FAQ
Q: Do I need a VPS, or can I run the bot locally? A: Local works for development; production wants a VPS — uptime, stable IP (your rate-limit identity), and no sleep-mode surprises. Home IPs also change, which resets Cloudflare’s per-IP budgeting.
Q: Which key lives on the server? A: Only the proxy wallet’s key. Your main EOA stays offline; a leaked proxy key risks that account’s collateral, not your identity.
Q: How do I update the bot without stranding orders? A: Graceful shutdown on SIGTERM: cancel resting orders, persist state, exit. systemd restarts the new version, which reconciles against the API before trading.
Q: Should I containerize?
A: Optional but recommended — it pins dependencies and makes the systemd unit a
one-liner (docker run --restart always). The operational rules (env keys, clock
sync, monitoring) are identical either way.
Q: What monitoring is enough? A: At minimum: process liveness (ping/uptime check), error-rate log alerts, and a daily balance reconciliation against the Data API. Any divergence between your ledger and the chain is an incident.
Sources
Disclaimer
Not financial advice. Educational purposes only. Updated October 2026.