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, one of my bots got stuck unable to post on X. The alerts it summarizes kept arriving in the feed, the bot kept reading them, and the public account stayed silent the whole time. X had counted 64 posts, own posts and replies combined, 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 checks a public feed of city alerts, each with its time and address. It reads the new ones, geocodes the address to place it on the map, and posts a summary to the account. There's no AI inside, just a feed reader, 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

Account blocked

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. 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 the nights when the feed fills up with alerts and for X's policy changes, which come without warning.

We left one deliberate exception: urgent alerts 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 alert than the whole account. 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 lightest projects I maintain: 14 work sessions and 116 messages from me in total. What it cost was the account's silence, and you don't get that 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 geocoding