Back to the blog

ProCat Solutions

SMS gateway and GSM modems: when the old technology is still the most reliable

GSM modem pools, AT commands, SIM management, delivery reports, message queues, combining SMS with voice, and when an aggregator is the better choice.

ProCat Solutions smsgsmgatewaytelecommessage-queue
SMS gateway and GSM modems: when the old technology is still the most reliable

After the VoIP post this summer, several people asked whether we handle SMS on our own infrastructure too. The answer is: it depends, and this post is about what it depends on. Over the past months we built two systems where text messaging was not a supplementary feature but the backbone of the service, and in both the same question came up: aggregator API or our own GSM modems.

Why a GSM modem at all?

SMS is the oldest digital messaging channel that everyone still uses. It needs no app, no data connection, no smartphone. A one-time code, an appointment reminder or an alert reaches its destination even if the recipient uses a ten-year-old handset.

The arguments for GSM modems in practice:

  • The message comes from a local number. Messages sent through an aggregator often appear from a short code or an alphanumeric sender, which some recipients treat as spam and some networks filter.
  • Two-way communication. You can reply to a real SIM card, and the reply arrives where the question came from. That matters in customer support.
  • Predictable cost. A business subscription with an unlimited or large SMS allowance is cheaper than per-message pricing up to a certain volume.
  • Independence. The system does not depend on the availability of an external API.

The drawbacks are real too, and we come back to them at the end.

The modem pool and AT commands

A single modem can send roughly one message per second, so any serious volume requires several modems. We usually solve this with USB modems or industrial devices with multiple SIM slots, under Linux, over serial ports.

We talk to the modems with AT commands. This is a decades-old text protocol: AT+CMGS sends a message, AT+CMGL lists received ones, AT+CSQ returns signal strength. That sounds simple, but in practice:

  • every modem manufacturer interprets the standard slightly differently, and the error messages are often meaningless,
  • PDU mode (binary encoding) is required for accented characters and multipart messages to work reliably; text mode is only good enough for a demo,
  • a serial port can be used by one process at a time, so access per modem has to be serialised,
  • modems occasionally freeze, and only a USB-level reset or a power cycle helps.

The pool is therefore managed by a separate service: one worker per modem, owning the serial port, taking jobs from a shared Redis queue and writing the result back. A modem dropping out then only reduces capacity rather than stopping the service.

SIM management and delivery reports

What we underestimated in the first system: operating the SIM cards is a job of its own. You have to keep track of which SIM is in which modem, what subscription belongs to it, how many messages went out on it in a given period, and when the credit or allowance expires. Operators may suspend SIMs with unusually high traffic, so we spread the load evenly across the pool members and enforce a daily limit per SIM.

The delivery report is one of the big advantages of SIM-based sending: the network confirms that the message reached the handset, not merely that the centre accepted it. For this you have to request the report when sending, and then match the incoming report to the original message by the network message reference. The reference can repeat per modem, so the matching also has to be narrowed by modem and time window.

Queueing and retries

SMS sending is asynchronous. The application does not wait for the message to go out; it puts it in a queue and checks its status later. What we take into account when designing the queue:

  • priority: a one-time login code cannot wait behind a marketing campaign,
  • retries with exponential backoff, but only on modem errors; an invalid number will not get better on the tenth attempt,
  • idempotency: the same message to the same number does not go out twice within a time window,
  • outgoing messages and incoming replies go into a shared, tenant-filtered message log.

That last point leads into another topic: SMS is genuinely useful only when it does not stand alone. In the systems we build, calls, SMS and web notifications share a common event model. If a call is not answered, an SMS goes out; if someone replies to the SMS, it lands on the customer’s timeline. We increasingly see this pattern as a baseline requirement.

When should you pick an aggregator instead?

Honestly: in most cases. Your own modem pool is worth it when a local number, two-way messaging or independence is a concrete business requirement, and someone is there to operate the hardware. For international sending, for high volumes (tens of thousands a day), or simply when there is no capacity to shepherd modems, the aggregator API is the better choice: one HTTP call, a delivery webhook, an invoice at the end of the month.

What we do in either case: abstract the sending layer. The application sends a message through an internal interface, and whether a modem, an aggregator or both sit behind it (modems domestically, an aggregator abroad, for example) is a matter of configuration. That is what lets a modem failure or a provider switch leave the business logic untouched.

QR Code