BroadNet
The JournalEngineering
Engineering

SMS throughput and TPS planning: sizing SMPP binds for high-volume campaigns.

SMS TPS is governed by SMPP window size divided by round-trip latency. Here is how to size binds, plan for OTP and campaign bursts, and hit real throughput.

BroadNet Engineering
10 min read
Engineering · Issue 02
10 min read

PS (transactions per second) is the number of SMS submit operations your platform completes each second. Over SMPP, sustained throughput is governed by the session window — the count of un-acknowledged PDUs in flight — divided by the round-trip latency to the SMSC: throughput ≈ window ÷ RTT. To scale past one session's ceiling, run multiple parallel binds.

Want the number without the theory? Feed your window size, latency, and bind count into the TPS calculator and it returns per-bind and aggregate throughput. This article is the reasoning behind the tool.

What TPS means in SMS

TPS — transactions per second, used interchangeably with messages per second in A2P messaging — measures how many message-submit operations leave your system and are accepted downstream each second. In SMPP terms, one transaction is one submit_sm PDU that the SMSC acknowledges with a submit_sm_resp. TPS is the unit every contract, rate limit, and capacity plan is written in, so getting the definition exact matters: it counts submits accepted for delivery, not messages confirmed delivered to a handset — that is a separate delivery-receipt (DLR) flow that arrives later as deliver_sm PDUs.

The distinction between submit-rate and delivery-rate is where most capacity plans go wrong. You can submit at 5,000 TPS while a downstream operator only terminates at 2,000; the gap fills a queue somewhere. Planning throughput means planning the whole chain — your client, the SMPP session to the platform, the platform's route to the terminating SMSC gateway, and that operator's own A2P rate ceiling.

How SMPP throughput actually works: window and latency

SMPP is a persistent, stateful TCP protocol. You bind once and stream PDUs in both directions for hours. Throughput on a single bind is not set by bandwidth — SMS PDUs are tiny — but by two variables: the asynchronous window and the round-trip time.

The window is the maximum number of submit_sm PDUs you may send before you must wait for a submit_sm_resp to come back. In synchronous mode the window is effectively 1: you submit, you block until the response, then submit again — so one slow round trip throttles everything. In asynchronous (windowed) mode you fire up to N submits without blocking, and responses flow back concurrently. That N is the window size, negotiated with the platform per bind.

Because a bind can have at most `window` PDUs outstanding, and each PDU occupies the pipe for one round-trip time (RTT) before its slot frees, the single-bind ceiling is simply the window divided by the RTT:

snippet
# Single-bind SMPP throughput ceiling
tps_per_bind = window_size / rtt_seconds
# Window of 10 un-acked PDUs, 100 ms round trip to the SMSC:
tps_per_bind = 10 / 0.100 = 100 submit_sm/s
# Same window, latency halved to 50 ms:
tps_per_bind = 10 / 0.050 = 200 submit_sm/s
# Scale horizontally across N parallel binds:
total_tps = tps_per_bind * n_binds
= 200 * 4 = 800 submit_sm/s

Two levers fall out of this. Widen the window and more PDUs sit in flight per round trip. Shorten the RTT — by placing your client near the platform's ingest or by removing per-request TLS handshakes, which is exactly what a persistent SMPP bind buys you over a per-call HTTP request — and each slot recycles faster. A window that is too small starves a low-latency link; a window that is too large just buffers PDUs the SMSC is not ready for and inflates latency without adding throughput.

Worked example: window and RTT to TPS, then multiple binds

Suppose your client sits in the same region as the platform and measures an 80 ms RTT under load. With a negotiated window of 50, a single bind sustains 50 ÷ 0.080 ≈ 625 TPS. That is already comfortable for most senders. When your peak needs more, you do not chase an ever-larger window — beyond a point it only queues — you add binds. Four binds at 625 TPS each give roughly 2,500 TPS aggregate; the platform load-balances submits across the sessions.

Window (un-acked PDUs)Round-trip timeTPS per bindParallel bindsAggregate TPS
10100 ms1001100
1050 ms2004800
5080 ms62542,500
5040 ms1,250810,000

The bottom row, 10,000 TPS, sits comfortably inside the up-to-30,000 SMS/sec a single BroadNet node sustains — reached not with one heroic bind but with a modest window, low latency, and horizontal binds. Model your own combination in the TPS calculator before you commit to a contracted rate, because the arithmetic decides how many binds your ops team has to run and monitor.

Provisioned TPS versus raw capability

There are two throughput numbers and they are not the same. Raw capability is what the window-and-latency arithmetic above says your binds could push. Provisioned (contracted) TPS is the rate your account is authorised to submit at — a policy limit the platform enforces so one customer cannot starve a shared route or trip an operator's abuse controls. If your contract is 500 TPS, opening ten wide binds will not get you to 5,000; the platform paces you to the provisioned figure and returns throttling responses (ESME_RTHROTTLED) above it.

So bind sizing has two jobs: provision enough contracted TPS for your real peak, and configure enough binds and window to actually reach that provisioned number given your latency. Under-provision and you are throttled; over-build binds against a low contract and you waste ops effort. Size the contract to peak demand first, then size the binds to hit it.

What eats into your real throughput

The formula gives a clean ceiling. Four real-world factors pull delivered throughput below it, and every capacity plan should account for them:

  • Segmentation. A message longer than one SMS segment is split and sent as multiple submit_sm PDUs — a concatenated (UDH) message, in which each GSM-7 segment holds 153 characters rather than 160, because the concatenation header consumes the difference. A 480-character GSM-7 marketing message is therefore four segments (3 × 153 = 459 falls short of 480, so a fourth is needed), so it consumes four transactions of your TPS budget, not one. UCS-2 (Arabic, emoji) drops the single-segment limit to 70 characters — 67 per segment once concatenated — so non-Latin campaigns burn TPS faster still. Count segments, not messages, when planning.
  • Queueing and back-pressure. When you submit faster than a downstream operator terminates, PDUs queue. A healthy platform applies back-pressure — throttling responses or a shrinking effective window — rather than silently dropping. Treat ESME_RTHROTTLED and rising response latency as signals to slow the submit loop, not errors to retry blindly.
  • Per-route operator rate limits. The terminating operator sets its own A2P TPS cap per sender or per binding, independent of your contract. You can submit at 5,000 TPS, but if the destination network accepts 1,000 for your sender ID, real delivery is paced at 1,000 and the rest queues. Route-level ceilings, not your bind, often define real-world throughput.
  • Sustained versus burst. A window sized for average load will not absorb a spike. OTP traffic is spiky by nature — a product launch or a broadcast triggers a wall of verification codes in seconds — so size for the burst, not the daily mean.

Peak versus sustained: sizing for OTP bursts

Sustained TPS is your steady rate; peak TPS is the worst second you must survive without codes arriving late. For OTP, peak is what matters — a verification code that lands after the user has given up has failed even if it is eventually delivered. OTP arrivals are bursty and correlated: a marketing push, a flash sale, or a regional event in the GCC around Ramadan or a national holiday can concentrate sign-ins into a few minutes. Size binds and contracted TPS to that peak with headroom, and let the shared platform absorb the overflow through queueing rather than dropping.

This is also where SMPP earns its operational cost over HTTP. A persistent bind removes the per-request TLS handshake from the critical path, so latency stays flat as volume climbs — the property you want when a burst hits. Teams that do not need that profile are often better served by the SMS API over HTTPS; the trade-off is throughput headroom and latency stability versus integration simplicity.

Sizing binds for a high-volume or OTP-burst workload? Run your window, latency, and peak through the TPS calculator, then talk to us about provisioning it — BroadNet sustains up to 30,000 SMS/sec per node with reach to 200+ countries — direct to the operator in 86 over 1,000+ direct operator connections — at a 99.99% platform SLA, on SMPP or the SMS API.

Frequently asked questions

What is TPS in SMS?

TPS means transactions per second — the number of SMS submit operations your platform accepts each second, used interchangeably with messages per second in A2P messaging. In SMPP, one transaction is one submit_sm PDU acknowledged by a submit_sm_resp. TPS counts submits accepted for delivery, not messages confirmed on a handset, which is tracked separately by delivery receipts arriving as deliver_sm PDUs.

How many SMS per second can SMPP send?

There is no universal number; a single SMPP bind sustains window ÷ RTT messages per second. A window of 50 over an 80 ms round trip yields about 625 TPS per bind, and running multiple parallel binds scales that further — reaching into the thousands. Real throughput is then capped by your contracted TPS and each terminating operator's own A2P rate limit, whichever is lower.

How do I size SMPP binds and window for peak load?

Start from your peak TPS, not your average. Divide it by the per-bind ceiling (window ÷ RTT) to get the number of binds, then provision contracted TPS to cover the peak with headroom. Count segments rather than messages — multipart and UCS-2 messages consume extra transactions — and add margin for OTP bursts. Model the combination in a TPS calculator before committing, then load-test against it.

References

  • SMPP v3.4 Protocol Specification — asynchronous transmission, window size, and PDU semantics: smpp.org
  • SMPP v5.0 Protocol Specification — congestion state and throttling behaviour: smpp.org
  • GSMA — IR.71 SMS Network-to-Network Interconnect and A2P framework: gsma.com
  • BroadNet — SMPP integration guide and the TPS calculator for bind sizing.
Was this useful?

How we write and review content

Written by

BroadNet Engineering

Engineering operates the wire: SMPP binds, SS7 stacks, routing engines, the boring infrastructure that makes one-billion-message months possible. They write here when something is worth writing down.

The Journal, by email

One essay a month. Nothing else.

Subscribe and we'll send the next piece — engineering, regulation, or industry — the day it ships. No drip campaigns, no product pitches, no third-party sharing. Unsubscribe in one click.

We send one email a month. Unsubscribe anytime. See our privacy policy.

What you'll get
  • Long-form, not link bait
    Six to eleven minutes of focused writing on a single topic.
  • Written by operators
    Engineers, regulatory leads, and product writing in-house.
  • Region-aware
    MENA-grounded view on regulators, operators, and channel mix.
  • Once a month
    No drip campaign. One essay when there is one to share.
Stop reading. Start shipping.

Most of what we write we learned in production.

If this piece made you nod, we should probably talk. Bring the use case, the volumes, the markets — we'll come back with routing, pricing, and a reference customer you can call.

$ curl -X POST https://api.broadnet.me/sms/sendSms