iKit
Guide · 9 min read ·

X's 280-Character Limit: Fit More Into Every Tweet (2026)

The X 280-character limit isn't a raw character count. Learn how weighted counting, t.co URLs, and emoji work — and how to pack more into every post.

X's 280-Character Limit: Fit More Into Every Tweet (2026)

X's 280-Character Limit: Fit More Into Every Tweet

You typed what felt like a short post, X told you you were 12 characters over, and you can't see why. The 280-character limit on X isn't a simple count of the characters on screen — it's a weighted count where a link costs 23, an emoji costs 2, and a CJK character also costs 2. Learn the rules and you stop fighting the counter and start writing to the budget you actually have.

TL;DR

  • Standard X posts are capped at 280 characters; X Premium allows long posts up to 25,000.
  • X uses weighted counting: Latin text is 1, emoji and CJK characters are 2.
  • Every URL counts as exactly 23 characters via the t.co wrapper, no matter its real length.
  • Leading @mentions in replies and attached media count as zero.
  • Your editor's character count lies — use a weighted counter to see the real length.

How does X count characters in a tweet?

The number in the corner of the compose box is not counting the characters you can see. It's running a weighted algorithm, and the difference trips up almost everyone at some point.

Why the limit is weighted, not a raw count

Per the X Developer Platform's character-counting docs, most characters count as 1, but several categories count as 2. So "280 characters" is really a budget of 280 weight units, not 280 keystrokes. A post of pure Latin text gets the full 280 glyphs; a post of pure emoji tops out at 140.

Under the hood, X's open-source twitter-text library defines the rules in a config file. The default weight for a code point is 200, common Latin ranges are re-weighted down to 100, and the whole sum is divided by a scale of 100 — so a normal letter resolves to 1 and an unlisted code point resolves to 2. The max_weighted_tweet_length is 280. You don't need to memorize the internals, but it explains why the counter behaves the way it does.

Latin, CJK, and the 140-character ceiling

Latin letters, digits, and common punctuation each weigh 1. Characters in the CJK ranges — Chinese, Japanese, and Korean, including Hiragana, Katakana, and fullwidth forms — each weigh 2. That's a deliberate design choice: a single CJK character carries far more meaning than a single Latin letter, so a 140-character Japanese post already says as much as a 280-character English one.

If you write in a mix of scripts, the counter adds it up per character. Ten Latin words plus a five-character Japanese phrase isn't "15 characters" — it's the Latin length plus 10 for the CJK.

A quick reference for what counts as what

Here's the weighting in one place:

Content type Weight each Practical max
Latin letters, digits, punctuation 1 280
Emoji (any complexity) 2 140
CJK characters 2 140
Any URL (via t.co) 23 flat

Media attachments and a reply's auto-filled leading @mentions both count as 0, which we'll get to below.

Why does my URL count as 23 characters on X?

This is the single most common source of "but it looks shorter than that" confusion. Links don't count by their visible length at all.

The t.co wrapper explained

Every link you post is rewritten through X's own t.co shortener before it goes out. Because the wrapped form is a fixed shape, X charges a flat rate for it. According to X's docs, any valid URL detected in your text counts as 23 characters, full stop.

https://example.com                 -> 23
https://example.com/very/long/path  -> 23
https://ikit.app/blog/some-article  -> 23

Why a short link and a long link cost the same

The upside: you never gain anything by manually shortening a URL before posting. A bit.ly link and the original 180-character link both count as 23 once X wraps them, so hand-shortening just hides the destination from your readers for no character savings. Paste the real URL and let t.co do its job.

The downside: you can't "reclaim" space by trimming a query string off a link. If you're 5 characters over and your post has a URL, cutting words is the only lever — the link is already at its floor.

Media, hashtags, and leading @mentions

Three more special cases worth committing to memory:

  • Attached media (images, GIFs, video added through an official client) counts as 0 characters. A photo doesn't eat your budget.
  • Hashtags count normally: the # plus every letter of the tag. #OpenSource is 11 characters.
  • Leading @mentions in a reply — the auto-populated names at the start of a threaded reply — count as 0. But any @mention you type into the body counts in full.

That last one is why long reply chains don't run out of room even when they're addressed to eight accounts.

How to fit more meaning into 280 characters

Knowing the rules is half the battle. The other half is writing so the budget goes to words, not overhead.

Front-load the hook

The first line does the heaviest lifting on X. In the timeline, and especially in a truncated long post (more on that below), the opening words decide whether anyone reads the rest. Lead with the claim, the number, or the question — not with throat-clearing like "So I've been thinking about..." Delete the wind-up; keep the pitch.

Trim the filler, not the meaning

Most over-limit posts are 15% padding. The reliable cuts:

  • Drop hedges: "I think," "kind of," "just," "really," "actually."
  • Cut redundant qualifiers: "completely eliminate" -> "eliminate."
  • Replace phrases with words: "in order to" -> "to," "at this point in time" -> "now."
  • Use digits, not words: "5" instead of "five."
  • Skip the trailing URL when the context already implies it, or move it to a reply.

None of these change what you're saying. They change how many weight units it takes to say it.

Count as you write, not after

The worst workflow is writing the whole thought, pasting it into X, and discovering you're 40 over. Draft in a tool that shows the count live so you can feel the ceiling approaching. If you're composing a thread, drafting in a Markdown editor first lets you shape the structure, then split it into posts — and a live word and character counter tells you where each segment stands before it ever touches the compose box.

X Premium and the 25,000-character long post

The 280 limit isn't the whole story anymore. Since X Premium launched longer posts, the ceiling depends on your subscription.

What changed and what didn't

Per X's About X Premium page, subscribers can publish long posts of up to 25,000 characters — enough for an essay. Everyone can read a long post; only Premium subscribers can write one. Crucially, all the counting rules above still apply within that larger budget: URLs are still 23, emoji still 2, leading reply mentions still 0. The number got bigger; the math didn't change.

The 280-character preview still rules the timeline

Here's the catch most people miss. A long post is shown in the timeline truncated to roughly the first 280 characters, with a "Show more" link. Readers scrolling past see only that preview. If your hook, your point, or your call to action isn't in those opening characters, the majority never expand the post. So even with 25,000 characters available, you're still writing the first 280 as if they're all you get.

Draft long, publish short

A practical pattern: write the full argument as a long post if you're Premium, but treat the first paragraph as a standalone 280-character tweet. If it can't stand on its own, rewrite it until it can. That discipline is exactly the skill the 280 limit taught in the first place — the long-post feature just raised the stakes on getting the opening right.

How to count X characters correctly before you post

Your editor, your Notes app, and your CMS all count "characters" differently from X. Trusting them is how you end up 12 over.

Use a weighted counter, not your editor's count

A plain character count treats an emoji as 1 (or as several, if it counts code points), ignores t.co wrapping entirely, and has no concept of CJK weighting. So it can be off by a lot in either direction. To see the real number, use a counter that mirrors X's weighted rules — or at minimum, paste your draft into a live counter and mentally add 23 per link and 1 extra per emoji.

Verify with twitter-text

If you're building anything that posts to X programmatically, don't reinvent the counting logic — call the official library. It handles emoji sequences, URL detection, and Unicode normalization for you:

import { parseTweet } from 'twitter-text';

const result = parseTweet('Ship it 🚀 https://ikit.app');
console.log(result.weightedLength); // includes emoji + t.co weight
console.log(result.valid);          // false if over 280

weightedLength is the number X actually enforces, and valid flips to false the moment you cross 280. That's the same code path X's own clients use.

The three miscounts that catch everyone

Watch for these when a post is mysteriously over:

  • Emoji math: every emoji is +2, and a "family" emoji built from several joined figures is still +2, not +8. (Each one is really several Unicode code points under the hood — the same reason a single emoji becomes a long string when you encode it as an HTML entity.)
  • Accented characters: X normalizes text to Unicode NFC before counting, so café is 4 characters whether you typed a composed é or an e plus a combining accent. The Unicode Normalization spec defines that form.
  • Hidden URLs: any bare example.com in your text is detected as a link and charged 23, even if you didn't mean it as one.

Nail these three and the counter stops surprising you.

References

Related on iKit

Related posts