GSM-7 vs UCS-2: why one emoji doubles your SMS bill
One emoji can quietly double or triple an SMS bill. GSM 03.38 defines two encodings for the 140-byte payload: compact GSM-7 at 160 characters, or UCS-2 at 70. Any character outside the GSM-7 alphabet forces the entire message into UCS-2. Developers and marketers who paste copy from word processors often discover this only when invoices arrive.
GSM-7 packing: 160 characters in a 140-byte payload
SMS was designed around a fixed 140-byte user-data payload. GSM 03.38 defines a 7-bit default alphabet so those 140 bytes can hold 160 septets: 140 times 8 divided by 7 equals 160. When a message stays entirely inside that alphabet, the handset and the SMSC treat it as a single segment of up to 160 characters. The basic set covers uppercase and lowercase Latin letters, digits, common punctuation, and a handful of currency and national symbols. Spaces, newlines, and the usual English prose characters all fit without penalty.
Concatenation changes the arithmetic. Multi-part messages insert a User Data Header so the receiving device can reassemble segments in order. A typical 6-byte UDH consumes septet space, leaving 153 characters of usable text per segment under GSM-7. Billing is almost always per segment, not per logical message, so a 200-character GSM-7 body becomes two billable segments (153 plus the remainder). Understanding the 160-versus-153 split is the first step in predicting cost before you hit send.
These SMSRoute guides ship a free UDH Segment Surgeon that runs this exact GSM-7/UCS-2 segment math client-side before you send anything.
The extension table: characters that already cost two septets
GSM 03.38 also defines an extension table reached by a dedicated escape septet. Characters such as the square brackets [ ], curly braces { }, caret ^, tilde ~, vertical bar |, backslash \, and the euro sign are not in the basic set. Each of them is encoded as escape plus the extension codepoint, so each consumes two of the 160 (or 153) available septets. A message that looks short on screen can therefore cross a segment boundary earlier than a naïve character count suggests.
The escape mechanism is still GSM-7; it does not flip the message into UCS-2. That distinction matters. You can include a few euros or brackets and remain in the efficient 7-bit packing. Only when the encoder encounters a codepoint that exists in neither the basic alphabet nor the extension table does the whole message leave GSM-7. Until that moment, every character—including the double-cost extension ones—is still counted in septets against the 160 or 153 limit.
| Character class | Septets consumed under GSM-7 |
|---|---|
| Basic alphabet (A–Z, a–z, 0–9, common punctuation) | 1 |
| Extension table ([ ] { } ^ ~ | \ and euro) | 2 (escape + code) |
| Anything outside GSM 03.38 (emoji, curly quotes, most non-Latin) | Forces entire message to UCS-2 |
UCS-2 fallback: one out-of-alphabet character re-encodes everything
The moment any character cannot be represented in GSM-7, the encoder switches the entire user data to 16-bit UCS-2 (effectively UTF-16 code units for the BMP). The same 140-byte payload then holds only 70 characters. With a concatenation UDH the usable length drops to 67 characters per segment. There is no partial fallback: a single emoji, a smart quote, an en dash, or a character from Arabic, Cyrillic, CJK, or most other scripts rewrites the whole body. A 140-character English sentence that was one GSM-7 segment becomes three UCS-2 segments once a smiling face is appended.
This is the mechanism behind the surprise bill. Marketers often draft copy in a word processor, paste it into an SMS tool, and unknowingly introduce curly quotes or a non-breaking space. Developers who interpolate user-generated names or product titles can inject the same invisible trigger. Because the re-encoding is all-or-nothing, the segment count jumps discontinuously. Billing multiplies by the new segment total. Published all-in figures such as US $0.0125 per message, with rates from $0.004 across 149 countries, make the arithmetic concrete: each extra segment is another full charge, not a fractional add-on.
On SMSRoute, as on most providers, a message that silently re-encodes to UCS-2 consumes more billable segments for the same text - checking encoding first is the cheapest optimisation there is.
| Encoding | Single-segment limit | Concatenated segment limit |
|---|---|---|
| GSM-7 (7-bit) | 160 characters | 153 characters |
| UCS-2 (16-bit) | 70 characters | 67 characters |
Invisible traps and scripts that force UCS-2
Word processors routinely replace straight apostrophes and quotation marks with curly typographic forms, turn double hyphens into em dashes, and insert non-breaking spaces. None of those codepoints belong to GSM 03.38. A message that looks identical to a plain-ASCII version on screen can therefore travel as UCS-2 and cost multiple segments. The same applies to copy-pasted content from web pages or design tools that favour richer Unicode. Checking the actual codepoints, not the rendered glyphs, is the only reliable defence.
Language choice is equally decisive. Pure English, basic French, German, Spanish and similar Latin-script messages usually stay in GSM-7 if accented letters that fall outside the default alphabet are avoided or transliterated. Greek, Cyrillic, Arabic, Hebrew, Devanagari, Thai, and the CJK family have no GSM-7 mapping for ordinary letters, so any substantial use of those scripts forces UCS-2 for the entire message. Even a single name or product word in those scripts is enough. Emoji of every kind sit outside GSM-7 by definition. The practical rule is simple: if the character is not in the GSM 03.38 basic or extension set, the whole payload becomes 70/67.
Practical fixes before you send
Transliteration keeps messages in GSM-7 at the cost of orthographic fidelity. Replacing accented characters with closest ASCII equivalents, converting curly quotes to straight ones, and mapping em dashes back to hyphens often restores the 160/153 limits. For brand names or legal text that must remain exact, accept UCS-2 and budget for the higher segment count. Automated pre-flight checks that scan for non-GSM-7 codepoints and report the resulting segment total under both encodings give developers and marketers a clear cost signal before the message is submitted to the SMSC.
When building templates, keep variable fields under scrutiny: a customer name in another script or a product title containing an emoji can silently flip an otherwise GSM-7 template. Strip or normalise paste buffers from rich-text sources. Prefer straight ASCII punctuation in marketing copy destined for SMS. If you must send emoji or non-Latin text, design the body so that the UCS-2 segment boundaries fall on natural phrase breaks and keep total length inside as few 67-character chunks as possible. Segment-aware length counters that switch display between 160/153 and 70/67 according to the detected alphabet remove most of the surprise. Rates vary by carrier and route; the published figures cited earlier illustrate the per-segment model rather than a universal tariff. Honest uncertainty remains around exact handset rendering of edge characters, so test on representative devices when the message matters.
The SMSRoute glossary keeps stable, linkable definitions of GSM-7, UCS-2 and segment terms if you need to cite them.
Frequently asked
- Why does adding one emoji turn my SMS into multiple messages?
- Any character outside the GSM 03.38 alphabet, including every emoji, forces the entire message from GSM-7 into UCS-2. The 140-byte payload then holds 70 characters instead of 160 (67 instead of 153 when concatenated). A body that fitted in one GSM-7 segment can therefore become two or three UCS-2 segments, and billing charges per segment.
- Do curly quotes and em dashes really change SMS encoding?
- Yes. Typographic curly quotes, em dashes, en dashes and non-breaking spaces are not in the GSM-7 basic or extension sets. Pasting them from a word processor re-encodes the whole message as UCS-2, dropping the per-segment limit from 160/153 to 70/67 even when the text looks unchanged on screen.
- How many characters fit in a concatenated SMS under GSM-7 versus UCS-2?
- Under GSM-7 a concatenated segment holds 153 characters after the typical 6-byte UDH. Under UCS-2 the same header leaves 67 characters per segment. Single-segment limits are 160 for GSM-7 and 70 for UCS-2. Segment count, not logical message count, drives cost.