Drawing 1 · Interactive
Add one character and watch the SMS split
Encoding
GSM-7
7-bit alphabet · 160 per SMS, 153 per part
Characters
154
163 septets
SMS parts
2
153 per part
Left in part
143
before part 3
Billed as 2 SMS
Part 1153 / 153
Kesarbagh Sweets order 4821 | [Kaju katli x2] [Motichoor ladoo x1] | Pickup {Hazratganj} after 6 pm ~ show this SMS at the counter. Reply STOP t
Part 210 / 153
o opt out.
Header (UDH) — 7 septets of every part go to reassembly data.
How it splits
- Alternating parts
- 2 septets
- Forces UCS-2
Why
Past 160 septets the message is split into 2 parts of up to 153: each part gives 7 septets to a header that lets the phone stitch the parts back together. 9 extension characters (€ [ ] { } \ ^ ~ |) cost 2 septets each.
Extension characters count double: GSM-7, 2 SMS parts.
What is concatenated SMS?
Concatenated SMS is the standard way to send a text longer than one SMS can carry. A single SMS has a payload of 140 octets: 160 characters in the GSM-7 alphabet, or 70 in UCS-2. Anything longer is cut into segments, each sent as its own SMS with a small User Data Header (UDH) in front of the text, and the receiving phone uses that header to put the pieces back in order and show one message.
The usual header is six octets: 05 (header length), 00 (information element: concatenation with an 8-bit reference), 03 (element length), then a reference number shared by every part, the total number of parts and this part's sequence number. Those six octets come out of the 140, which is why a GSM-7 segment holds 153 characters and a UCS-2 segment 67. A variant with a 16-bit reference (element 08) takes seven octets and leaves 152 or 66.
Concatenation happens after the encoding is decided: GSM-7 Encoding and UCS-2 Encoding set the alphabet, and concatenation does the arithmetic on top. One character outside GSM-7, such as a Hindi letter, an emoji or a curly quote, moves the whole message to UCS-2, so the same 150-character offer goes from one part to three. Operators and aggregators bill per segment and return a delivery report per segment, so a long text is really several SMS that happen to display as one.
Key takeaways
- A concatenated SMS is one long text sent as several SMS segments that the phone stitches back into a single message.
- Each segment gives 6 octets to a User Data Header, so parts hold 153 GSM-7 or 67 UCS-2 characters instead of 160 or 70.
- Every segment is billed as a separate SMS: a 161-character English text costs two, and so does a 71-character Hindi one.
- Over SMPP the UDH rides in short_message with esm_class 0x40, or SAR TLVs or message_payload let the SMSC split the text.
- A lost part or a stripped header breaks reassembly, so keep business texts short and track delivery reports per segment.
Specifications
Concatenated SMS: key facts and limits
- Single SMS payload
- 140 octets: 160 GSM-7 or 70 UCS-2 characters
- Per segment
- 153 GSM-7 or 67 UCS-2 characters
- UDH size
- 6 octets (8-bit reference) or 7 (16-bit)
- UDH fields
- Reference, total parts, sequence number
- SMPP flag
- esm_class 0x40 (UDHI) when the UDH is in short_message
- Billing
- Each segment billed as one SMS
- Maximum parts
- 255 by the header; providers cap far lower
Operating sequence
How does concatenated SMS work?
Decide the encoding
If every character is in the GSM-7 alphabet (extension characters such as € [ ] { } ~ | count double), the text is GSM-7; otherwise the whole message becomes UCS-2.
Check whether it fits one SMS
Up to 160 GSM-7 septets or 70 UCS-2 code units travel as a single SMS with no header at all.
Split into segments
Longer text is cut into pieces of 153 septets or 67 code units. A careful encoder never splits an escape sequence or an emoji's surrogate pair across two parts.
Add the header to each part
Every segment carries the same reference, the total and its own sequence number. Over SMPP the UDH sits at the start of
short_messagewith the UDHI bit set (esm_class0x40); alternatively thesar_msg_ref_num,sar_total_segmentsandsar_segment_seqnumTLVs, or a singlemessage_payload, let the SMSC do it.The phone reassembles
The handset buffers parts by sender and reference until all have arrived, orders them by sequence number and shows one message. Each part produces its own delivery report.
Implementation
Concatenated SMS in code
import secretsdef concat_ucs2(text: str) -> list[bytes]:"""Split text into UCS-2 SMS parts, each prefixed with a 6-octet concatenation UDH."""units = text.encode("utf-16-be")if len(units) <= 140: # up to 70 code units: one SMS, no headerreturn [units]chunks, i = [], 0while i < len(units):end = min(i + 134, len(units)) # 67 code units per part# never cut between the two halves of a surrogate pair (an emoji)if end < len(units) and 0xD8 <= units[end - 2] <= 0xDB:end -= 2chunks.append(units[i:end])i = endref, total = secrets.randbelow(256), len(chunks) # same reference on every partreturn [bytes([0x05, 0x00, 0x03, ref, total, n + 1]) + c for n, c in enumerate(chunks)]# Send each part as its own submit_sm with esm_class=0x40 (UDHI) and data_coding=0x08 (UCS-2).
Splitting on whole UTF-16 code units, and never inside a surrogate pair, keeps emoji and Indian scripts intact at part boundaries.
Failure modes
Common mistakes with concatenated SMS
Counting characters instead of segments
A 161-character text is two SMS, not one and a bit. Compute segments with the encoding rules before every bulk send and show the count in the campaign tool.
Letting one character flip the encoding
An emoji, a curly apostrophe pasted from a document or the rupee sign forces UCS-2 and can triple the segments. Normalise text, or choose UCS-2 deliberately for regional-language messages and budget 67 characters a part.
Splitting in the wrong place
Cutting between an escape character and its partner, or between the halves of an emoji, corrupts the characters at the boundary. Split on whole characters, as the Python sample does.
Reusing reference numbers carelessly
Two long messages to the same phone with the same reference can be merged into nonsense. Increment references per recipient and wrap at 255.
Reading one receipt as the whole message
Each part has its own delivery report; the message is delivered only when every part is. Aggregate receipts under your own message ID before marking it delivered.
Example: A Surat wholesaler's weekly rate list
A Surat textile wholesaler sends a weekly rate update to 8,000 retailers. The English text is 290 GSM-7 characters: two segments, so 16,000 billed SMS. One week a staff member pastes the rates from a spreadsheet with curly quotes and a rupee sign, and the message silently becomes UCS-2: 290 characters now need five segments, or 40,000 billed SMS for the same news. The team adds a pre-send check that flags non-GSM characters, swaps curly quotes for straight ones and writes Rs. instead of the symbol, which brings the update back to two parts.
Recommended practice
Best practices for concatenated SMS
- Keep OTPs and alerts to one segment: 160 GSM-7 or 70 UCS-2 characters.
- Prefer
message_payloador the SAR TLVs when your SMSC supports them rather than hand-building headers. - Test long messages on several handsets and networks before a campaign.
- For long content, send a short SMS with a whitelisted link, or use WhatsApp, where a text message can run to 4,096 characters.
Design intent
Why does concatenated SMS matter?
Segment count is the hidden multiplier on every SMS bill: a campaign that spills one character past 160, or picks up a single emoji, can double or triple its cost overnight. It also affects reliability, because each extra part is another chance for something to go missing, and compliance in India, where the full text must still match a registered DLT content template however many segments it takes. Knowing the mechanics lets developers size messages before sending and explain to marketing why one more line has a price.