Bluesky Rate Limit Exceeded: What It Means and How Long It Lasts
"Rate Limit Exceeded" on Bluesky is one message covering two unrelated limits, and which one you hit changes the answer from "wait four minutes" to "wait until tomorrow." If it appeared while you were logging in, signing up, or resetting a password, you hit a session limit — and when I tested it on August 3, 2026, bsky.social advertised a policy of 10 attempts per 24 hours, keyed to your handle and your IP address. If it appeared while you were posting, following, or liking, you hit the write budget of 5,000 points per hour, which refills across the hour.
Neither number needs taking on trust. Every response from a Bluesky server carries a header with the exact Unix timestamp your window clears — the app just never shows it to you. Below: how to read that header, what the two limits actually are, and which one you're on.
Why Does Bluesky Say "Rate Limit Exceeded"?
Because a server refused the request with HTTP 429, and there are two entirely different systems that can do that to you. Bluesky's docs put it plainly: "Requests that cross a limit usually receive an HTTP 429 ('Too Many Requests') response status code." What the docs don't do — and what no page I found on this topic does — is tell you which limit you met.
| What you were doing | Which limit | Typical window | What to actually do |
|---|---|---|---|
| Logging in, signing up, resetting a password | Session/account limit, counted per handle + IP | Up to 24 hours (live header, Aug 2026) | Stop retrying. Fix the credential. |
| Posting, following, liking, reposting | Write budget: 5,000 points/hour, 35,000/day | Refills across the hour | Slow down; the ceiling isn't a target |
| Scrolling, searching, loading profiles | General API request cap: 3,000 per 5 minutes per IP | 5 minutes | Almost never you — check your client |
| Reading public data with no login | No rate-limit headers returned at all | — | Not the cause |
The last row is worth pausing on. The public read endpoint (public.api.bsky.app) returns no ratelimit-* headers whatsoever — its response carries caching and CDN headers and nothing else. Reading Bluesky is essentially free. Nearly every "rate limit exceeded" story is a write or an auth problem, which is why "refresh the page" advice does nothing.
The write budget is the one most people have read about, because it's the one Bluesky announced back in 2023: CREATE costs 3 points, UPDATE 2, DELETE 1, against 5,000 points an hour, which Bluesky's own docs translate to "at most 1,666 records per hour and 11,666 records per day." I've written up what that means for following specifically, and it is not the same thing as being labelled as spam — the throttle is mechanical and forgets about you, the label is a moderation decision that doesn't.
But the write budget is rarely what people are hitting when they search this phrase. Run the phrase through a keyword tool and the suggestions that come back are login, password, sign in, verify email, email verification, delete account. That's the auth path, and it's the one nobody has written up honestly.
How Long Does a Bluesky Rate Limit Last?
Exactly as long as the ratelimit-reset header says, which is a Unix timestamp, not a duration. Developers building on the protocol have known this since 2023; what's never happened is anyone telling a locked-out person that the answer to "how long" is sitting in a response header they can read in one command. Four headers come back from a Bluesky PDS:
ratelimit-limit— how many requests this window allows.ratelimit-remaining— how many you have left.ratelimit-reset— the Unix timestamp when the window clears. This is the one you want.ratelimit-policy— the policy inlimit;w=secondsform, so3000;w=300means 3,000 requests per 300 seconds.
To read them, run one command against any Bluesky endpoint and look at the headers:
curl -sS -D- -o /dev/null \
https://bsky.social/xrpc/com.atproto.server.describeServer
Then convert the reset value with date -u -d @<timestamp> (or paste it into any epoch converter). Here's a real one from my own terminal on August 3, 2026 at 16:04 UTC:
ratelimit-limit: 3000
ratelimit-remaining: 2998
ratelimit-policy: 3000;w=300
ratelimit-reset: 1785773317
That timestamp is 16:08:37 UTC — 238 seconds away. Not sixty, not five minutes, not fifteen to thirty: 238 seconds, because the window opened when it opened and doesn't care what a blog post told you.
This matters more than it sounds, because "how long" is a genuinely open question on Bluesky's own issue tracker. social-app issue #5668 is titled "Rate Limit Exceeded Duration Time" and asks whether the duration is indicated anywhere — the reporter had been stuck for more than 12 hours. It's been open since October 10, 2024 and has attracted exactly one comment, from someone asking whether the reporter ever figured it out.
What Are Bluesky's Actual Rate Limits?
Here they are — and where the live server disagrees with the published docs, I've given you both. Everything in the "measured" column I pulled from response headers on August 3, 2026 against bsky.social; everything in the "documented" column comes from Bluesky's rate limits page.
| Limit | Documented | Measured live (Aug 3, 2026) | Documented scope |
|---|---|---|---|
| All API requests | 3,000 per 5 min | 3000;w=300 ✓ |
Per IP |
createSession (login) |
30 per 5 min, 300 per day | 10;w=86400 ✗ |
"Per account" ✗ (see below) |
| Write budget | 5,000 pts/hr, 35,000/day | not testable unauthenticated | Per account |
| Point costs | CREATE 3, UPDATE 2, DELETE 1 | — | Per account |
createAccount (signup) |
100 per 5 min | not tested (would create accounts) | Per IP |
updateHandle |
10 per 5 min, 50 per day | not tested | Per account |
deleteAccount |
50 per 5 min | not tested | Per IP |
resetPassword |
50 per 5 min | not tested | Per IP |
| Blob upload size | 52,428,800 bytes (50 MB) | — | Per blob |
The bold row is the reason this post exists. Bluesky's documentation says the login endpoint allows 30 attempts per 5 minutes and 300 per day. The live server, right now, returns ratelimit-policy: 10;w=86400 — ten attempts per 24 hours. Thirty times tighter than the documented daily figure, on a window shape the docs don't mention at all.
And it isn't a one-day reading. In November 2024 a developer debugging this exact error pasted their response headers into an atproto discussion: ratelimit-limit: '100', ratelimit-policy: '100;w=86400', dated 19 November 2024. Same 24-hour window, ten times the allowance. So over twenty months the login limit has tightened by a factor of ten while the documented figure never moved — which tells you both that the number is real and that it is not a constant. Check it yourself before you build anything on it; I can't promise you it still says 10 next month.
Two things I genuinely can't see from outside, and would want flagged if I were reading someone else's numbers. Every attempt I made returned 401, because I was deliberately using wrong passwords — so I can't tell you whether successful logins are charged against the same counter, or whether this limiter only counts failures. And bsky.social is what the docs call a "central 'entryway'" that "applies similar limits" of its own, while the open-source PDS code self-hosters run configures 300 per day and 30 per 5 minutes, matching the docs exactly. The tighter number looks like something the entryway adds on top, not a change to the protocol.
The scope, though, I can state flatly, because the source code says so and my measurements agree. The docs describe this limit as "measured per account." The code doesn't. The limiter's key is:
${input.body.identifier}-${req.ip}— your handle and your IP address together, not your account alone.
Behaviourally: I made three attempts on one made-up handle and watched ratelimit-remaining fall 9 → 8 → 7 against a fixed reset time (retrying spends attempts, but it does not push the reset further out). I then tried a different handle from the same machine and got a fresh counter at 9. That has two consequences. Changing networks starts a new budget, which is why "try mobile data" sometimes works and why it's a workaround rather than a fix. And on a shared IP — an office, a campus, a VPN exit node, a CGNAT block — the per-handle half means your neighbours' failed logins don't spend your allowance. If you run several accounts, each handle is counted separately, which is one fewer thing to worry about when you run multiple Bluesky accounts.
One of the pages ranking for the "how long" version of this question lists four confident figures — posting at 100 requests per 5 minutes per user, feeds at 300 per 5 minutes per IP, search at 30 per minute per IP, authentication at 10 per minute per IP — attributed to "community testing and the official API documentation." Every one of those numbers is misfiled. The 100 is createAccount's per-5-minute cap, the 300 is createSession's daily allowance, the 30 is createSession's per-5-minute one, and 10 is updateHandle's. They're real numbers from the docs table, shuffled onto the wrong rows with the wrong windows — and Bluesky doesn't meter posting in requests at all, it meters it in points. The page that ranks first for that query is different but no better: it advises stopping all activity for fifteen to thirty minutes, which corresponds to no window Bluesky operates.
How Do I Fix "Rate Limit Exceeded" on Bluesky?
Stop retrying, read the reset time, then fix the credential before you spend another attempt. With a ten-per-day allowance the arithmetic is unforgiving. A script in a retry loop burns it in seconds. A phone and a laptop both holding a stale session token, each quietly re-authenticating, get through it in an afternoon. And app passwords are where this bites hardest, because a revoked app password doesn't fail loudly — it just fails, ten times, until you're out.
In order:
- Stop retrying. This is the whole fix and it's the one people skip. Each attempt spends allowance you don't have.
- Read the reset time with the curl above, and treat it as the answer.
- Fix the credential before you spend another attempt — generate a fresh app password under Settings → Privacy and Security → App Passwords rather than trying to remember the old one.
- Kill anything automated pointed at the account until you're back in. Third-party clients, scripts, cron jobs.
- Only then consider a different network, understanding that you're starting a new counter rather than clearing the old one.
Two neighbouring cases worth separating out, because they get filed under this error and aren't the login limit. Signing up goes through createAccount, capped per IP rather than per handle — which is why social-app issue #2859, where someone hit this while trying a second username during signup, was solved by switching networks. And the November 2024 case above turned out not to be a limit problem at all: the developer was passing environment variables as a prefix to curl rather than exporting them, so every request went out with a malformed body and was counted as another failed attempt. Worth checking your own tooling before you blame the server.
Where Does Agent Sky Fit?
Any tool that touches Bluesky on your behalf has to answer this question, and most of them answer it badly — they catch the 429, sleep for some hardcoded interval, and try again. If that interval is shorter than the real window, the retry itself is what keeps you limited.
Agent Sky reads the header. When a login comes back 429, the code pulls ratelimit-reset off the response, parses it as a Unix timestamp, and parks that account until exactly that moment — falling back to a conservative 60 seconds only if the header is absent or unreadable. That's the whole mechanism, and I'm spelling it out in this much detail because it's a few lines of code that any tool could have written and most didn't.
The write side matters more for anyone growing an account, and there the honest answer is that the rate limit was never the binding constraint. The default settings work through 50 to 100 follows a day, two to five minutes apart, and the built-in floor is gentler still at 5 to 20 — against a documented ceiling of 11,666 records a day, that's roughly two orders of magnitude of headroom. The reason isn't caution about the throttle. It's that the pace that looks like a bot starts far below the throttle, and a moderation signal doesn't reset on the hour the way a points budget does. The free tier runs the same loop; $9/month is what the paid one costs.
None of that helps you today if you're locked out as you read this. Read the header, wait for the timestamp it names, and rotate the app password while you wait — no tool required, and nothing on this page will get you back in any faster.
Quick FAQ
What does "rate limit exceeded" mean on Bluesky? It means a server refused your request with HTTP 429 because you crossed one of two completely separate limits. If you were logging in, signing up, or resetting a password, you hit a session limit counted per handle-and-IP pair. If you were posting, following, or liking, you hit the write budget: 5,000 points per hour and 35,000 per day, where each create action costs 3 points. The message is identical either way, which is why so much advice about it is wrong — the two limits have different windows and different fixes.
How long does a Bluesky rate limit last?
It depends which limit you hit, and the exact answer is in the response header rather than in any article. Bluesky returns a ratelimit-reset header containing a Unix timestamp of the moment your window clears. On August 3, 2026 a login attempt against bsky.social returned a reset roughly 24 hours out; a general API request returned one about 4 minutes out. The write budget refills hourly. Anyone quoting a single number for all of them is guessing.
Why does Bluesky say rate limit exceeded when I log in? Because login attempts are counted separately from everything else, and the allowance is much smaller than people expect. When I tested bsky.social on August 3, 2026, the response header advertised a policy of 10 attempts per 24 hours, keyed to the combination of the handle you typed and the IP address you typed it from. Bluesky's published documentation lists 30 per 5 minutes and 300 per day for this endpoint, so the live number is far tighter than the docs suggest. A few mistyped passwords can genuinely lock you out until the next day.
How do I fix Bluesky rate limit exceeded?
Stop retrying first — each attempt spends allowance you don't have, and on the login path you may only have ten for the day. Read the ratelimit-reset header to get the exact moment your window clears, then fix the credential before you spend another attempt: generate a fresh app password rather than guessing at the old one. Switch off anything automated pointed at the account until you are back in. If it was posting or following rather than logging in, just slow down — the write budget refills over the hour.