BlogLessons

Midnight doesn't count

Our counter allowed 96 posts in 24 rolling hours and X blocked the bot at post 64

Nicolás Biondi

A long line of light dots across the floor and a cyan frame enclosing one stretch, under a crescent moon.

On August 12, 2026, the emergency bot went 11 hours without being able to post. The emergencies kept happening, the scraper kept reading them, and the public account stayed silent the whole time. X had counted 64 posts inside its window and shut the door. My counter, meanwhile, was looking at the clock on the wall and feeling good about two quiet days.

The rate limit counter did exactly what I wrote, and that's why it took me a while to suspect it.

Every two minutes, no AI

Every 2 minutes the bot logs into the fire department's dispatch system, reads the new emergencies, geocodes the address and posts a summary. There's no AI inside, just a scraper that reads the page, a geocoder and a posting budget.

That budget exists because X allows around 50 of your own posts per day plus 200 replies, with extra caps for each half hour. We set ourselves a more conservative internal cap and considered the matter closed.

Two ways to count the same night

Our counter reset at midnight, Lima time. X's counter never resets: it looks back 24 hours from the exact moment it checks.

Reconstructing that day is short and embarrassing. The bot posted around 48 times up to 23:00 and filled the day's budget. Midnight put the counter at zero and the bot kept posting as if it were another day: our counter allowed it to reach 96 in 24 rolling hours. In our notebook those were two quiet days; X, which looks at the last 24 hours, counted 64 inside its window and triggered the block.

The same thing happens with a gym that resets your visit counter at midnight: you go in at 23:00, leave, come back at 00:30, and in your notebook those are two different days. The turnstile counts the last 24 hours and knows it was the same night.

Meme Woman Yelling At Cat: The counter reset to zero! / I count 24 rolling hours The counter reset to zero! I count 24 rolling hours

23:00, 48 posts

Midnight: counter to zero

The bot keeps posting

Our count: two days

X's window: 64

11-hour block

The same stretch counted by calendar day and by rolling window

The penalty used the same calendar

My first theory was that X had flagged us for the content or for posting with browser automation. I lost a while there: the texts had nothing strange in them, and the pace, seen day by day, didn't either.

The mistake was duplicated in the cooldown, the pause the bot imposes on itself when it hits the cap. On stopping, it slept until the following midnight, because midnight was its only idea that the limit had passed. Old posts leave X's window on their own schedule, not when the day changes, so the bot woke up just as blocked and went back to sleep.

How the budget ended up on August 13

The budget became a rolling 24-hour window with a cap of 45 of our own posts (replies count separately), a maximum of 2 per half-hour slot and at least 30 minutes between one and the next. Each post saves its timestamp to disk, so a process restart no longer starts counting from zero. That had happened to us too.

We didn't raise the cap to the platform limit. 45 against 50 leaves room for nights with back-to-back emergencies and for X's policy changes, which come without notice.

We left one deliberate exception: critical emergencies sort first in the queue and can use a shorter spacing than the general one. The urgent stuff goes out on time even if we post less that day.

Since the fix there's been no other block

On busy days the bot posts less, and that's on purpose: we'd rather lose the summary of a minor emergency than 11 full hours. It's still open that X's limits aren't published precisely and aren't stable, so our 45 is an informed bet nobody confirmed for us.

This bot is one of the cheapest projects in the system, 14 work sessions and 116 messages from me in total. What it cost was the 11 hours of silence, and you don't get those back the next day. The rest of the defenses already reasoned in rolling windows (the geocoding cache with a 30-day life, the retry queue with a cap on attempts) and none of them repeated the mistake.

The rule now lives in the repo's AGENTS.md, the file any AI agent reads before touching the code: when you touch a limit, reason in rolling windows and never in calendar days. The budget was the only one congratulating itself at midnight, and X's turnstile doesn't look at the clock on the wall.

postmortem rate-limits rolling-window bots scraping