If you're building a Bluesky app, bot, or integration, understanding rate limits is essential. Rate limits prevent abuse, maintain network security, and ensure fair access for all users. This guide explains how Bluesky's rate limits work, the points system for content creation, and best practices for staying within the limits.
What Are Rate Limits?
Rate limits control how many requests or actions you can perform within a given time period. They serve several important purposes:
- Prevent abuse - Stop spammers and malicious actors from overwhelming the network
- Ensure fairness - Give all users equal access to API resources
- Maintain stability - Protect servers from being overloaded
- Detect attacks - Identify brute-force login attempts and other malicious activity
When you exceed a rate limit, the server returns an HTTP 429 (Too Many Requests) response. Your application should handle this gracefully by waiting before retrying.
Content Write Limits: The Points System
Bluesky uses a points-based system for repository record operations (creating, updating, and deleting content). This is the most important rate limit for apps that post content.
Points Allocation
- 5,000 points per hour (per account)
- 35,000 points per day (per account)
Point Values by Operation
- CREATE: 3 points (new posts, likes, follows, etc.)
- UPDATE: 2 points (editing existing records)
- DELETE: 1 point (removing records)
What This Means in Practice
With the hourly limit of 5,000 points:
- ~1,666 posts created per hour (5,000 ÷ 3)
- ~2,500 updates per hour (5,000 ÷ 2)
- ~5,000 deletes per hour (5,000 ÷ 1)
With the daily limit of 35,000 points:
- ~11,666 posts created per day (35,000 ÷ 3)
- ~17,500 updates per day (35,000 ÷ 2)
- ~35,000 deletes per day (35,000 ÷ 1)
These limits are designed with active human users in mind. Normal users will never come close to hitting them. However, prolific bots and automated tools need to be mindful of these thresholds.
Hosted PDS (Personal Data Server) Limits
If your app connects to Bluesky's hosted PDS infrastructure, these limits apply:
General API Limits
- 3,000 requests per 5 minutes (per IP address)
Account-Specific Limits
- Handle updates: 10 per 5 minutes, 50 per day (per account)
- Session creation: 30 per 5 minutes, 300 per day (per account)
IP-Based Limits
- Account creation: 100 per 5 minutes (per IP)
- Account deletion: 50 per 5 minutes (per IP)
- Password reset: 50 per 5 minutes (per IP)
Blob Upload Limits
- Maximum file size: 50 MB per blob
Bluesky AppView Limits
The Bluesky AppView (api.bsky.app and public.api.bsky.app) provides generous rate limits for client applications. The public endpoint is cached and designed for web use cases where you need unauthenticated access.
These limits are intentionally generous to support client applications, but you should still implement proper rate limit handling.
Relay Limits
If you're running your own PDS and connecting to the Bluesky-operated Relay, these limits apply to new instances:
- Repository stream events: 50 per second, 1,500 per hour, 10,000 per day
- New account creation: 5 per second
These limits help prevent spam PDSs from flooding the network with events.
Handling Rate Limits in Your Code
Here's how to properly handle rate limits in your application:
1. Check for HTTP 429 Responses
When you hit a rate limit, the server returns a 429 status code. Your code should catch this and handle it appropriately.
async function makeRequest(url, options) {
const response = await fetch(url, options);
if (response.status === 429) {
// Rate limited - implement backoff
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : 60000;
await sleep(waitTime);
return makeRequest(url, options); // Retry
}
return response;
}
2. Read Rate Limit Headers
Bluesky includes rate limit information in response headers. Monitor these to avoid hitting limits:
RateLimit-Limit- Maximum requests allowedRateLimit-Remaining- Requests remaining in current windowRateLimit-Reset- When the limit resets (Unix timestamp)Retry-After- Seconds to wait before retrying (on 429)
3. Implement Exponential Backoff
When rate limited, use exponential backoff to avoid hammering the server:
async function requestWithBackoff(url, options, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
// Exponential backoff: 1s, 2s, 4s, 8s, 16s
const waitTime = Math.pow(2, attempt) * 1000;
await sleep(waitTime);
}
throw new Error('Max retries exceeded');
}
4. Track Your Usage
For write-heavy applications, track your points usage to stay within limits:
class RateLimitTracker {
constructor() {
this.hourlyPoints = 0;
this.dailyPoints = 0;
this.hourlyReset = Date.now() + 3600000;
this.dailyReset = Date.now() + 86400000;
}
canCreate() {
this.checkReset();
return this.hourlyPoints + 3 <= 5000 &&
this.dailyPoints + 3 <= 35000;
}
recordCreate() {
this.hourlyPoints += 3;
this.dailyPoints += 3;
}
checkReset() {
const now = Date.now();
if (now > this.hourlyReset) {
this.hourlyPoints = 0;
this.hourlyReset = now + 3600000;
}
if (now > this.dailyReset) {
this.dailyPoints = 0;
this.dailyReset = now + 86400000;
}
}
}
Best Practices for Developers
For Client Apps
- Cache aggressively - Don't fetch the same data repeatedly
- Batch requests - Combine multiple operations when possible
- Use pagination - Don't try to fetch everything at once
- Handle 429s gracefully - Show users a friendly message, not an error
For Bots
- Spread activity over time - Don't post 1,000 times in a minute
- Track your points - Know when you're approaching limits
- Implement queues - Buffer posts and release them gradually
- Respect the spirit - Limits exist to prevent spam; don't try to circumvent them
For Feed Generators
- Cache feed results - Don't regenerate on every request
- Use the firehose efficiently - Don't re-request data you already have
- Implement backpressure - Slow down if you're getting rate limited
Different Networks, Different Limits
Remember that Bluesky is built on the federated ATProtocol. Different network providers may implement different rate limits:
- Self-hosted PDS - You control the limits
- Third-party providers - May have their own limits
- Different Relays - May impose different event limits
Always check the documentation for whatever service you're connecting to, and implement flexible rate limit handling that can adapt to different limits.
Growing Your Bluesky Presence Within Limits
Rate limits shouldn't prevent you from growing your Bluesky audience. Here's how to maximize engagement while staying within bounds:
- Quality over quantity - One great post beats ten mediocre ones
- Engage authentically - Reply to others rather than mass-posting
- Use hashtags strategically - Help people find your content
- Post at optimal times - Check our guide on best times to post
Frequently Asked Questions
What are Bluesky's rate limits?
Bluesky uses a points-based system: 5,000 points per hour and 35,000 points per day for content writes. Creating a record costs 3 points, updating costs 2 points, and deleting costs 1 point. API requests are limited to 3,000 per 5 minutes per IP.
How many posts can I create per hour?
With 5,000 points per hour and 3 points per post, you can create approximately 1,666 posts per hour. Normal users will never hit this limit.
What happens when I hit rate limits?
The server returns HTTP 429 (Too Many Requests). Implement exponential backoff and check the Retry-After header to know when you can try again.
Are limits per account or per IP?
Content write limits are per account. General API request limits are per IP address. Some endpoints have both.