I've noticed that SMS functionalities tend to get tightly integrated with authentication, onboarding, and alerts in web apps, which can lead to a fragile setup over time, especially with retry mechanisms, limits, and potential failures. For developers who have implemented SMS at scale, how should this be abstracted? Do you recommend building a service layer for SMS, and what architectural patterns have proven effective for longevity? I'm looking for architectural insights rather than specific tools.
4 Answers
Abstracting SMS through a small service layer made a significant improvement for us. We use Signalhouse.io for sending messages now, and the app itself doesn’t need to worry about how the SMS is delivered, which simplifies our architecture.
We keep the SMS functionality somewhat abstracted, similar to our email system. We create an object in our database that represents the message to be sent along with parameters like retries, enqueue it, and then let a background process handle the sending. Feedback on delivery updates that message object, and any replies create new message entries.
Honestly, I’d advise against relying on SMS entirely. It’s often unreliable—like, I’ve gotten validation codes from my bank hours after requesting them. For critical tasks, opting for 2FA or email could be a better choice, as the delays with SMS can be ridiculous.
Exactly! SMS can be a useful option for many, but those delays are real, even if not super common. Just don’t put all your eggs in that basket.
One solid approach I've seen is following a Message Queue pattern. Essentially, your app can create and store SMS messages, while a separate process handles the I/O, error handling, and retry logic. While using a message broker like Kafka isn’t essential, it can definitely streamline operations.

Having your I/O behind a service is definitely a smart pattern. Beyond freeing up your app, it also aids in implementing Dependency Injection and makes testing easier by allowing you to mock services.