Character counter
Live count with platform-specific limit hints.
A Character Counter computes character counter from the inputs you provide. It applies the standard formula to the values you enter and returns the result instantly, without sending any data to a server. Total characters, characters without spaces, letters, digits, uppercase, lowercase, punctuation, and whitespace.
Live count with platform-specific limit hints.
Counts every character class: letters, digits, punctuation, whitespace, plus uppercase / lowercase splits.
Drop in text. The result lists every character class - total, without spaces, letters, digits, uppercase, lowercase, punctuation, whitespace.
A character counter measures the literal length of a string the way the JavaScript runtime, the SMS gateway, and the database column see it. Three numbers matter in practice: total code points (the value string.length returns), code points minus whitespace (the figure most CMS plugins enforce), and UTF-8 byte length (the figure database VARCHAR(n) columns and SMS gateways bill against). This page reports all three, plus platform-specific aggregates for X, SMS, and Google meta descriptions.
Counting characters sounds trivial until Unicode arrives. A naive string.length in JavaScript counts UTF-16 code units, so a single ancient script glyph or a clothed-runner emoji can read as two, three, or seven units even though the user typed one symbol. Our counter exposes the raw figure so you can verify whatever your downstream system is enforcing instead of trusting a sanitized number. For password and slug fields the raw count is exactly right; for user-facing limits like a 280-character post, downstream rules apply.
The page runs in your browser and never sends keystrokes to a server. On every input event the tool computes four primitives and derives the rest from them.
total = text.length // UTF-16 code units no_space = text.replace(/\s+/g, '').length // strips spaces, tabs, newlines bytes = new TextEncoder().encode(text).length // UTF-8 byte count twitter = total + heuristic for t.co shortening sms_segs = total <= 160 ? 1 : ceil(total / 153) // GSM 7-bit segments
The SMS segment math drops to 70 then 67 if any character falls outside the GSM 7-bit set, because UCS-2 encoding takes effect for the whole message. The meta-description aggregate flags any total above 160 because Google truncates description snippets at roughly that width on desktop SERPs (mobile is shorter).
Suppose you draft this post: Launched the new docs site today! Read more at https://example.com/docs/getting-started-with-tooling followed by a single rocket emoji.
VARCHAR(120) CHARACTER SET utf8mb4 column accepts it; a legacy VARCHAR(120) CHARACTER SET utf8 column (which is actually 3-byte) rejects it because the rocket needs 4 bytes.| Surface | Limit | Counts as | Source |
|---|---|---|---|
| X (formerly Twitter) post | 280 weighted characters | Code points with t.co URL shortening | X Developer Platform docs |
| Bluesky post | 300 graphemes | Grapheme clusters | Bluesky AT Protocol spec |
| SMS single segment (GSM 7-bit) | 160 characters | GSM 03.38 alphabet | 3GPP TS 23.038 |
| SMS single segment (UCS-2) | 70 characters | Any non-GSM character forces UCS-2 | 3GPP TS 23.038 |
| Google meta description | ~155 to 160 characters | Truncation point on desktop SERPs | Moz, Ahrefs SERP studies 2026 |
| Google title tag | ~60 characters (or 580 pixels) | Pixel-width truncation | Google Search Central |
| Slack message | 40,000 characters | UTF-8 code points | Slack API docs |
| Email subject line (deliverability) | ~50 characters target | Code points | Litmus, Mailchimp benchmarks |
.length for graphemes. A flag emoji is two code points, a family emoji is four to seven. If you need user-perceived characters, segment with Intl.Segmenter's grapheme cluster mode, not raw length.text.normalize('NFC').replace(/\s+/g, ' ').trim().ER_DATA_TOO_LONG is byte-based when the column is utf8mb4; a 250-character latin1 column accepts 250 bytes which is exactly 250 ASCII characters.X (formerly Twitter) collapses every URL to a 23-character t.co shortlink before counting, and weights some CJK characters as two units under its 'weighted character' rule. A raw character counter shows the literal code-point length; X shows the weighted length. For posts without links and without CJK, the two match exactly. For posts with links, expect the X composer to report roughly len(text) minus (URL length minus 23) per link.
Yes. A tab (U+0009) is one code point, a newline (U+000A) is one code point, and a carriage return plus newline (CRLF) is two. All three add to the total character count but are excluded from the 'without spaces' line. UTF-8 byte length stays equal to the code-point count for ASCII whitespace, so the byte counter shows the same number for these.
An emoji can be one code point (a single smiley) or many code points joined by zero-width joiner (ZWJ U+200D). A family emoji is usually four to seven code points: a base man, woman, boy, girl plus ZWJ glue. A skin-tone modifier adds one more. The counter reports the raw code-point total, so a single 'family' emoji often reads as four to seven characters. Most messaging apps count the same way, which is why a tweet with three family emojis can fail validation.
An SMS is 160 characters when every character is in the GSM 7-bit alphabet (basic Latin plus a small extension table). It drops to 70 characters when any character is outside that set, which forces UCS-2 16-bit encoding for the whole message. Once you exceed one segment, each follow-up segment shrinks to 153 or 67 characters because 7 or 3 bytes are spent on the User-Data Header that tells the receiver how to stitch segments back together. A 200-character GSM message therefore costs two segments, not one.
Modern browsers handle a few million characters in a textarea comfortably. Chrome on desktop has paginated five million plus inputs in tests; mobile Safari starts to lag past about one million. The counter itself is O(n) for total length and O(n) for whitespace strip, so a one-million-character string runs in well under 100 ms on a mid-range laptop and stays responsive on phones up to roughly 250,000 characters.
Yes. Zero-width joiners, zero-width spaces, byte-order marks (BOM, U+FEFF), variation selectors (U+FE0F and friends), and bidirectional override marks all count toward total length. This is the most common reason a 280-character tweet is rejected at apparent length 270: copy-pasting from a rich text source dropped invisible markers into the string. Strip them with a regex or use a Unicode normalizer before posting.