TL;DR
7 min readBluesky allows 300 graphemes per post and X allows 280 characters, rising to 25,000 for Premium subscribers. Bluesky runs on AT Protocol, whose lexicons and account migration endpoints are public, so an account can move hosts and keep its identity; X publishes no equivalent. Reading Bluesky's public API costs nothing and needs no token, while X charges $0.005 per post read and $0.015 per post created, capped at 3 million post reads per billing cycle. Moderation is the sharpest split: Bluesky separates speech from reach through subscribable labelers, X keeps enforcement in-house.
What actually differs in Bluesky vs X?
Any useful Bluesky vs X comparison has to start from what each company publishes rather than what each set of users claims, because the two networks differ on exactly four things you can look up: how long a post can be, who owns the protocol, what the API costs, and who decides what you see. Everything else is taste.
| Bluesky | X | |
|---|---|---|
| Post length | 300 graphemes | 280 characters, 25,000 with Premium |
| Protocol | AT Protocol, public lexicons | proprietary, undocumented |
| API reads | free, no token, public.api.bsky.app | $0.005 per post read |
| API writes | free | $0.015 per post, $0.200 with a URL |
| Read ceiling | not metered | 3 million post reads per billing cycle |
| Moderation | labels from subscribable labelers | in-house enforcement teams |
| Account portability | documented PDS migration | no published equivalent |
How long can a post be on each platform?
Bluesky allows 300 graphemes and X allows 280 characters, which look similar and are measured very differently. The app.bsky.feed.post lexicon sets "maxGraphemes": 300 alongside "maxLength": 3000, meaning a post is capped at 300 user-visible characters but may occupy up to 3000 bytes of storage, which is what lets a 300-emoji post fit. The full mechanics are in the Bluesky character limit.
X counts by weight instead. Its documentation states that "Posts on X can contain up to 280 characters" and then explains that not all characters count equally: Latin text and punctuation weigh 1, while emoji and CJK characters weigh 2, which puts the practical emoji ceiling at 140. Every URL is rewritten through t.co and counts as exactly 23 characters no matter its real length. X's help centre then raises the ceiling for paying users: "Longer posts allow subscribers to post up to 25,000 characters," with the caveat that "Everyone will be able to read longer posts, but only Premium subscribers can create them." X Premium starts at $3 per month or $32 per year in the United States for the Basic tier, rising to $8 and $40 per month for Premium and Premium+. The weighting rules behind the base figure are covered in the X character limit.
So the honest version of this row is that Bluesky's limit is one number and X's limit is three: 280 for everyone, 140 for anyone posting emoji, and 25,000 for anyone paying.
What is the protocol difference between Bluesky and X?
Bluesky runs on AT Protocol, a published specification whose schemas anyone can read and implement, while X runs on infrastructure X Corp does not describe outside its API documentation. The practical form of that difference is the lexicon. Every Bluesky object, from a post to a list to a labeler, is defined by a JSON schema in a public repository, and the record types are namespaced strings like app.bsky.feed.post. Bluesky's own HTTP reference is explicit that the namespace is not reserved to Bluesky: "The wider AT Protocol Lexicon ecosystem is open and any service can publish its own Lexicons."
Nothing comparable exists on X. Its documentation describes endpoints you may call against X's servers. It does not describe a data model anyone else can implement, and there is no second X server.

What does each platform charge for API access?
X charges per request and Bluesky charges nothing for public reads. X moved to pay-per-use credits, and its pricing page states the model without hedging: "The X API uses pay-per-usage pricing. No subscriptions, pay only for what you use."
| Operation | X price |
|---|---|
| Post read | $0.005 per resource |
| User read | $0.010 per resource |
| Post create | $0.015 per request |
| Post create containing a URL | $0.200 per request |
| Owned reads of your own data | $0.001 per resource |
X caps the whole arrangement: "Pay-per-usage plans are capped at 3 million Post reads per monthly billing cycle," with anything above that requiring an Enterprise contract. Resources are deduplicated inside a 24-hour UTC window, so fetching the same post twice in a day is charged once, and X calls that deduplication "a soft guarantee." The longer history of how X arrived here is in Twitter API pricing.
Bluesky publishes no price list because there is nothing to price. Its HTTP reference states that "Most app.bsky.* GETs are public and can be called without authentication against the Bluesky AppView at https://public.api.bsky.app," and describes that host as needing "no token required." Writes need a session, which you create with an app password or OAuth, but creating a session costs nothing. What Bluesky publishes instead of a rate card is a conduct policy: its Developer Guidelines open with "Don't spam" and define spam to include "Generating automated or bulk interactions" and "Any method to automate generating followers or interactions."
That is the real asymmetry. X limits API use with a bill. Bluesky limits it with a rule and the threat of losing access.
How does moderation differ between Bluesky and X?
Bluesky splits moderation into a layer anyone can plug into, and X keeps it inside the company. AT Protocol's moderation guide states the design goal directly: "The atproto model is that speech and reach should be two separate layers, built to work with each other. The 'speech' layer should remain permissive, distributing authority and designed to ensure everyone has a voice. The 'reach' layer lives on top, built for flexibility and designed to scale."
That reach layer is built from labels. Two services produce them. Ozone is described as "a labeling service and web frontend for making moderation decisions," and Osprey as "an event stream decisions engine and analysis UI designed to investigate and take automatic action," maintained by the open source moderation group Roost. Users then choose which labelers to trust, and the docs describe the flow as subscribing "to moderation labelers to have their labels applied in your application." Anyone can run a labeler.
X documents no such thing. What it does document is that enforcement stays with X: even for paying subscribers, "policy enforcement issues and reports by subscribers will continue to be handled by existing enforcement teams, under the current review process," and "The X Rules won't apply differently to subscribers." A user who disagrees with an X moderation decision appeals to X. A user who disagrees with a Bluesky labeler unsubscribes from it.

RedReplier
Get Started
Reddit, X, Bluesky & HN
Real-time intent alerts
Unlimited AI replies
Ranked by buyer intent
Can you move an account off each platform?
AT Protocol documents account migration between hosts and X does not. Bluesky's migration guide walks through four stages with named endpoints: prove control of the identity and call com.atproto.server.createAccount on the new host, where "The new account will be in a deactivated state"; export the repository with com.atproto.sync.getRepo and import it with com.atproto.repo.importRepo; re-upload media, tracking what is left with com.atproto.repo.listMissingBlobs; carry preferences over with app.bsky.actor.getPreferences and app.bsky.actor.putPreferences; update the DID document to point at the new host; then call com.atproto.server.activateAccount.
The part that makes this portability rather than export is the identity. The account keeps its AT Protocol DID through the move, so followers, likes and replies still resolve to the same account on a different server. X offers an archive download. It does not offer a second server to move to.
What this comparison deliberately leaves out
User counts. X has not published a monthly active user figure since it stopped filing as a public company, and no current number for either platform could be confirmed against a company source while writing this. Every side-by-side user total in circulation traces back to third-party estimates rather than to a filing or an official post, so none of them appear above.
Frequently asked questions
Which platform allows longer posts?
X, if you pay. Bluesky caps every post at 300 graphemes with no paid upgrade, while X caps free accounts at 280 characters and raises Premium subscribers to 25,000.
Is the Bluesky API really free?
Public reads are. Bluesky's HTTP reference says unauthenticated app.bsky.* GETs against https://public.api.bsky.app need "no token required," and Bluesky publishes no price list for any tier. Authenticated writes need a session but are not billed.
How much does it cost to read 100,000 posts from X?
$500 at the published rate of $0.005 per post read, before deduplication. X deduplicates repeat reads of the same resource inside a 24-hour UTC window, so the real bill depends on how many distinct posts those requests touch.
Can I use my Bluesky handle on another server?
Yes. AT Protocol documents moving an account between personal data servers while keeping the same DID, using com.atproto.server.createAccount, com.atproto.repo.importRepo and com.atproto.server.activateAccount, among others.
Who moderates Bluesky?
Multiple parties. Bluesky operates labeling services, and the protocol lets anyone run their own labeler, with users subscribing to the ones whose labels they want applied. Bluesky's own account-level enforcement still applies on top.
Does X have anything like Bluesky's labelers?
No published equivalent. X documents its own rules and its own enforcement teams, and provides no mechanism for a third party to publish moderation labels that other users can subscribe to.
How does X's link shortening affect its character limit?
Every URL on X is rewritten through t.co and counts as exactly 23 characters no matter how long the real link is. A long link costs no more of the 280-character budget than a short one does.
What emoji limit does X's character weighting create?
X weighs emoji and CJK characters as 2 units against a 280 character budget, which pushes the practical ceiling down to 140 emoji per post, half of what plain text allows.
What is the difference between Ozone and Osprey?
Ozone is a labeling service with a web frontend for making moderation decisions, while Osprey is an event stream decisions engine with an analysis UI for investigating and taking automatic action, maintained by the open source moderation group Roost. Ozone produces the labels users subscribe to; Osprey drives automated moderation decisions.
What counts as spam under Bluesky's developer guidelines?
Bluesky's Developer Guidelines define spam to include generating automated or bulk interactions and any method to automate generating followers or interactions. Since API reads and writes are otherwise free and unmetered, this conduct rule does the job a rate limit would do elsewhere.
See us more often in Google
One click marks RedReplier as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.
Before you go...
RedReplier
Catch every buyer asking for what you sell
RedReplier watches Reddit, X, Bluesky and Hacker News in real time, ranks every thread by buyer intent, and drafts your reply, so you get there first.
Reddit, X, Bluesky & HN
Real-time intent alerts
Unlimited AI replies
Ranked by buyer intent
Related Articles


How the Bluesky Character Limit Works in Graphemes
The Bluesky character limit is 300 graphemes per post, counted the way a reader actually sees it, and links, mentions and hashtags count in full, unshortened.


What Bluesky Statistics Show About Its User Growth
Sourced from Bluesky's own blog and press coverage, Bluesky statistics trace growth from 1 million users in 2023 to over 43 million, dated and sourced.


Why the AT Protocol DID Is the Identity Bluesky Never Loses
Learn what an AT Protocol DID is, how did:plc and did:web work, why it outlives a changed handle, and how to resolve one to a DID document.

