Why Bluesky scheduling is different from every other network
Most major networks expose a scheduled_time or publish_at field in their publishing API. You hand the network a timestamp and the network does the work. Bluesky does not have one. Bluesky runs on the AT Protocol, and a post is a repository record of type app.bsky.feed.post with a text field and a createdAt timestamp. There is no field that says "not yet, publish later."
That means a Bluesky scheduler is, mechanically, a small server with a timer attached. It stores your draft, sleeps, and at the due moment calls com.atproto.repo.createRecord on your personal data server. There is no trick to route around it and no native fallback if your scheduler is down at 9:00am.
Here is the comparison that matters, and it is the one most "best scheduler" lists get wrong:
The native-scheduler myth
Mastodon has scheduled single posts built into its own web and mobile clients for years. People assume "the fediverse" works the same way. It does not. Bluesky's app still has no scheduler at all, so a tool that promises to post on Bluesky is promising to do the publishing itself.
What actually works
A scheduler that connects to Bluesky with an app password, holds the post, and publishes it on a timer. Postiz treats Bluesky as a first-class channel alongside Mastodon, Threads, and X — one calendar, one composer, per-channel copy adjustments when the character limits differ.
What "schedule Bluesky posts" actually requires
Before choosing a tool, know the four constraints you are signing up for. Each one kills a naive setup.
1. An app password, not your account password
Bluesky will not accept your login password for third-party publishing. You generate an app password in Settings → App Passwords, with at least atproto.create scope. The tool trades that token for a session and publishes as you. Postiz asks for the handle and app password straight from the channel setup screen — no environment variables, no callback URLs to register. You can also revoke an individual app password later without touching your account password or other sessions.
2. A 300 grapheme limit, not 300 characters
Graphemes are user-perceived characters, so an emoji or an accented script eats more budget than it looks. Long posts are the single most common reason a scheduled Bluesky post fails validation at the composer.
3. Media rules that differ per network
Images upload as blobs through com.atproto.repo.uploadBlob with a 2 MB limit, and up to four can ride along on one post. Video travels the same record path. The same asset does not have identical rules on Mastodon, so a cross-post needs per-channel handling rather than a single global payload.
4. Per-post visibility and content warnings
Mastodon exposes a visibility level (public, unlisted, followers-only, direct) and content-warning fields per post. Bluesky does not have those concepts. If you run both, one shared payload will not cover them — you need a composer that stores a per-channel variant.
{"text": "Shipped the 2.4 release today. Full changelog on the blog — link in replies.", "createdAt": "2026-10-23T14:00:00Z"}
Mastodon — 500 char default, visibility + CW supported:
{"status": "Shipped the 2.4 release today. Full changelog on the blog: https://example.com/changelog", "visibility": "unlisted", "scheduled_at": "2026-10-23T14:00:00Z"}
Note the asymmetry in the last line. Mastodon accepts scheduled_at and the network publishes it. Bluesky has no equivalent field, so the same scheduler that hands Mastodon a future timestamp has to hold the Bluesky post in its own queue and call createRecord at 14:00. Understanding that difference is the difference between a tool that works and a tool that silently posts three hours late.
Three ways to schedule Bluesky posts, honestly compared
Option 1 — Bluesky-native and Mastodon-native tools
These are the fastest for a single network. A Bluesky-only scheduler can offer genuinely better per-platform timing suggestions than a generalist, and Mastodon's own client handles scheduled posts with no third party involved at all. The catch is obvious: you are running two separate calendars, two approval flows, and two sets of analytics. If your audience overlaps between a Mastodon instance and Bluesky, that is a real cost in daily effort, not a rounding error.
Option 2 — Unified schedulers
Buffer, Hootsuite, Sprout Social, and Postiz all reach Bluesky, and each treats it as one channel among many on a shared calendar. The strength is operational: one content calendar, one team approval flow, one analytics view. The weakness is that the Bluesky integration gets the same generic treatment as the others — you will still write a short Bluesky variant by hand unless the tool supports per-channel copy, which is exactly why per-channel editing is worth checking for before you pay.
Option 3 — DIY with cron and the AT Protocol SDK
If you already run infrastructure, this is viable and free. The AT Protocol SDK makes creating a post a short script. The hard parts are not the API call — they are session refresh, media upload, retries when the PDS is briefly unavailable, and the queue surviving a restart. The honest cost is maintenance: someone has to own the timer, and when it breaks the post simply does not go out.
Key Takeaways
- Bluesky has no native scheduler and no
scheduled_timefield — every tool that posts there is publishing on your behalf at the due minute. - Mastodon does schedule natively, which is why the two networks behave differently even though both use the AT Protocol.
- Connection requires an app password with
atproto.createscope, generated in Bluesky Settings, not your account password. - The real limit is 300 graphemes, with 2 MB image blobs and a four-image maximum per post.
- Per-channel copy is not a nicety — the same payload cannot satisfy a 300-grapheme Bluesky post and a Mastodon post with a visibility setting.
What Postiz does with Bluesky and Mastodon specifically
Postiz is an open-source social media scheduling platform (AGPL-3.0) with a hosted cloud tier and a self-hostable edition. Bluesky is one of 30-plus channels it publishes to, alongside Mastodon, Threads, X, LinkedIn, Instagram, TikTok, YouTube, Reddit, Pinterest, Discord, Slack, Telegram, and newer additions like Warpcast, Lemmy, Nostr, and MeWe.
The parts that matter for a fediverse workflow specifically:
- Bluesky connects with no configuration. The Bluesky provider guide is short because there are no environment variables to set — you add the account from the UI and start posting. Mastodon is the harder one, because instance OAuth clients must be registered via the API and the credentials placed in your
.env. - Any instance works. Mastodon connections are not limited to
mastodon.social. SetMASTODON_URLto your instance and register a client against it. - Per-channel editing is native. Write one post, then shorten and adapt it for Bluesky's 300-grapheme budget while keeping the longer, visibility-tagged Mastodon version intact.
- Everything lands on one calendar with drag-to-reschedule, recurring posts, RSS auto-posting, team approvals, and analytics pulled from each network's own insights API.
-F "client_name=YourPostiz" \
-F "redirect_uris=http://localhost:5000/integrations/social/mastodon" \
-F "scopes=write:statuses write:media profile"
# then add to your .env:
MASTODON_CLIENT_ID="your_client_id"
MASTODON_CLIENT_SECRET="your_client_secret"
MASTODON_URL="https://mastodon.social"
How to schedule Bluesky posts in three steps with Postiz
- Add the channel. Open the channel settings, pick Bluesky, and paste your handle and app password. The tool handles the session exchange. Add Mastodon next if you run one — that one asks for your instance and client credentials.
- Write once, adapt per channel. Compose the post, then open the Bluesky preview and trim to 300 graphemes. Leave the Mastodon preview at full length and set its visibility and content warning there. Attach media and confirm it clears the per-network size limits.
- Queue it on the calendar. Drag it into a slot or import a batch from CSV, then let the timer handle the publish. Bluesky goes out through the session you authorized; Mastodon goes out through the
scheduled_atfield the network understands.
If you would rather not operate a server at all, the cloud tier runs from $29 per month for 5 channels, $39 for 10, $49 for 30, and $99 for 100, with unlimited posts per month and a 7-day free trial on every plan. Self-hosting the open-source edition costs $0 in licence fees and gives you the same channel list — see the Postiz GitHub repository and its installation docs if you want to run it on your own infrastructure.
Ready to schedule Bluesky posts on a real calendar?
Postiz connects Bluesky, Mastodon, and 28+ other networks from one dashboard, with per-channel copy, a 7-day free trial, and an open-source edition you can self-host for free. If you have been managing a cron job by hand, this is the part that stops being work.
Try Postiz free for 7 days →Choosing a Bluesky scheduler: what to check before you pay
- Per-channel copy editing. If the tool only has one global text field, you will be rewriting every cross-post by hand.
- How it holds the queue. Does a missed publish retry? Does a restart lose drafts? A scheduler with no retry path will eventually drop a post.
- Grapheme counting, not character counting. If the counter is naive, your emoji-heavy posts will pass validation and then fail at publish time.
- Media handling per network. Confirm the tool respects the 2 MB Bluesky blob limit rather than accepting a 4 MB upload and failing later.
- Whether Bluesky counts against your channel limit. In Postiz each connected account is one channel, so a six-account setup lands on a specific tier — worth calculating before you commit.
- Whether Mastodon-native scheduling is bypassed. If your tool hands Mastodon a
scheduled_at, the network publishes even if your scheduler is offline. That is a genuine reliability advantage over the Bluesky path, and it is worth knowing which side of the line a tool falls on.
Frequently Asked Questions
Does Bluesky have a built-in post scheduler?
No. The Bluesky mobile and web apps have no scheduler, so any tool that schedules Bluesky posts must hold the content and publish it at the due time on your behalf. Most connect with an app password rather than OAuth, create an app.bsky.feed.post record, and respect the 300 grapheme limit. Postiz handles this from one shared calendar alongside every other channel.
How do I connect Bluesky to a social media scheduler?
Bluesky requires an app password, not your account password. In Bluesky Settings, open App Passwords, create one with atproto.create permission, and paste the generated string into the scheduler's Bluesky connection screen. The tool exchanges it for a session and can then publish as you. Postiz asks for the handle and app password directly from the UI, with no environment variables to configure.
Can I post to both Bluesky and Mastodon from one calendar?
Yes, and this is where unified schedulers earn their keep. Mastodon publishes natively and Bluesky does not, so the two need different handling despite both running on the AT Protocol. Postiz treats them as separate channels on the same calendar, letting you write once, tailor copy per channel, and publish to both. Each connected account counts as one channel toward your plan limit.
Is it safe to connect Bluesky with an app password?
An app password is scoped and revocable. You can create several, give each tool one, and revoke that single token later without changing your account password or logging out other sessions. Treat it like an API key: store it in a password manager, never paste it into a public repository, and rotate it if a tool you no longer use still holds a copy.
What is the Bluesky character limit for scheduled posts?
Bluesky counts 300 graphemes per post, not characters, so emoji and non-Latin scripts consume more room than they appear to. Images upload as blobs with a 2 MB limit, and up to four can be attached to one post. Video travels the same record path. Cross-posting from a longer network therefore needs a shorter version, which most schedulers let you set per channel.
How much does a Bluesky scheduler cost?
Bluesky-capable schedulers usually bundle it into a paid plan. Postiz runs from $29 per month for 5 channels, $39 for 10, $49 for 30, and $99 for 100, all with unlimited posts per month, a 7-day free trial, and an open-source edition you can self-host for free. Every connected account counts separately toward the channel limit.
Conclusion
Learning how to schedule Bluesky posts is less about discovering a hidden feature and more about accepting that Bluesky does not have one. Because the AT Protocol has no scheduled_time field, the scheduler is the publisher — which makes reliability, retries, and a durable queue the things that actually matter, not the interface polish.
Pick a tool that treats Bluesky as a real channel with its own 300-grapheme budget and its own app-password flow, lets you write one post and adapt it per network, and keeps Bluesky and Mastodon on the same calendar even though the two publish by different mechanisms. If you want to stop hand-rolling timers, get started with Postiz and connect Bluesky in the next five minutes.