Everyday Math & Text

SMS Character Limits: Why 160 Becomes 70

A single emoji or curly apostrophe can cut an SMS limit from 160 characters to 70 and double the cost. Here's how SMS encoding and segments work, with real examples.

  • By Jacob
  • 5 min read
Two speech bubbles filled with rows of small tiles, linked by a green connector, illustrating a text message split into segments

You write a 110-character text message, add a thumbs-up emoji at the end, and your SMS provider bills you for two messages. Or a reminder that fit in one message last week suddenly takes two, though nobody made it longer. The culprit is almost always the same: one character switched the message to a different encoding, and the limit dropped from 160 characters to 70.

Here's how SMS length really works, which characters cause the switch, and how to keep messages in a single segment.

Where 160 comes from

An SMS carries at most 140 bytes of text, which is 1,120 bits. How many characters fit depends on how many bits each character takes:

  • GSM-7, the default SMS alphabet, uses 7 bits per character: 1,120 ÷ 7 = 160 characters.
  • UCS-2, used for anything outside that alphabet, uses 16 bits per character: 1,120 ÷ 16 = 70 characters.

The GSM-7 alphabet is defined in the 3GPP specification TS 23.038, "Alphabets and language-specific information." Twilio's explanation of the limits gives the same numbers.

The key detail: the encoding applies to the whole message. If even one character isn't in GSM-7, every character is sent as UCS-2, and the limit for the entire message drops to 70.

What's in the GSM-7 alphabet

GSM-7 covers more than plain ASCII letters, but less than you might expect:

  • Included: A–Z, a–z, 0–9, common punctuation, space and line breaks, plus some accented letters and symbols such as é è ù ì ò à ä ö ü ñ Ç Ø Å Æ ß £ ¥ ¤ § and several Greek capital letters.
  • Included, but count as two characters: ^ { } \ [ ] ~ | and €. They live in an extension table and need an escape character before them.
  • Not included: emoji, curly quotes and apostrophes (’ “ ”), most accented letters (including lowercase ç, á, í, ó, ú, ã), and all non-Latin scripts.

So é is fine but á isn't, and uppercase Ç is in the alphabet while lowercase ç is not. Rules like these are why it's worth checking messages with a counter rather than guessing.

Real examples

These results come from our Character Counter, which shows the SMS encoding, the number of parts and the characters left:

MessageCharactersEncodingParts
A 109-character shipping notice109GSM-71
The same notice plus a space and 👍111UCS-22
Don't forget: tomorrow at 9.28GSM-71 (132 left)
Don’t forget: tomorrow at 9. (curly apostrophe)28UCS-21 (42 left)
€10 {promo}11GSM-7Counts as 14

The second row is the classic surprise: adding two characters doubled the cost, because the emoji pushed a 111-character message past the 70-character UCS-2 limit.

The curly apostrophe is the sneaky one. Word processors, phones and content management systems often replace straight quotes with curly ones automatically, so text pasted from a document can switch encoding without anyone noticing.

Long messages: 153 and 67

Messages longer than one SMS are split into segments that the recipient's phone reassembles, a feature called concatenated SMS, defined in 3GPP TS 23.040. To make that possible, each segment carries a small User Data Header with a reference number, the total number of parts and the part's position. The header takes 6 bytes of the 140, which leaves:

  • 153 characters per segment with GSM-7 (the header uses the space of 7 characters)
  • 67 characters per segment with UCS-2 (134 bytes ÷ 2)

So the thresholds look like this:

PartsGSM-7 up toUCS-2 up to
116070
2306134
3459201
4612268

Note the jump from 160 to 161: a 161-character GSM-7 message needs two segments that can each hold 153, so it uses 2 parts with room for 306. Providers bill per segment. Twilio, for example, states that it "bills SMS per message segment sent."

How emoji are counted

Most emoji are outside the range a single 16-bit unit can represent, so they're sent as a pair of 16-bit units, called a surrogate pair. Each such emoji uses two of the 70 slots. Thirty-five 😀 emoji fill a single message completely, and a 70-character message with one emoji at the end needs two parts. Emoji with skin tones, or combined emoji like family groups, are built from several code points and use even more.

Many SMS tools, including the Character Counter, count in 16-bit units for this reason, so an emoji shows up as 2 toward the limit even though it looks like one character.

How to keep messages in one segment

  • Replace curly quotes and apostrophes with straight ones before sending. Many SMS providers offer an option that does this automatically; Twilio calls its version Smart Encoding.
  • Skip emoji in transactional messages like codes, reminders and shipping updates, where a doubled cost adds up across thousands of messages.
  • Watch extension characters. €, brackets, braces, ~, ^, | and \ each count twice in GSM-7.
  • Shorten links. A long tracking URL can use a third of a message by itself.
  • Check templates with real data. A template that fits with "Ana" may overflow with a long name or address, and a name with an accent like á switches the whole message to UCS-2.
  • Count before you send. Paste the final text into the Character Counter. For longer copy, the Word Counter also tracks characters as you edit.

Checking the encoding in code

If you send messages from an application, it's worth checking length before handing text to your provider. This is a simplified version of the logic the Character Counter uses, in JavaScript:

const GSM = "@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà";
const GSM_EXT = "^{}\\[~]|€\f";

function smsParts(text) {
  let units = 0;
  for (const ch of text) {
    if (GSM.includes(ch)) units += 1;
    else if (GSM_EXT.includes(ch)) units += 2;
    else return { encoding: "UCS-2", parts: text.length <= 70 ? 1 : Math.ceil(text.length / 67) };
  }
  return { encoding: "GSM-7", parts: units <= 160 ? 1 : Math.ceil(units / 153) };
}

smsParts("Don't forget: tomorrow at 9.");  // { encoding: "GSM-7", parts: 1 }
smsParts("Don’t forget: tomorrow at 9.");  // { encoding: "UCS-2", parts: 1 }

In JavaScript, text.length counts 16-bit units, which is exactly how UCS-2 messages are measured, emoji included. Use it to warn editors when a template crosses a segment boundary, or to log which messages switched encoding.

When UCS-2 is unavoidable

For languages written in non-Latin scripts, such as Arabic, Chinese, Hindi or Russian, every message is UCS-2, so 70 and 67 are simply the limits to plan around. Some networks support national language tables that extend GSM-7 for specific languages like Turkish, Spanish and Portuguese, but support varies by country and provider, so don't count on it without checking with your SMS provider.

FAQ

Why does my phone show 160 characters but my provider billed two messages?

Usually a character outside GSM-7, often a curly apostrophe or an emoji, switched the message to UCS-2, where the limit is 70. Many phones don't show which encoding a message uses, so it's easy to miss.

Are spaces and line breaks counted?

Yes. Each counts as one character in both encodings.

Is there a maximum length for a long SMS?

The concatenation scheme allows up to 255 segments in theory, but carriers and providers set much lower limits in practice. Twilio, for example, lists a maximum of 1,600 characters for a GSM-7 message.

Do these limits apply to iMessage, WhatsApp or RCS?

No. Those are internet-based messaging services with their own, much higher limits. The 160 and 70 rules apply to SMS.