Character Counter: How It Works
Character limits are everywhere — social posts, meta descriptions, SMS, database fields, form validation — and almost every platform counts them slightly differently. This counter shows the numbers; this page explains why one string can have three legitimate lengths.
Common limits
| Where | Limit | Note |
|---|---|---|
| X / Twitter post | 280 | Links count as a fixed 23 regardless of length |
| SMS (GSM-7) | 160 | 153 per part once concatenated |
| SMS (Unicode) | 70 | One emoji switches the whole message to this |
| Meta description | ~160 | Truncated by pixel width, not characters |
| Title tag | ~60 | Same — roughly 580 pixels |
| Instagram caption | 2,200 | Truncated after ~125 in the feed |
| LinkedIn post | 3,000 | 'See more' appears after ~200 |
| YouTube title | 100 | Truncated around 60–70 in most views |
Note the recurring pattern: the hard limit and the visible limit are different numbers, and the visible one is what determines whether anyone reads your point. Write for the second.
The SMS trap
Standard SMS uses a 7-bit alphabet allowing 160 characters. Include a single character outside it — an emoji, a curly quote, an accented letter, an em dash — and the entire message switches to 16-bit encoding with a 70-character limit. A 150-character message that fitted in one segment becomes three segments, tripling the cost, because someone's text editor auto-converted a straight apostrophe into a curly one. For bulk messaging this is a real budget line.
Characters, code points and bytes
A visible character is not necessarily one unit of storage.
| Text | Looks like | Code points | UTF-8 bytes |
|---|---|---|---|
a | 1 | 1 | 1 |
é | 1 | 1 (or 2 if decomposed) | 2 (or 3) |
中 | 1 | 1 | 3 |
| 👍 | 1 | 1 | 4 |
| 👨👩👧👦 | 1 | 7 | 25 |
That last row is a family emoji built from four people joined by zero-width joiners. It appears as one glyph and consumes 25 bytes. This is why a database column declared as VARCHAR(50) in bytes can reject a name that is clearly under fifty characters, and why truncating by byte count can split a character and produce a broken string.
Practical guidance
- Validate by what the storage counts. If the field is byte-limited, count bytes; if character-limited, count characters. Mixing them produces errors that only appear with non-English input.
- Never truncate by bytes without checking you have not split a multi-byte sequence.
- Test with non-Latin text and emoji. A form that works in English and fails on a Japanese name has a bug, not an edge case.
- Front-load anything with a visible-truncation limit — the first 125 characters of an Instagram caption do all the work.