Module 22Neill's Vibe · Tier 1 · Ship-First-App Scars~8 min

Build for the day the API says no

You fetched hard yesterday. Today a clean deploy can't reach the API at all — and the meter doesn't reset just because you shipped.

01 · the scene

Clean deploy. Every fetch refused.

After a period of heavy fetching, a fresh, clean deploy went out — and then every single fetcher couldn't reach the source. Not a code error; the connection itself was being refused.

floodstream — droplet — Jun 7–8
~/app $ fetch Venue
curl: (7) Failed to connect — Errno 111 Connection refused
(all fetchers, every endpoint. the deploy was clean. yesterday: heavy fetching.)
Neill51% · the terrain

"I shipped a clean deploy and suddenly nothing could even connect. My first thought was I'd broken something. But the code was fine — so why was the door slammed shut today when it was open yesterday?"

Claude49% · the execution

"The heavy fetching the day before tripped a rate limit on the whole account/IP — and the limit applies retroactively, not per-request. A clean deploy doesn't reset the meter. The real lesson isn't 'fetch less' — it's that the fetch path has to survive being refused without corrupting data."

02 · the why

The meter belongs to you, not to the request.

A rate limit is counted against your account or IP over time — not against any single request. So a burst of fetching today can get tomorrow's requests refused, and a successful deploy does nothing to reset it. The deploy and the meter are unrelated systems. The thing you control isn't whether the API ever says no — it will — but whether your app fails closed when it does: never fabricating data, clearly marking the work as a transient failure to retry later.

∑

Counted over time

per account/IP

The limit tallies your usage across requests and minutes — not one call in isolation.

⟲

Deploy ≠ reset

different system

Shipping new code doesn't clear the meter. A clean deploy can still be refused on arrival.

⛉

Fail closed

mark, don't fake

When refused, never fabricate a result. Mark it a transient failure and retry later.

The model: it's a water meter on the whole house, not on a single tap. Run every faucet wide open today and the utility throttles the line tomorrow — installing a brand-new faucet won't change that. You can't make the limit disappear; you design so that when the water's cut, nothing downstream silently fills the glass with something fake.

03 · predict it

Clean deploy, connection refused everywhere. Why?

You fetched heavily yesterday. Today's deploy is clean and green, but every fetcher gets connection refused. What happened?

Not it. The deploy is clean and the code is fine. Focus on what your usage yesterday did to a limit that's measured over time, not per request.
Exactly. Rate limits tally against the account/IP across time and strike retroactively; shipping new code doesn't reset them. You can't prevent the "no" — so design the fetch path to fail closed: mark a transient failure, never fabricate data, retry later. The outage is what validates that path.
04 · the walkthrough

Designing for "the API said no."

detect the refusal
step 1Treat a 429 / connection-refused as an expected outcome, not a crash to swallow.
mark TRANSIENT_FAIL
step 2Record the item as a transient failure to retry — never write a fake or partial result.
back off + retry later
step 3Wait and retry with backoff. The meter clears with time, not with another attempt now.
throttle your own fetches
step 4Cap your fetch rate up front so today's burst doesn't refuse tomorrow's work.
05 · prove it · gate

Teach it back to unlock the payoff.

Same rule as always: answer it right, or the module isn't done.

Since you can't stop an upstream API from rate-limiting you, what's the design that makes the outage survivable instead of corrupting?
// one correct answer unlocks Module 22
Not the load-bearing reason. Hammering retries makes it worse, and faking a result corrupts your data. Think about how to record the failure honestly and recover later.
That's it. You can't prevent the "no," so the design that matters is failing closed: mark it transient, never fabricate, back off and retry. The day the API refuses you is the day that path proves it works. Module unlocked. ↓
the durable idea

You don't control whether the API says no — only what your app does when it does. Fail closed: mark it, never fake it, retry later. The outage validates the path.

06 · factory payoff
⊘ locked — pass the teach-back to claim this piece of the factory

The fetch wrapper that fails closed.

A real safe-fetch.js that detects a rate-limit / connection refusal, returns an explicit { status: 'TRANSIENT_FAIL' } instead of fabricating data, backs off, and throttles your own outgoing rate so today's burst can't refuse tomorrow. Plus a one-page resilience checklist for any app that depends on an upstream API.

✓ Module 22 complete