Skip to content

Email / SMS Delivery (Twilio-like)#

Problem statement (interviewer prompt)

Design a Twilio-style transactional email + SMS delivery service. Accept API calls from customers, route through multiple carriers/providers, manage sender reputation, handle bounces + opt-outs + DLR receipts, and prove deliverability + auditability.

flowchart LR
  CUS([Customer])
  API[Send API]
  Q[[Queue]]
  DEL([Channel workers])
  SMTP((Email MTAs / SES))
  SMS[SMS gateways]
  CUS --> API --> Q --> DEL
  DEL --> SMTP
  DEL --> SMS

    classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
    classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
    classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
    classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
    classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
    classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
    classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
    classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
    classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
    classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
    class CUS client;
    class API,SMS service;
    class Q queue;
    class DEL compute;
    class SMTP external;
flowchart TB
  subgraph Customer
    APP([Customer apps])
  end

  subgraph Edge
    GW[API Gateway]
    AUTH[API key auth]
    IDEM[Idempotency key]
  end

  subgraph Pipeline
    Q[[Kafka per priority]]
    TMPL[Template rendering]
    LANG[Localization]
    SUPP[Suppression list - unsub / bounce]
    DEDUP[Dedup window]
  end

  subgraph Channels
    EMAIL([Email workers + MTA])
    SMS([SMS workers + carrier APIs])
    WHATSAPP[WhatsApp Business API]
    VOICE[Voice]
  end

  subgraph Providers
    SES((SES / Sendgrid / Mailgun))
    TWILIO((Twilio / MSG91 / carriers))
    METAB[Meta Business APIs]
  end

  subgraph Reliability
    RT[Routing per region/carrier]
    FALL[Failover provider]
    BR[Bounce reasons handler]
    REC[Delivery receipts]
    DLR([DLR ingest])
  end

  subgraph Data
    CONT[(Contacts)]
    HIST[(Send history + events)]
    SUPP_DB[(Suppression DB)]
  end

  Customer --> Edge --> Pipeline
  Pipeline --> Channels --> Providers
  Providers --> Reliability --> Data

    classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
    classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
    classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
    classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
    classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
    classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
    classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
    classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
    classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
    classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
    class APP client;
    class GW edge;
    class AUTH,IDEM,TMPL,LANG,SUPP,DEDUP,WHATSAPP,VOICE,METAB,RT,FALL,BR,REC service;
    class CONT,HIST,SUPP_DB datastore;
    class Q queue;
    class EMAIL,SMS,DLR compute;
    class SES,TWILIO external;

Glossary & fundamentals#

Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.

Tag Concept What it is Page
HLD API gateway / BFF single ingress, auth, rate limit, routing api-gateway
HLD Pub/Sub & message brokers topics, consumer groups, delivery semantics pub-sub-pattern
HLD Idempotency & retries safe re-execution, backoff + jitter idempotency-retries
LLD REST API design verbs, statuses, pagination, errors rest-api-design
LLD Async models futures / async-await / coroutines / actors async-models

Quick reference#

Functional#

  • Multi-channel send API.
  • Templates + localization.
  • Suppression / unsubscribe / bounce handling.
  • DLR (Delivery Reports) ingest.
  • Per-channel routing (region, carrier).

Non-functional#

  • p99 send < 2 s for txn.
  • 99.9% delivery for valid recipients.
  • Bursty (campaign sends).

Trade-offs#

  • One provider = simple but risk; multi-provider = failover + costlier ops.
  • Throttle per carrier rate cards strictly.
  • Reputation: warm IPs, SPF/DKIM/DMARC mandatory.

Refs#

  • Twilio architecture talks; SendGrid, Mailgun blogs.
  • Postmark on transactional vs marketing.
  • AWS SES, GCP Pub/Sub + email integrations.

FAQ#

How does an email and SMS delivery service work?#

Customers call an API. The service routes messages through multiple SMTP or SMS carriers, tracks delivery receipts, retries on transient failures, and exposes events via webhooks.

What is sender reputation and why does it matter?#

Mailbox providers score senders by bounce rate, spam complaints, and engagement. A bad reputation routes messages to spam, so providers warm up IPs and segment traffic carefully.

How does the system handle bounces and complaints?#

Hard bounces are added to a suppression list immediately. Soft bounces are retried with backoff. Spam complaints from feedback loops mark the recipient as opted out.

What is a DLR receipt in SMS?#

A Delivery Receipt is an async ack from the carrier indicating whether the SMS reached the handset. Services correlate DLRs to messages and surface them via webhooks.

How does the service stay compliant with opt-out laws?#

Every send checks a suppression list. Reply keywords like STOP trigger automatic opt-out. The system enforces local rules like CAN-SPAM, GDPR, and TCPA per region.

How are multiple SMTP and SMS providers managed?#

A routing layer chooses providers by cost, deliverability, and destination. On failure it falls over to a backup, ensuring no single carrier outage stops the platform.