Last updated: September 2026

Does a link count toward Bluesky's 300-character limit?

Yes. Bluesky gives links no discount: every character of the URL counts toward 300 graphemes. Through the API, and through OpenTweet, a link counts at its full length. The bsky.app composer only shortens how the link is displayed.

That difference is why a post that looks fine in the app can come back too long from a tool, and why a post that fits X can miss Bluesky.

What Bluesky's own maintainers say

In February 2025 someone asked on the atproto GitHub whether Bluesky counts links as 23 characters the way Twitter and Mastodon do. A Bluesky maintainer answered that links "are not counted in any special way", and that every character in the text itself counts the same.

The same reply explains the part that confuses people. The Bluesky app uses rich text facets to show a shortened version of a URL while keeping the full URL as the link target. That is a choice the app makes when you compose there. A post created through the API gets no such treatment unless the client building it does the same thing. Source: atproto discussion #3517 on GitHub.

Why the app and a tool disagree

Paste a long URL into bsky.app and the composer displays a shortened form, so it looks like it costs less. Send the same text through the API and every character of the URL is in the post text. OpenTweet sends it at full length and makes it clickable, so count it at full length.

Do spaces count?

Yes. The limit is 300 graphemes, meaning 300 user-perceived characters, and a space is one of them. So is a line break. There is no Bluesky character limit without spaces: if you are counting words and leaving out whitespace, you are undercounting.

Under the grapheme limit sits a 3,000-byte ceiling. Plain English never reaches it before 300 graphemes. It only comes into play for text made mostly of multi-byte characters.

A quick check before sending: paste the draft into the Bluesky character counter, which counts links at full length the way the API does.

The same link on X

X counts every URL as 23 characters no matter how long it is. That single rule is where most cross-posts that fit X and miss Bluesky come from. As of September 2026:

What
X
Bluesky
Limit
280 weighted characters, 25,000 on Premium
300 graphemes, plus a 3,000-byte ceiling
A link
Always 23, any length
Full length via the API
A space
Counts
Counts
Most emoji
Count 2
One grapheme
CJK characters
Count 2
One grapheme each

Worked example: 180 characters of text plus a 120-character URL. On X that is 180 + 23 = 203, well under 280. On Bluesky, sent through the API, it is 180 + 120 = 300 graphemes, right at the limit. Add one more word and it no longer fits Bluesky, while X still has room to spare.

What OpenTweet does with it

OpenTweet makes links and mentions in a Bluesky post clickable. It does not shorten links, does not attach link cards and does not split long text into a thread. A cross-post over 300 graphemes is skipped on Bluesky with the reason recorded, and still publishes on X.

response.json
{
  "posts": [
    {
      "id": "66f0a1c2e4b0a1c2e4b0a1c2",
      "results": [
        { "platform": "x", "status": "published" },
        {
          "platform": "bluesky",
          "status": "skipped",
          "skip_reason": "This post is 312 characters, over the 300 Bluesky allows."
        }
      ]
    }
  ]
}

If you cross-post often, trim URLs before they go into the draft. The guide to posting on X and Bluesky at the same time covers the other limits that differ, and cross-posting covers how one draft reaches both.

7-day free trial. Cancel anytime.

Frequently asked questions

Does a link count toward Bluesky's 300-character limit?

Yes. Bluesky does not give links special treatment: every character of the URL counts. Through the API, and through OpenTweet, the link counts at its full length. The bsky.app composer shortens how a link is displayed, which is why a long URL can look cheaper in the app.

Do spaces count toward the Bluesky character limit?

Yes. The limit is 300 graphemes of text, and a space is a grapheme like any letter. Line breaks count too. There is also a 3,000-byte ceiling underneath, which only matters for text heavy in multi-byte characters.

How does X count the same link?

X counts every URL as 23 characters, whether it is a short domain or a 200-character tracking link. So a post with a long URL can fit X at 280 and still be over 300 on Bluesky.

Does OpenTweet shorten links or add link cards on Bluesky?

No. OpenTweet makes links and mentions clickable on Bluesky but does not shorten them and does not attach link cards. A post over 300 graphemes is skipped on Bluesky with the reason recorded and still publishes on X. Nothing is truncated or auto-split.

How do I fit a long URL into a Bluesky post?

Trim the URL before it goes in: drop tracking parameters, use the shortest canonical path, or use a link shortener you control. Then check the draft in a grapheme counter that counts the link at full length.

One draft, a result per network

X and Bluesky from one draft or one API call. From $11.99 a month.

7-day free trial. Cancel anytime.