Bot Execution Engine
How bots run via cron, paper vs live mode
The bot execution engine is the cron-driven runtime that actually executes your bot strategies. Understanding how it works helps you debug unexpected bot behavior and tune for performance.
## Architecture
The execution engine is a Vercel cron job that runs every 15 minutes:
1. **Trigger.** Vercel cron hits /api/cron/execute-bots at 0/15/30/45 past every hour. 2. **Authentication.** The endpoint verifies the request came from Vercel using a signed token. 3. **Bot enumeration.** Fetches all bots with status="running" from the database. 4. **Strategy dispatch.** For each bot, loads the appropriate strategy template (EV Follower, ARB Hunter, etc.). 5. **Market evaluation.** The strategy examines current market state against the bot's parameters. 6. **Order placement.** When conditions match, the engine submits orders via the Polymarket CLOB API (Live mode) or records simulated fills (Paper mode). 7. **Audit logging.** Every action β evaluation, trade, error β is logged to the audit trail.
## Why 15 Minutes?
The choice of 15-minute intervals balances several factors:
- **Polymarket rate limits.** The CLOB API allows 10 trades/minute per user. Across all bots Γ all users, we have to stay under aggregate limits.
- β’**Cost.** Each cron tick scans all markets for all bots. More frequent = more compute = higher costs.
- β’**Diminishing returns.** Prediction markets are slower-moving than crypto or equities. A 5-minute vs 15-minute granularity rarely captures more alpha.
- β’**Vercel free tier compatibility.** Our cron schedule fits within Vercel's hobby tier limits.
For users on the Bot plan who want faster execution, **TWAP orders** are not bound by the 15-minute cron β they execute on per-minute slices via a separate cron.
## Rate Limits
To prevent runaway bots from blowing up the system or your bankroll, several limits are enforced:
- **Per-user:** 10 trades per minute, 200 trades per day
- β’**Per-bot:** 5 trades per cron cycle (i.e. per 15 minutes), configurable daily limit
- β’**Per-market:** 1 trade per market per cycle (prevents the same bot opening multiple positions in the same market)
- β’**Account level:** If your overall API error rate exceeds 5%, the engine pauses your bots and notifies you
If your bot hits a rate limit, the engine logs the skip and continues. No retry-storm.
## What Happens When a Trade Fails
The CLOB API can fail for several reasons:
- **Network error.** Retried up to 3 times with exponential backoff. If all retries fail, the trade is marked as "failed" with the error reason.
- β’**Insufficient balance.** Logged as "insufficient_balance". The bot is paused if this happens 3 times in a row.
- β’**Market closed.** Logged as "market_closed". The bot moves on to the next opportunity.
- β’**Price slipped.** If the price changed enough that your order would now violate your max-position-size, the bot skips and tries again next cycle.
Failed trades don't break bot execution β they're logged and the bot continues.
## Monitoring Your Bots
The **Bot Monitor** page (admin and per-user) shows execution health:
- **Last cycle.** When the bot last ran (should be within the last 15 minutes if active).
- β’**Cycles today.** How many times the bot has been evaluated today.
- β’**Trades placed today.** Count of executed trades.
- β’**Skip reasons.** Why trades were skipped (rate limit, no signal, low liquidity, etc.).
- β’**Error log.** Last 10 errors with stack traces.
- β’**API health.** Polymarket CLOB API status as seen by your bot.
If a bot shows "0 trades today" but you expected activity, click into the skip log to see why.
## Manually Triggering Execution
The "Execute now" button on the bot detail page (available to Bot plan users) lets you trigger an immediate cycle without waiting for the next cron tick. Useful for:
- Testing parameter changes without waiting 15 minutes
- β’Capturing time-sensitive signals you've identified manually
- β’Verifying connectivity after CLOB API maintenance
Manual triggers count toward your daily rate limit. Don't spam this button.
## Stopping a Bot
Three ways to stop a bot:
1. **Pause.** Bot keeps existing positions, doesn't take new ones. Use for short breaks. 2. **Stop.** Bot is fully deactivated. Open positions stay; close them manually. 3. **Kill switch (global).** Settings β Trading β Kill Switch immediately stops ALL bots and ALL automated execution. Use for emergencies.
Kill switch is the right call if you see unexpected behavior β pause to investigate, then re-enable when you're sure.
## Audit Trail
Every bot action is logged to the bot_audit_logs table with:
- Timestamp
- β’Bot ID
- β’Action type (evaluate, place_order, close_order, error)
- β’Market involved
- β’Decision rationale (which condition triggered or why skipped)
- β’Order details (size, price, direction)
- β’Outcome (filled, rejected, partial)
You can export audit logs as CSV from the bot detail page. Useful for:
- Tax reporting (Form 8949 export available)
- β’Strategy review ("why did the bot pass on this market?")
- β’Debugging when behavior doesn't match expectations
- β’Compliance documentation if you're trading professionally
## Common Bot Execution Issues
## Related Docs
- [Bot Builder Overview](/docs/bot-overview)
- β’[Bot Strategy Templates](/docs/bot-strategies)
- β’[Live CLOB Trading](/docs/live-trading)
- β’[Kill Switch & Safety](/docs/security)