Best time to post on Bluesky

Enter a Bluesky handle and this reads up to 300 items from its public feed, throws out the reposts and the replies to other people, and charts what is left across a 7 by 24 grid of day and hour. It runs on the AT Protocol’s free public API, so it needs no login, no app password and no API key, and it works on any public account.

A Bluesky handle is a domain, so alice.bsky.social rather than alice. A bare name is completed to .bsky.social, and a pasted bsky.app profile link or a did:plc: identifier both work.

Try:

How this differs from every other posting-time tool

Bluesky is the only major network whose read API is fully public. public.api.bsky.app serves app.bsky.feed.getAuthorFeedat 100 posts a page with cursor paging and no authentication at all, verified live on 2 September 2026. That means the heat map on this page is built from the same data Bluesky’s own client sees, not from a sample bought through a scraper, and there is no account pool that can run out.

It also means the honest limits are visible rather than hidden. There is no view count in the AT Protocol, so this page never prints one, and it never converts engagement into a reach percentage. The comparison it does make is engagement per 1,000 followers, with the denominator named on the page.

The single biggest error a naive Bluesky analysis makes is treating the author feed as a list of the author’s posts. It is not. Measured on the @bsky.app account on 2 September 2026, 29 of the first 100 items were reposts of other accounts, and requesting the same feed with filter=posts_with_repliesreturned items from 27 distinct authors. Those items carry the original author’s timestamp and like count. Charting them produces a plausible-looking heat map of when other people post.

Two rules remove it: drop any feed item carrying a reason (that is a repost), and drop any item whose post.author.didis not the account you asked about. Neither can be replaced by the endpoint’s own filter parameter, which is applied after the feed is assembled. An unrecognised filter value is not even rejected: filter=bogus answered HTTP 200 with the default feed, so a typo there fails silently.

What the score is built from

The timing score is not a quality score for the account. It answers one question: is this posting schedule regular enough, spread enough and concentrated enough in its own good slots that timing is not costing reach. Cadence, gap consistency, how many days and hours of the week are used, and how many of the top slots hold enough posts to be worth acting on all feed it.

Every central figure on the page is a median, never an average. One post that escapes into a large feed can be fifty times an account’s normal engagement, which moves a mean by an order of magnitude and a median barely at all. A mean-based chart would mostly report which day of the week happened to contain the outlier.

The timezone estimate is offered only above 20 posts, and only when the account actually has a quiet window. An account that posts evenly around the clock is told there is no timezone to infer rather than handed a confident guess, because that pattern usually means a scheduler or a shared account rather than a person in a particular place.

What this cannot tell you

It cannot tell you how many people saw a post. Nothing can: the AT Protocol publishes no impressions, and neither the official client nor any third party has that number for an account they do not own.

It cannot separate the effect of timing from the effect of content. A slot that scores well may simply be the slot the account posts its best material in. The heat map is evidence about correlation across the account’s own history, and the honest way to use it is as a list of slots worth testing, which is how the recommendations are worded.

It cannot see private accounts, and it does not read your following graph, your likes or anything that needs a login, because it never has one.

Frequently asked questions

Does this need my Bluesky password or an app password?

No. It reads public.api.bsky.app, the AT Protocol's unauthenticated public AppView. There is no login, no OAuth, no app password and no API key anywhere in this tool, which is why it works on any public account including ones you do not control.

Why is every hour shown in UTC?

Because that is the only clock the protocol gives us. A Bluesky post record carries createdAt as an instant with no timezone attached, so there is no author-local hour to display. Showing you a bare '3 PM' would mean a different moment for every reader. The tool estimates the account's likely timezone separately, from the gap in the week when it goes quiet, and labels that as an estimate.

Are reposts included in the heat map?

No, and excluding them is the single most important thing this tool does. Measured against bsky.app on 2 September 2026, 29 of the first 100 items that app.bsky.feed.getAuthorFeed returned were reposts of other people, carrying those other people's timestamps and those other people's like counts. Bucketing that into a heat map would chart when strangers post and present it as your best hours. Reposts are dropped, and so is any item whose author is not the account you asked about.

What about replies?

A reply to somebody else is dropped, because its timing was decided by whoever you were replying to. A reply inside your own thread is kept, because that is your own content posted at a time you chose. The result reports all three counts separately so you can see what was used.

Why does it say my best slot is 'too few posts to be confident'?

A week has 168 hour-slots and most accounts have posted a few hundred times, so almost every slot holds one or two posts. Ranking raw slot averages would hand the top recommendation to whichever single post happened to go well. Each slot's score is therefore pulled toward the account's own median by 2 notional posts, and a slot is only marked confident once it holds 3 or more.

Why does it refuse some accounts?

It needs at least 12 of the account's own original posts. Below that there is no pattern to find, only noise, and it refuses rather than draw a chart from four posts. Between 12 and 40 posts it answers but marks the sample thin on the page, because that is enough to see which day someone posts on and nowhere near enough to rank 168 hourly slots.

Why is there no engagement rate against views?

There is no view or impression count anywhere in the AT Protocol. Bluesky does not publish one, so no tool can honestly divide by it. This tool gives engagement per 1,000 followers and names that denominator. Any Bluesky tool quoting you an impression figure is generating it.

How far back does it read?

Up to 3 pages of 100 feed items, so around 300 items, then whatever original posts survive the repost and reply filtering. For a heavy poster that is a few weeks; for a light one it can be a couple of years. The result prints the exact date range it covered.

PlayerSells is not affiliated with Bluesky or Bluesky Social PBC. Every figure on a result is read live from the AT Protocol’s public AppView at the moment you run the tool, from the account’s own public posts, and nothing is stored on your behalf. Endpoint behaviour described on this page was verified against public.api.bsky.app on 2 September 2026.