Skip to content

System Architecture Overview

Sema Link is a pan-African SMS gateway platform. It allows businesses across Africa to send SMS at scale through a REST API, track delivery in real time, and top up via M-Pesa. Agents (resellers) can white-label the service and offer it to their own customers. The platform supports 54 African countries with MNO prefix coverage across 53 of them (151 prefixes, two-tier carrier identification strategy).

Where It Started

The architecture below grew out of this whiteboard sketch — drawn at the very first planning session before a line of code was written. It already had the core ideas right: four frontend apps, RabbitMQ with SMS queue lanes (schedule / normal / priority), a DLR queue, a consumer connecting to aggregators (MNO / Celcom / AGG), and the backend modules (user management, message manager, contact manager, pricing, payments, accounting).

Original whiteboard sketch

What changed from whiteboard to current architecture:

  • Kafka dropped — not needed while the backend is a modular monolith; revisit when services split
  • EMG / Kannel dropped — Celcom Africa has a REST API, no gateway software needed
  • MySQL → PostgreSQL — better fit for relational billing and ledger data
  • DLR consumer extracted into its own worker with micro-batch writes instead of running inside the main backend
  • Phone Validation and SMS Content workers added — not on the whiteboard but emerged from design discussions
  • Three environments (prod / staging / test) formalised for the Customer Web App

High-Level Diagram

Sema Link system architecture diagram

Component Summary

LayerComponentHostingSubdomain
FrontendMarketing WebsiteCloudflare Pagessemalink.africa
FrontendCustomer Web AppCloudflare Pagesapp.semalink.africa
FrontendInternal Admin AppCloudflare Pagesadmin.semalink.africa
FrontendAgent PortalCloudflare Pagesagents.semalink.africa
BackendMain APIDigitalOcean App Platformarc.semalink.africa
BackendSMS WorkerDigitalOcean App Platform— (internal)
BackendDLR Webhook ServiceDigitalOcean App Platformdlr.semalink.africa
BackendDLR Processor WorkerDigitalOcean App Platform— (internal)
BackendPhone Validation WorkerDigitalOcean App Platform— (internal)
BackendSMS Content WorkerDigitalOcean App Platform— (internal)
DataPostgreSQLDigitalOcean Managed DB
DataRedisDigitalOcean Managed Redis
MessagingRabbitMQDigitalOcean Managed RabbitMQ
AggregatorCelcom AfricaExternal

Design Principles

Modular monolith first — The Main API is a single deployable Node.js process, split internally into modules (auth, messaging, billing, etc.). Individual modules can be extracted into standalone services when traffic warrants it, without a full rewrite.

SMS Worker and DLR Webhook Service are separate deployables — each runs as its own DigitalOcean App Platform component with independent scaling, environment variables, and deploy lifecycle. They share the backend monorepo for now; they can be extracted to separate repos when team ownership warrants it. Keeping them separate from the Main API means a crashing worker never takes down the API, and each component can be scaled independently.

Cloudflare for the frontend, DigitalOcean for the backend — Cloudflare Pages gives zero-cost global CDN for static apps. DigitalOcean App Platform gives managed containers with straightforward vertical and horizontal scaling for the Node.js services.

Celcom Africa as the aggregator — Celcom connects to all major East African MNOs. Sema Link calls their REST API to submit SMS and receives delivery reports via webhook callbacks. Direct MNO connections and SMPP will be evaluated once volume justifies it.

Internal use only — Sema Link Engineering