X (Twitter) Character Counter

Social Media Text
0 Characters
0 Hashtags
0 Mentions
0 URLs
0 Line breaks
0 Paragraph breaks
Detected
Hashtags
Mentions
URLs

Introduction

X counts posts with a system most people have never heard of: weighted characters. Links collapse to exactly 23 characters no matter how long they are, Chinese/Japanese/Korean glyphs and emoji weigh twice as much as English letters, and a handful of Unicode ranges get special treatment. The result is a limit that regularly surprises – a draft that looks safely under 280 gets rejected, and nobody can see why.

The Toollect X (Twitter) Character Counter applies the real rules, not a naive string length. Paste a draft and six counters update as you type – weighted total, hashtag count, mention count, URL count, line breaks and paragraph breaks – alongside lists of every hashtag, mention and link the platform-style parser detects. The detection boundaries were verified case by case against live x.com behavior, including the odd corners: ##Japan extracts but #Japan# does not, .@alice detects while !@alice does not, and handles keep matching up to 20 characters even though new accounts stop at 15.

Everything runs locally in your browser. There is no API key, no sign-up, and no request of any kind – your draft never leaves your device, and the numbers stay instant because nothing waits on a network.

Use Cases

Social media managers checking scheduled posts

Scheduling tools frequently miscount X drafts because they use plain length. Run the copy through this counter before queueing – the weighted total and the URL list tell you exactly what X will accept, and the over-limit warning appears the moment the draft crosses the line.

CJK writers fighting silent truncation

Japanese, Chinese and Korean posts fit roughly 140 glyphs into the same budget an English post uses for 280. Seeing the weighted number next to your draft turns the invisible doubling into something you can plan around instead of discovering after publishing.

Developers building bots and automation

If your bot composes tweets programmatically, this counter doubles as a specification reference: the weight ranges, the fixed URL cost, and the hashtag/mention boundary tables document the exact rules the parser implements, case by case.

Cross-platform writers

Adapting one message across platforms means respecting different limits and different math. Pair this tool with its sibling, the Instagram Caption Analyzer, and you can check both destinations without guessing which platform weighs what.

How It Works

The counter runs four steps entirely in your browser, updating live on every keystroke:

  1. Normalize the text. The input is converted to Unicode NFC form first, so a decomposed é (letter plus combining accent) counts once instead of twice – matching how X itself normalizes before counting.
  2. Extract and flatten URLs. Every link X recognizes is pulled out and replaced with a flat cost of 23 characters – both https:///http:// addresses and protocol-less domains such as twitch.tv whose ending sits on the official top-level-domain lists. Trailing punctuation such as a sentence-ending period stays with the surrounding text rather than the link.
  3. Segment into grapheme clusters. The remaining text is split by Intl.Segmenter into user-perceived characters – so an emoji family built from seven code points, a flag built from two, and a skin-toned thumbs-up each form exactly one unit.
  4. Weigh each cluster. Clusters containing emoji weigh 2. Everything else sums its code points against the official light ranges – 1 if inside, 2 if outside. Hashtags and mentions are extracted separately from the link-free text using the x.com boundary rules documented below.

Changing any option re-runs the whole chain instantly. Nothing is sent anywhere and nothing is cached between sessions.

The Weighted Counting Rules

This is the complete weight table the counter applies, matching the public twitter-text configuration X builds on.

Characters Examples Weight
U+0000 – U+10FF Latin, Greek, Cyrillic, Hebrew, Arabic, Hindi, Thai, punctuation, digits 1
U+2000 – U+200D General punctuation and the zero-width joiner 1
U+2010 – U+201F Dashes and typographic quotes 1
U+2032 – U+2037 Prime marks 1
Everything else Chinese/Japanese/Korean, Hangul, emoji, most other scripts 2

Three special rules sit on top of the table:

  • Every link costs 23. Any address the parser recognizes flattens to exactly 23 characters regardless of its true length – https:// and http:// URLs plus protocol-less domains like twitch.tv. A lookalike whose ending is not a real top-level domain (foo.zzz) stays ordinary text.
  • Emoji clusters are atomic. Detection works on grapheme clusters, so 👨‍👩‍👧‍👦 counts as one cluster (weight 2), flags count as one, and skin-tone modifiers merge into their base emoji. Without clustering, that family would wrongly add eleven code points.
  • Accents collapse before counting. Text is normalized to NFC, so café typed with a decomposed accent counts as 4 characters, not 5.

A worked example – the draft Read more about the mission 🚀 https://x.com/a/long/path:

Part Computation Cost
Read more about the mission 27 light characters 27
🚀 one emoji cluster 2
space 1 1
https://x.com/a/long/path flattened URL 23
Total 53

Hashtag and Mention Boundaries

Detection follows the boundaries observed on live x.com across 36 verified test cases – including several that contradict common assumptions. The tables below list the decisive ones.

Hashtags

Input Result Rule
#Japan at start, after a space Standard case
🇯🇵#Japan, !#Japan, .#Japan, ,#Japan, -#Japan Emoji and these punctuation marks do not block the hash
abc#Japan, 123#Japan A letter or digit glued in front cancels it
_#Japan Underscore blocks too
&@mention, &#Japan Ampersand blocks (HTML-entity safety)
@#Japan An at-sign directly before the hash does not block
##Japan, ##Japan, #Japan Extra hashes – halfwidth or fullwidth – do not block
#Japan#, #Japan#Japan, #Ja#pan A hash immediately after the tag kills it, and no partial retry happens
#123, #123, #🇯🇵 Tags need at least one letter or the run never forms
#1Direction, #日本語, #foo_bar Digits mixed with letters, Unicode tags and underscores all work

The #Japan# family surprises most people: the tag text itself is fine, but X discards the entire candidate when another hash sits directly against its end, and the parser never falls back to a shorter match.

Mentions

Input Result Rule
.@alice, ,@alice, ?@alice, :@alice, (@alice, /@alice, -@alice These punctuation marks allow the mention
🇯🇵@alice Emoji allows it too
!@alice An exclamation mark blocks mentions – stricter than hashtags
@@alice, #@alice, &@alice, abc@alice, 123@alice At/hash/ampersand/word characters all block
@alice@bob ✗ both Handles followed directly by another at are discarded
@alice's post ✓ alice The possessive stays outside the handle
@15chars_max_0000 (16 chars) ✓ full handle The parser matches up to 20 characters – account creation stops at 15, detection does not
@12345678901234567890123 (23 digits) ✓ first 20 Beyond the cap the remainder becomes plain text

Mentions are deliberately stricter than hashtags on the left side (! blocks here but not there) and looser on the right (@alice# keeps its mention where #Japan# loses its tag). Both behaviors were confirmed on live x.com before being encoded.

Character Limit Myths

Four beliefs survive from old documentation or plain assumption. Each fails against current x.com.

"Replies don't count leading mentions." True in 2017, false today. Typing or pasting handles at the head of a reply reduces your available characters exactly like body text – verified on live x.com while building this tool. Guides repeating the exemption are describing a retired rule.

"All non-English text weighs double." The doubling starts above a specific Unicode point. Arabic, Hebrew, Hindi and Thai all sit inside the single-weight zone, so an Arabic post carries nearly as much text as an English one. The heavy weight belongs to CJK, Hangul, emoji and scripts beyond that range.

"Shorten your links before posting." Pointless since 2010. X replaces every link with its own shortener and charges a flat 23 whether you hand it 13 characters or 300. Pre-shortening changes nothing except hiding where the link points.

"Images and quote posts eat characters." Attachments cost nothing – up to four photos ride along free – and a quoted post's text is not added to yours. Only the text you actually type counts.

Premium and Long Posts

An X Premium subscription raises the ceiling from 280 to 25,000 characters on every paid tier, turning a post into something closer to an article. Two caveats matter more than the headline number.

First, X documents the weighted rules for the 280 limit but has never published how the 25,000 cap treats links, emoji or CJK text. Any third-party counter claiming exact parity with the long-form limit is guessing. This tool deliberately models only the well-documented 280 rules instead of inventing unverifiable ones.

Second, timelines fold long posts after roughly the first 280 characters behind a Show more link. Whatever you write beyond that, the opening competes for attention under the same weighted rules as everyone else's post. For anything that must be read without an extra click, 280 remains the number that matters – which is why this counter stays useful even for Premium accounts.

Usage

  1. Type or paste your draft into the text area. All six counters update on every keystroke.
  2. Watch the Characters card – it turns red the moment the weighted total passes 280, and the message above explains the overrun.
  3. Read the breakdown lists – every hashtag, mention and link the parser detected appears below, with duplicates collapsed into a single chip marked ×N.
  4. Copy the draft when it fits – the button selects the text and puts it on your clipboard, ready for x.com or your scheduling tool.
  5. Clear resets the text and every counter in one step.

There are no options to configure and no modes to choose – the tool always applies the same live-x.com rules.

Tutorial

Follow one realistic draft through the whole pipeline.

Step 1 – Paste a mixed draft.

Training complete ✅ Full report https://x.com More details soon

A generic character counter reports 63. The Characters card reports 74. The gap is the invisible arithmetic at work: the checkmark emoji weighs 2 as its own cluster (+1 over a plain count), and the link flattens from 13 characters up to 23 (+10).

Step 2 – Watch the URL flatten. Replace the short address with a much longer one:

Training complete ✅ Full report https://defense.example.gov/news/2026/exercise-report More details soon

The link grew by 40 characters, yet the Characters card does not move from 74 – the Detected URLs list confirms the new address costs the same flat 23. A plain counter would jump to 103; this is why pre-shortening links saves nothing on X.

Step 3 – Add hashtags the way x.com parses them. Append #Japan #Training. Both extract cleanly and add 6 and 9 weighted characters respectively, plus the two separating spaces – the card reads 91.

Step 4 – Break a hashtag on purpose. Type #Ja#pan. Neither fragment appears in the list – a hash against the end of a tag invalidates the whole candidate. Undo back to the working version.

Step 5 – Cross the line. Duplicate the CJK opening until the card turns red and the over-limit message appears. Trim until it clears – watching the number fall makes the 2-per-glyph arithmetic instinctive.

Step 6 – Copy and ship. Hit Copy, paste into x.com, and the composer accepts the draft first try – same rules, same number.

Pro Tips

  • Budget links at 23 each, before writing. One link leaves 257 characters; three leave 211. Reserve the budget first and the draft never needs surgery later.
  • Treat complex emoji as luxury spending. Every emoji cluster costs 2, and reaction strings add up fast – three party poppers outweigh the word wow.
  • Front-load the hook. Timelines truncate around the fold; whatever sits past the weighted midpoint rarely earns clicks. Put the payoff early.
  • Keep hashtags to a clean handful. X imposes no hard hashtag penalty, but tags mid-word never parse – leave a space or start-of-line before every hash.
  • Paste from Word without fear. Smart quotes and dashes sit in the single-weight punctuation ranges, and NFC normalization folds decomposed accents down to one.
  • Pair with the Instagram Caption Analyzer for cross-posting. Same draft, different platform math – X weighs and flattens links, IG tracks tallies against a lenient 2200 with a five-hashtag guideline.
  • Trust the red card over your eyes. If Characters says over, the post is over – the weighted arithmetic sees costs plain counters cannot.

Alternatives

Option Weighted rules Boundary-exact detection Live stats breakdown Private/offline
This counter Yes – verified on live x.com Yes – 36 tested cases Six counters + item lists Yes
x.com composer counter Yes Yes Total only, no breakdown N/A (on platform)
Generic character counters No – plain length No Partial Usually
Scheduler built-in checks Rarely – most use plain length No Varies No
twitter-text library Yes – reference implementation Yes Build it yourself Depends on host

The composer inside x.com is authoritative but offers a single number with no diagnosis. Generic counters are the reason drafts get rejected – they ignore weighting entirely. Schedulers inherit the same flaw. The twitter-text library is the source of truth if you want to embed the full engine, at the cost of a dependency. This tool occupies the practical middle – reference-grade rules with zero setup.

Against the twitter-text Library

X publishes an open-source library, twitter-text, that defines the canonical counting and extraction rules – this counter implements the same public specification rather than calling any API.

Capability twitter-text library This counter
Weighted length Exact – reference implementation Same weights and ranges
Link detection Exhaustive grammar with hundreds of valid top-level domains Bare domains checked against the same official suffix lists – https links skip that check
Emoji clustering Config-driven parsing Grapheme segmentation with the standard emoji-block heuristic
Hashtag/mention boundaries Reference regexes Boundaries transcribed from live x.com tests (36 cases)
Integration A bundled dependency for your build None – open the page and type

Bare-domain detection now shares the library's foundation: this counter embeds the same official gTLD/ccTLD suffix lists, so twitch.tv counts as a link while foo.zzz stays text, exactly as the library decides. Two honest gaps remain – https:// links are accepted in any plausible shape without the suffix check, and the embedded lists freeze at the open-source release, so a top-level domain introduced after it could be missed. For ordinary posts the numbers agree; everything else – weights, clustering, boundaries – follows the same spec, and the boundary tables came from live-platform testing rather than library transcription.

Counter vs. Caption Analyzer

Toollect ships sibling analyzers for the two biggest social platforms, and their differences illustrate why one counter never fits all:

Question Caption Analyzer (Instagram) This counter (X)
Limit 2,200 characters 280 weighted characters
Counting basis UTF-16 length Weighted grapheme clusters
Simple emoji 2 (astral units) 2 (cluster rule)
Complex emoji families Weighs each code unit – a family costs more than 2 Always exactly 2 per cluster
Links Ordinary text – no flattening Flat 23 each
Platform-specific limits Five-hashtag guideline Reply mentions count; boundary rules per the tables above

Neither approach is wrong – each mirrors its platform. Instagram's longer limit tolerates simpler counting, while X's tight budget demands the weighted precision. One honest note on the sibling: a ZWJ emoji family pasted into the caption analyzer counts its raw code units (a family costs more than 2), because Instagram has never documented its exact method and UTF-16 was the pragmatic choice. If you post the same family on both platforms, expect X to charge it 2 and the analyzer to report more.

What It Doesn't Do

  • It does not model Premium long posts. The 25,000-character tier exists, but X has never documented how it counts – inventing rules would break the accuracy guarantee. See Premium and Long Posts above.
  • It does not split threads. Over the limit means trim or thread manually; the tool reports, it does not rewrite.
  • It does not guarantee bit-for-bit parity with X servers. Bare domains are checked against the official suffix lists, but https links skip that check and the embedded lists freeze at the open-source release – pathological addresses could in theory be classified differently. Ordinary posts agree.
  • It does not verify that handles exist. @nonexistent_account_12345 still parses as a mention – validity is a platform lookup, not a grammar question.
  • It does not check bio, DM or name limits. Those fields use different caps (160, 10,000 and 50 respectively) outside this counter's single-purpose scope.
  • It does not post, schedule or store anything. The output is knowledge, not actions.
  • It is not affiliated with X. Rules were transcribed from public documentation and live observation, with no endorsement implied.

Troubleshooting

Problem Cause Solution
My draft looks shorter than 280 but the card is red Weighted costs – links at 23, CJK/emoji at 2 Check the breakdown lists; replace the link or trim doubled-weight text until it clears
The URL list shows a link I did not intend to post Recognized links count – including protocol-less domains like twitch.tv Reword so the address is not part of the draft, or accept its 23-character cost
#123 does not appear under Hashtags Purely numeric tags are not hashtags on X Add a letter to the tag, or drop it
A hashtag after an emoji is missing Should not happen – emoji prefixes are valid Confirm no letter/digit/underscore sits directly before the hash; report the exact input if it still fails
The count differs slightly from another website's counter Most competitors use plain length This counter applies the official weights; trust the red card over generic totals
Accented words seem to count differently elsewhere Other tools skip NFC normalization This counter normalizes first – its number matches X
Copy did nothing Clipboard permission denied by the browser Grant clipboard access or select the textarea manually and copy with Ctrl/Cmd+C

Privacy and Data Handling

This tool is a member of the site's zero-request family – the strictest privacy class Toollect ships.

  • Nothing leaves your device. Drafts, hashtags, mentions and counts exist only in your browser tab. No Toollect server, no third-party endpoint, no analytics touch the text you type.
  • No account, no storage, no cookies for tracking. Close the tab and every trace disappears – there is no history to clear because none was written.
  • The checker works offline. Once the page has loaded you can sever the connection entirely and keep counting.
  • Clipboard use is explicit. Text reaches the clipboard only when you press Copy – never automatically.

If you need the same privacy philosophy applied to link analysis, the X (Twitter) URL Parser on this site runs its entire workflow with zero requests as well.

Technical Specs

Details:

  • Limit – 280 weighted characters; each link flattens to 23; every other unit weighs 1 or 2 per the range table
  • Light ranges – U+0000–U+10FF, U+2000–U+200D, U+2010–U+201F, U+2032–U+2037 (weight 1); all other code points weigh 2
  • Normalization – input converted to Unicode NFC before counting
  • Segmentation – Intl.Segmenter grapheme mode; clusters containing emoji markers (VS16, ZWJ, keycap, U+1F000+, U+2600–27BF) weigh 2 atomically; fallback to code-point iteration where Segmenter is unavailable
  • Link grammar – an https:///http:// address (leading boundary at start/space/open bracket) or a protocol-less domain whose TLD matches the official gTLD/ccTLD lists; a domain glued directly after dash/underscore/dot/slash does not parse; trailing punctuation excluded from the link and weighed as text
  • Hashtag grammar – #/ plus at least one letter within [\p{L}\p{N}_]+; preceding character must not be a letter, digit, underscore, ampersand; following character must not be a hash symbol; fullwidth symbols accepted
  • Mention grammar – @/ plus 1–20 characters of [A-Za-z0-9_]; preceding character must not be a word character, exclamation mark, at, hash, ampersand (fullwidth equivalents included); following at-sign discards the candidate
  • Statistics – weighted total, hashtag count, mention count, URL count, line-break count, paragraph-break count (blank-line separated), plus deduplicated item tallies with ×N badges
  • Network traffic – zero; all computation is local JavaScript
  • Browser support – all modern browsers with Intl.Segmenter (Chrome 87+, Safari 14.1+, Firefox 125+) and the Clipboard API

Features

  • Counts against the real X weighted limit – URLs cost exactly 23 characters, CJK and emoji weigh 2, verified against live x.com
  • Boundary-exact hashtag and mention detection – 36 edge cases verified on real x.com, covering emoji prefixes, doubled hashes, glued fragments and numeric-only tags
  • Six live statistics as you type – characters, hashtags, mentions, URLs, line breaks and paragraph breaks
  • Unicode-correct by design – emoji families count as one cluster, decomposed accents normalize before counting, Arabic weighs 1
  • Reflects today's X, not 2017 folklore – leading reply mentions count toward the limit, exactly as the platform behaves now
  • Free, private and instant – everything runs in your browser with zero requests, no API key, no sign-up

Frequently Asked Questions

Why does my post look under 280 but X says it is too long?
Because X uses weighted counting, not a plain tally. Every link costs exactly 23 characters no matter how long or short it is, Chinese/Japanese/Korean characters and emoji weigh 2 each, and only some scripts weigh 1. A post that looks like 250 visible characters can easily pass 280 once a link and a few emoji are added. This counter applies the same weights, so its number is the number X will use.
How many characters does a link count as?
Exactly 23, always. X wraps every recognized link behind its own shortener – https and http addresses, plus protocol-less domains like twitch.tv – so a 13-character address and a 300-character tracking URL cost identical amounts. Shortening your links beforehand saves nothing – one link leaves about 257 characters for text, and each additional link costs another 23.
Which languages count double on X?
Fewer than most people assume. Characters up to a certain Unicode range – covering Latin, Greek, Cyrillic, Hebrew, Arabic, Hindi and Thai among others – weigh 1 each. The double weight applies mainly to Chinese, Japanese and Korean characters, plus emoji. So an Arabic or Russian post fits roughly as many characters as an English one, while a Japanese post fits about half.
Do leading @mentions in replies still not count?
Not anymore. In 2017 Twitter exempted reply mentions from the limit, and many guides still repeat that rule. Testing on live x.com in 2026 shows leading @mentions now count toward the limit like any other text, and this counter matches that current behavior rather than the outdated folklore.
Why do purely numeric tags fail while tags containing letters work?
X requires every hashtag to contain at least one letter – purely numeric tags are ignored. The tag must also start cleanly – a letter, digit or underscore glued in front of the hash cancels it, while spaces, emoji and most punctuation allow it. This counter follows those same boundaries, tested case by case on live x.com.
Does X Premium really give 25,000 characters?
Yes – paid subscribers can publish long-form posts up to 25,000 characters, although X has never documented how that larger cap counts links or emoji. Note that timelines fold long posts after roughly the first 280 characters behind a Show more link, so the opening still does the heavy lifting. This tool models the universal 280 weighted limit that applies to every account.
ESC