# Why `drwu-htmls` hits the 100/day Vercel cap

**Pulled 2026-06-25** from the live Vercel deploy log (`list_deployments`), launchd plists, and the jobs' own run logs.

## The cap
- `drwu-htmls` deploys to team `team_jzbv9IytIxM0TIIXX6pbwXYY`, a **FREE "hobby" plan = 100 prod deploys/day**.
- At 0 remaining, every new deploy fails `402 api-deployments-free-per-day` for ~24h. The site still serves 200; only NEW deploys are blocked, so a finished page can stay stale on the alias.

## Verdict: ~48/day is automation, the rest is chat `/ship` storms

### Two redundant robot deployers (~48/day floor)
| launchd job | fires | deploy behavior | deploys/day |
|---|---|---|---|
| `com.drwu.phone-chat-index` | every 5 min | throttled to 1×/hr via stamp file | 24 |
| `com.drwu.recents-rebuild` | every 60 min | **every run, no throttle, no change-check** | 24 |

Both run the **same** `build_all_chats_dashboard.py` and both do a full `vercel --prod` of the **same** project. One dashboard, two uncoordinated hourly deploys — and most are no-op redeploys of unchanged HTML.

**Evidence:**
- `~/.claude/logs/phone_chat_index.log`: **205** "deployed drwu-htmls (hourly)", **165** "deploy failed", **3,602** correctly-throttled skips.
- `~/Projects/_outputs/chat-recents/_refresh.log`: deployed today at 04:31, 06:20, 07:46, 08:48, 09:55 — each HTTP/2 200.

### Chat `/ship` storms (the rest)
Last 20 prod deploys span 9.3h; median gap ~23 min, but **two landed 1.4 seconds apart** and another **3 fired inside 4 minutes**. That's concurrent chats each running `/ship` → `deploy_htmls_lean.py` simultaneously — the exact multi-chat storm `reference_vercel_hobby_deploy_cap` warns about ("deploy ONE at a time"). The fleet today: 47 queued / 4 in-progress, running all day.

**Arithmetic:** 48 baseline + an active fleet's ship deploys ≈ 100 most days.

## Fix (cheapest first)
1. **(free) Deploy-on-change only** — hash `public/` or the dashboard HTML; skip deploy when unchanged. Kills most of the 48 baseline.
2. **(free) Kill the redundancy** — keep one of the two hourly deployers, let the other rebuild locally only. −24/day instantly.
3. **(free) Shared debounce lock** — one lockfile `/ship` + both jobs check, coalescing concurrent deploys into one per N minutes. Kills the storm bursts.
4. **($20/mo) Upgrade the team to Pro** — removes the 100/day cap entirely. Permanent answer if the fleet stays this busy.

## Confirmed deployers of this project
- `~/scripts/refresh_phone_chat_index.sh` (com.drwu.phone-chat-index)
- `~/Projects/_outputs/chat-recents/refresh_and_deploy.sh` (com.drwu.recents-rebuild)
- `~/.claude/skills/_shared/ship.py` → `~/Projects/drwu-htmls/scripts/deploy_htmls_lean.py` (every chat `/ship`)
