Character Counter
Character Counter measures text the way each destination will: grapheme clusters for most platforms, X's weighted length — where a CJK ideograph costs two and every URL counts as 23 — for X, and GSM-7 versus UCS-2 segment arithmetic for SMS. Counting text.length over-counts every emoji.
- Characters
- 156
- Code points
- 156
- UTF-16 units
- 157
- Words
- 26
- Sentences
- 4
- Lines
- 5
- Bytes
- 161
Limits by platform
X (Twitter)
- Post146 / 280weighted characters
- Post (Premium)146 / 25000weighted characters
- Bio156 / 160characters
- Display name156 / 50characters106 over
Bluesky
- Post156 / 300characters
- Bio156 / 256characters
Threads
- Post156 / 500characters
- Caption156 / 2200characters
- Bio156 / 150characters6 over
- Post156 / 3000characters
- Headline156 / 220characters
- Post156 / 63206characters
TikTok
- Caption156 / 2200characters
YouTube
- Title156 / 100characters56 over
- Description156 / 5000characters
- Tags156 / 500characters
Search & SEO
- Meta title156 / 60characters96 over
- Meta description156 / 155characters1 over
Google Ads
- Headline156 / 30characters126 over
- Description156 / 90characters66 over
Discord
- Message156 / 2000characters
- Status text156 / 700characters
SMS
- One message156 / 160code points
X weighted length
146 / 280 · 1 link(s) counted as 23
CJK and emoji cost two; Latin costs one. That is X's arithmetic, not a character count.
SMS
3 messages · UCS-2 · 157/70
One or more characters forced UCS-2, which halves the capacity to 70.
How does Character Counter work?
Every character counter is answering a question it has not been asked precisely, and the answer changes depending on who is asking. This one refuses to give a single number, because there is not one.
Three ways to count the same text
"😀".length is 2. JavaScript counts UTF-16 code units, which is a fact about the encoding rather than about the text — an emoji needs two of them. [..."😀"].length is 1, because a code point is closer to what a person means by a character. And the grapheme count is also 1, which is the number every platform limit actually uses.
The three diverge further than one emoji suggests. A family emoji built from four people joined by zero-width joiners is 11 code units and one grapheme. A flag is two code points and one grapheme. A letter with a combining accent is one or two code points depending on how it was typed — the same visible text, two different counts. All three numbers are shown, because a form field’s maxlength uses the first, a database column’s length often uses the second, and a platform limit uses the third.
X does not count characters at all
X counts weight. A CJK ideograph costs two, a Latin letter costs one, and an emoji costs two, so that 140 Japanese characters and 280 Latin ones occupy the same space. It also rewrites every URL through t.co and counts it as a flat 23 characters regardless of how long it really is. So a post containing a 200-character link is 23 characters shorter than it looks, and a Japanese post that reads as 200 characters is 400 by X’s arithmetic — well over the limit. The ranges and the 23-character rule used here are X’s own published configuration, not an estimate.
SMS has two alphabets and two sets of arithmetic
A text message holds 160 characters if every one of them is in the GSM 7-bit alphabet, and 70 if any is not — a curly apostrophe, an accented capital, an emoji. One character can therefore turn one message into three. Concatenation changes the numbers again: 153 and 67, because each segment carries a header. And eight characters in the alphabet — {}[]|^~\ and the euro sign — are transmitted as two, so a message that reports 160 of 160 can still bill as two.
Text
Ship faster without shipping secrets. 🚀
Counts
characters (graphemes) 39 code points 39 UTF-16 code units 40 words 5 X weighted 40 / 280 SMS 1 message (UCS-2)
Why do four counters give four different numbers?
The same short post measured four ways. One emoji and one URL are enough to make every count disagree, and each number is the right answer to a different question.
Text
Ship faster without shipping secrets. 🚀 https://example.com/releases/v9-32
Counts
characters (graphemes) 75 code points 75 UTF-16 code units 76 words 10 X weighted 65 / 280 SMS 2 messages (UCS-2)
X counts the URL as 23 characters rather than 40, which is why the weighted figure is lower than the character count. The SMS count is two because the emoji forced UCS-2, halving the capacity from 160 to 70 — one character moved the message into a different alphabet.
What options and edge cases does Character Counter support?
| Parameter | Type | Default | Behaviour & edge cases |
|---|---|---|---|
| Graphemes | count | platform limits | User-perceived characters, the unit every platform limit is written in. An emoji, a flag and a family of four are one each. Computed with Intl.Segmenter, falling back to code points in browsers without it. |
| X weighted | count | 280 | X's own arithmetic: CJK and most emoji cost 2, Latin costs 1, and every URL is rewritten to a flat 23 characters because it goes through t.co. The ranges used here are from X's published twitter-text configuration. |
| Code points | count | — | What most other counters mean by "characters", and what a database column measured in characters holds. Different from the grapheme count whenever combining marks or zero-width joiners are involved. |
| UTF-16 code units | count | String.length | What JavaScript's .length and an HTML maxlength attribute count. An emoji is 2. Worth knowing because a form that validates with .length and a platform that counts graphemes will disagree. |
| Words | count | — | Runs of letters, digits and apostrophes, so don't is one word and well-known is one word. Counting by splitting on spaces reports two for a double space. |
| SMS encoding | derived | GSM-7 or UCS-2 | 160 characters in GSM-7, 70 in UCS-2 — and one character outside the GSM alphabet switches the whole message. Concatenated segments hold 153 and 67 because each carries a header. |
| Bytes | count | UTF-8 | What the text costs on the wire and in a database. An emoji is 4 bytes, a CJK ideograph is 3, an ASCII letter is 1 — so a 280-character Japanese post is well over 800 bytes. |
| Verified | date | 2026-10-03 | Platform limits change without notice. These were checked on the date shown; the note beside each one says whether exceeding it truncates the text or refuses it outright, which is the part that actually matters. |
Frequently asked questions
Why does my emoji count as two characters?
Because something is counting UTF-16 code units, which is what JavaScript's String.length and an HTML maxlength attribute do. An emoji outside the Basic Multilingual Plane needs two code units to encode. The grapheme count — the number a reader and every platform limit use — is one. Both are shown here, so you can tell which one a form is complaining about.
Why is my X post over the limit when it looks short?
X counts weight, not characters. A CJK ideograph costs two, so a 200-character Japanese post is 400 by X's arithmetic and well over 280. Emoji cost two as well. Latin text is one for one, which is why the problem is invisible to anyone testing in English — the weighted count is shown separately for exactly this reason.
Does a link really count as 23 characters?
On X, yes. Every URL is rewritten through t.co and counted at a flat 23 characters whatever its real length, so a 200-character tracking URL costs the same as a short one. That is also why the count here does not simply measure the string: a 300-character post containing one long link can publish fine.
Why does my SMS count change when I add one character?
Because one character outside the GSM 7-bit alphabet re-encodes the whole message as UCS-2, which halves the capacity from 160 to 70. A curly apostrophe, an accented capital or an emoji will do it. The tool names the exact characters that caused the switch, because replacing one of them is usually easier than splitting the message.
What is a grapheme, in plain terms?
The thing a person would point at and call one character. A flag, an emoji with a skin-tone modifier, and a letter with an accent typed as two code points are all one grapheme. Intl.Segmenter computes this properly; where a browser lacks it the count falls back to code points, which is close but treats a combining accent as a separate character.
Is my text uploaded anywhere?
No. Counting is arithmetic on a string in this tab, and the Network panel shows no request when you type. That matters here because the text people measure before posting is often an unreleased announcement or a private message.