The cap
100 prod deploys / day · FREE "hobby" plan · team team_jzbv9…XYY. Hit 0 remaining and every new deploy fails 402 free-per-day for 24h. The site keeps serving 200 — only NEW deploys die.
Where the deploys come from (per day)
Two robot timers put ~48 on the board before you touch anything. The active chat fleet (47 queued / 4 in-progress today) piles its /ship deploys on top. 48 + a busy fleet clears 100 most days.
The two redundant robot deployers
| launchd job | fires | deploys | /day |
|---|---|---|---|
com.drwu.phone-chat-index | every 5 min | throttled to 1×/hr | 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. That's the bug: one dashboard, two uncoordinated hourly deploys. Most are no-op redeploys of unchanged HTML.
Evidence — phone_chat_index.log: 205 “deployed (hourly)” · 165 failed · 3,602 correctly-throttled skips. recents/_refresh.log: deployed today at 04:31, 06:20, 07:46, 08:48, 09:55 (each HTTP 200).
The /ship storm signature
The last 20 prod deploys span 9.3h. Median gap ~23 min, but two of them landed 1.4 seconds apart, and another cluster fired 3 deploys inside 4 minutes. That's concurrent chats each running /ship → deploy_htmls_lean.py at once — exactly the multi-chat storm your own memory note warns about (“deploy ONE at a time”).
Source: Vercel list_deployments, all by creator 7onething1-4435, target=production.
The fix (cheapest first)
- freeDeploy-on-change only. Hash
public/(or just the dashboard HTML); skip the deploy when nothing changed. Kills most of the 48 baseline — idle hours stop redeploying identical pages. - freeKill the redundancy. The two hourly jobs build the same dashboard. Keep one deployer, let the other only rebuild locally. Removes 24/day instantly.
- freeShared debounce lock. One lockfile that
/shipand both jobs check, coalescing concurrent deploys into one per N minutes. Kills the 1.4-second storm bursts. - $20/moUpgrade the team to Pro. Removes the 100/day cap entirely. The permanent answer if the fleet stays this busy.