Why drwu-htmls burns the 100/day Vercel cap

Live deploy log + launchd + run logs, pulled 2026-06-25.

VERDICT: ~48/day from robot timers, the rest from chat /ship storms

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)

phone-chat-index — 24
recents-rebuild — 24
chat /ship storms (fleet) — ~50+ on active days

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 jobfiresdeploys/day
com.drwu.phone-chat-indexevery 5 minthrottled to 1×/hr24
com.drwu.recents-rebuildevery 60 minevery run, no throttle, no change-check24

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 /shipdeploy_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)

  1. 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.
  2. freeKill the redundancy. The two hourly jobs build the same dashboard. Keep one deployer, let the other only rebuild locally. Removes 24/day instantly.
  3. freeShared debounce lock. One lockfile that /ship and both jobs check, coalescing concurrent deploys into one per N minutes. Kills the 1.4-second storm bursts.
  4. $20/moUpgrade the team to Pro. Removes the 100/day cap entirely. The permanent answer if the fleet stays this busy.

Explain like I'm 5

Your website has a rule: it can only be re-published 100 times in one day. After that, it says “come back tomorrow.”

Two robot clocks on your computer re-publish the same page every hour, all day. That's already about 48 times before you do anything.

Then lots of your helper chats each ask to publish too, sometimes at the very same second. Add those up and you blow past 100.

The easy fix: only re-publish when the page actually changed, and let just one robot do it. Then you almost never run out.