Build log · week ending 12 October 2026
Two guards for the waitlist form
By Tim
Each week I write up what we built on Noisy Brood: what broke, how we fixed it, and what I learned along the way.
The waitlist sends a confirmation email to each address someone types in. To keep a run of typed addresses from using up my sending reputation, I limit how many go out in a day. This week I found the limit leaked.
A limit that counted too late
The limit counted confirmations already recorded as sent. But a send was recorded after the mail left. Ten requests arriving together each counted the same total, each saw room, and all ten sent. This is a race condition: the result depends on which request gets ahead of which. A test that made one request at a time passed every time.
The fix uses an advisory lock, which is a lock the database holds on a name you choose rather than on a table row. The PostgreSQL documentation on advisory locks covers it. Each join now takes the lock first, claims its slot by setting its send time inside the lock, and the count reads claimed slots instead of sent mail. A send that fails gives its slot back.
Look at the first line inside the transaction:
return sql.begin(async (tx) => {
// One join at a time decides against the cap, and claims its slot by
// setting `confirm_sent_at` before the next may count.
await tx`SELECT pg_advisory_xact_lock(hashtextextended('waitlist:cap', 0))`;
// ...
});
const [row] = await sql<{ claimed: number }[]>`
SELECT count(*)::int AS claimed FROM waitlist
WHERE confirm_sent_at > now() - interval '1 day'`;
The test that reproduces it needs a pool of connections. One connection takes requests in turn and hides the race, so the test opens ten and expects exactly the remaining slots to succeed:
const pool = postgres(db.appUrl, { max: 10 });
const results = await Promise.all(
Array.from({ length: 10 }, (_, i) =>
join(pool, `together${i}@example.test`, T),
),
);
expect(results.filter((r) => "send" in r)).toHaveLength(2);
expect(results.filter((r) => "refused" in r)).toHaveLength(8);
Forms sent from other sites
A page on another site can make each of its visitors’ browsers submit our form, spread over as many addresses as it has visitors. Browsers tell a server where a request came from in a header called Sec-Fetch-Site, described on MDN. The check refuses cross-site before reading the form, and also refuses an Origin that is neither ours nor the string null. A request with neither header is a script, not a browser, so other guards handle it.
export function fromElsewhere(headers: Headers): boolean {
if (headers.get("sec-fetch-site") === "cross-site") return true;
const origin = headers.get("origin");
return origin !== null && origin !== "null" && origin !== SITE;
}
Why it matters
When the day’s confirmations run out, every real person who tries to join is turned away until tomorrow. Holding the limit exactly, and keeping other sites from spending it, means the list stays open to the people it is for.
Noisy Brood files away the mail that doesn’t need you, so the mail that does can find you. We write up what we build each week because every fix like this one is meant to make that a little more reliable. It isn’t open to everyone yet. If you’d like to hear when it can take you, join the list.