Detecting encoding means checking whether every character is in the GSM-7 alphabet; if even one is not, the whole message becomes UCS-2 and capacity drops from 160 to 70 characters. Because SMS is billed per segment, a single stray emoji or curly quote can double or triple the cost of a message.
How to detect GSM-7 vs UCS-2
The rule is simple and absolute: if every character in the message is present in the GSM-7 basic or extension table, the message can be sent as GSM-7; if any character is not, the entire message must use UCS-2. Detection is therefore a set-membership test against the GSM-7 alphabet, applied to the whole string, remembering that the ten extension characters count as two septets each.
for each character c in message:
if c not in GSM7_BASIC and c not in GSM7_EXTENSION:
encoding = UCS-2 # one stray char forces the whole message
break
else:
encoding = GSM-7The characters that quietly force UCS-2
The expensive characters are the ones users introduce without noticing. Word processors and phones auto-substitute straight quotes and hyphens with typographic versions that are not in GSM-7. Emoji are never in GSM-7. Non-Latin names and any accented letter outside the GSM-7 accent set do the same. Sanitising these before sending — replacing smart punctuation with ASCII, transliterating where acceptable — keeps messages on GSM-7.
| Triggering character | GSM-7-safe replacement |
|---|---|
| ' ' (curly single quotes) | ' (straight apostrophe) |
| “ ” (curly double quotes) | " (straight quote) |
| – — (en/em dash) | - (hyphen) |
| … (ellipsis) | ... (three dots) |
| emoji | (remove, or describe in words) |
| non-breaking space | (normal space) |
How encoding drives segment count
SMS is charged per segment, and encoding sets how many segments a message needs. The thresholds are fixed: GSM-7 gives 160 in one segment then 153 per part; UCS-2 gives 70 then 67. So a 75-character message is one segment in GSM-7 but two in UCS-2. A 160-character promotional SMS with one emoji jumps from one segment to three. Encoding is the largest controllable factor in per-message cost.
| Segments | GSM-7 chars | UCS-2 chars |
|---|---|---|
| 1 | 1 – 160 | 1 – 70 |
| 2 | 161 – 306 | 71 – 134 |
| 3 | 307 – 459 | 135 – 201 |
| n (n ≥ 2) | 153 × n | 67 × n |
Practical cost control
Three habits keep SMS cost predictable. First, validate and sanitise every outbound message's characters, flagging anything that forces UCS-2. Second, keep templates within a single GSM-7 segment (≤160 chars) wherever the message allows. Third, measure the realised segment count per message and per campaign, since that — not character count — is what you are billed for. A segment calculator makes the trade-off visible before you send.
Frequently asked
How do I know if my SMS is GSM-7 or UCS-2?
Check every character against the GSM-7 alphabet. If all characters are in the GSM-7 basic or extension table, it is GSM-7; if any single character is not, the whole message is UCS-2. A GSM-7/Unicode checker automates this and highlights the offending characters.
How much does one emoji cost me in an SMS?
Potentially a lot. One emoji forces the whole message to UCS-2, dropping capacity from 160 to 70 characters. A 160-character message with a single emoji goes from one segment to three, roughly tripling the cost.
How is a multi-segment SMS billed?
Each segment is billed as a separate SMS. A message that splits into three parts is charged as three messages. That is why encoding, which sets the per-segment capacity, is the biggest lever on cost.
How can I keep messages on GSM-7?
Sanitise input before sending: replace curly quotes and dashes with ASCII equivalents, remove emoji, and transliterate stray accents where acceptable. Keep templates within 160 GSM-7 characters so they stay one segment.
Does character count or segment count determine cost?
Segment count. Two messages with the same character count can cost different amounts if one uses UCS-2. Always measure realised segments per message, not raw character length.
Source specifications
The published standards this page is grounded in. Opens in a new tab.