Pass Muster follows writers instead of platforms. One page shows a writer's Substack posts, YouTube videos, Bluesky posts and live shows, and each writer can get their own site built from all of it.
That creates a tension every aggregator has. Readers want it fresh: a new post or a show going live should appear within minutes. But none of that data is ours. It lives on Substack, YouTube and Bluesky, and if we asked them for it every minute for every writer, we'd be the bad guest who gets rate-limited, or blocked.
Our answer comes down to three rules: check often when someone is looking, check rarely when no one is, and learn when to expect things.
Rule 1: the page only asks while you're looking
The pages are static files on Cloudflare. The archive is built ahead of time, so a visitor gets everything instantly with no server work. The live parts are small top-ups on a timer, and each source gets its own pace:
- Live shows: every minute, because a show that started 10 minutes ago is old news.
- New Substack and Bluesky posts: every 3 minutes.
- YouTube: every 10 minutes, the slowest, because YouTube's official API has a daily quota.
Every timer checks one thing first: is this tab visible? Browsers expose that through the Page Visibility API (document.hidden). A tab in the background, or a phone in a pocket, asks for nothing. When you come back to the tab, it catches up once, right away.
So ten people with a writer's page open in background tabs cost the same as zero.
Rule 2: the server spends its checks where people are looking
Behind the pages is one small server function (a Supabase Edge Function) that wakes up once a minute. It can't check every writer every minute, so each run it decides who goes first:
- Writers with a page open right now. Every time a visible page polls, it tells the server "someone is reading this writer." For the next 5 minutes, that writer jumps the queue and gets checked about every 3 minutes. Up to 8 of these per run.
- Writers who are due. Everyone else waits for their next scheduled check, up to 10 per run.
- Quiet writers, rarely. Someone who has never streamed gets their Substack activity feed read every 3 hours. That feed is about 400 KB, so reading it every minute for hundreds of writers would be pure waste.
The effect: attention is the signal. The writers people are actually reading stay fresh, and the long tail costs almost nothing.
Rule 3: learn when to expect things
Most creators keep a rhythm: the same show, same weekday, same time. So the server remembers when each writer's streams actually started (not when they were scheduled; people start late), keeping the last 40 start times. From those it works out each writer's usual slots on a weekly cycle.
Put the three rules together and every writer ends up on one of these schedules:
| Situation | How often we check |
|---|---|
| Someone has their page open | every 3 min |
| Inside their usual show slot (15 min before to 75 min after) | every 3 min |
| Streams sometimes, no pattern yet | every 5 min |
| Known streamer, outside their usual slots | every 20 min |
| Has never streamed | every 3 hours |
| A show on the schedule, starting within 15 min | every minute |
| A show days away (in case it moves or is cancelled) | every 30 min |
A scheduled show that never starts drops off after 6 hours instead of being checked forever. The same history powers the calendar: a writer's site can label a show "daily," "weekly" or "one-off" because the server has seen when they really go live.
Being a good guest
The three rules decide when to look. A few guardrails make sure that looking stays polite:
- One fetch serves everyone. Posts are cached per publication on our side. A page asks for "no older than 3 minutes," and if the cache is fresh enough, it's served from there. A hundred people reading the same writer means one request to Substack every few minutes, not a hundred. YouTube channels get the same treatment with a 10-minute floor.
- Hard caps per run. At most 18 activity feeds per minute, 3 at a time. YouTube show details come in batches of 50 per API call, so a whole lineup costs one unit of quota.
- Back off together. If Substack answers "429, slow down," every part of the system pauses that service for 10 minutes. The pause is stored in the database, so no other copy of the function keeps knocking. Pages keep getting the cached answer meanwhile.
- Jitter. Each next-check time is nudged up to 20% either way, so hundreds of checks don't land on the same second.
Did we invent this? No, and that's the point
Every piece has a long history. Gmail and X only refresh visible tabs. Feed readers check popular feeds more often than quiet ones. Search engines visit busy sites more often and slow down when a server pushes back. HTTP caching has had "serve it if it's fresh enough" for decades.
What we're proud of is the fit. Reader attention drives server effort, and learned habits fill the gaps when nobody is looking. The result: live shows appear within minutes, and the whole thing runs on small, cheap pieces without hammering the platforms it depends on.
If you're building anything that reads someone else's data, here's our takeaway: let attention set the schedule. Check hard where people are looking, gently everywhere else, and keep a memory so you know when to look again.