~cpchander@dev:~$
cpchander@dev:~/blog$ cat pap2-to-twilio-voip-architecture.mdx
~ cat pap2-to-twilio-voip-architecture.mdx
# published May 18, 2026

From PAP2 to Twilio: 15 years of VoIP architecture for a remote workforce

How a remote-staffing company's telephony evolved across three generations — PAP2 ATAs, then Asterisk + OpenSIPS, then Twilio + SIP trunks — and what each transition actually taught us about scaling B2B voice.


A remote-staffing company is a telephony company that happens to bill by the hour. If the voice quality drops, the trust drops, the client churns. Over 17 years at Virtual Employee I rebuilt our voice stack three times. Each generation had a different ceiling, broke for different reasons, and taught a different lesson.

I'm writing this because most VoIP architecture content online is either 2010-era Asterisk tutorials (some of mine still live at cpchander.blogspot.com) or 2025-era "just use Twilio" hot takes. The truth is in the middle, and it's specific to who is calling whom, how often, and from where.

Generation 1 — PAP2 ATAs (60 → 200 agents)

When I joined in 2006, the entire voice stack was Linksys/Cisco PAP2 ATAs (analog telephone adapters), one per agent. Each PAP2 connected a normal handset to a SIP account from a wholesale VoIP provider. Calls went out through the provider; inbound DIDs landed on the same accounts.

What worked:

  • Zero PBX to manage — provider handled everything
  • Per-agent SIP accounts — easy provisioning, easy deprovisioning
  • Cheap — sub-$50 hardware per seat, no carrier contracts

Where it broke around 200 agents:

  • No central call recording (each provider had its own format, no unified store)
  • No queueing or IVR — clients started asking "can we have an IVR that routes to my team?"
  • No analytics — we couldn't tell management how many calls a team handled
  • Outage exposure — when our VoIP provider had issues, we had no second path

When you outgrow PAP2, you're outgrowing the idea that telephony is a vendor feature. It becomes infrastructure you have to own.

Generation 2 — Asterisk + OpenSIPS (200 → 1,000+ agents)

We brought voice in-house. The architecture had two layers:

[Carriers / VoIP providers] ─SIP─→ [OpenSIPS] ─SIP─→ [Asterisk cluster] ─→ [agents]
                                       ↑                    ↑
                                  routing/policy      call logic (IVR, queues,
                                                       recording, voicemail)

OpenSIPS acted as our SIP edge — routing inbound calls to the right Asterisk node, load-balancing across multiple Asterisk servers, applying carrier policies, and rate-limiting per source IP. It does almost no media; it's a SIP traffic director.

Asterisk did the call logic — IVRs, queues, voicemail, call recording, callme-back style callback flows, and integration with our in-house HRMS for attendance correlation. Each Asterisk server handled ~500 concurrent calls comfortably; for redundancy and scale we ran 4–6.

Lessons that don't show up in tutorials

1. Separate SIP routing from call logic. Tutorials almost always show Asterisk doing both. At scale, this kills you — Asterisk restarts (and you will restart Asterisk) drop in-flight calls. OpenSIPS in front means you can take an Asterisk node out for maintenance without dropping a single call.

2. Record media on a separate I/O path. Call recordings will saturate the disk on the same machine running calls. We learned the hard way. The fix: a dedicated NFS or object-store mount for recordings, with Asterisk writing async.

3. Codec choice is a customer satisfaction lever. G.711 sounds great, uses 64 kbps per direction, and falls apart on any link with packet loss. G.729 sounds fine and uses ~8 kbps. For US-India calls, G.729 ended up being the default — saved bandwidth and was more resilient on lossy international links.

4. SIP trunks change everything. Once we contracted direct SIP trunks per region (US, UK, AU), call quality jumped a generation. Wholesale providers route via whatever's cheapest; SIP trunks let us specify carriers and SLAs.

5. Integrate telephony with your HRMS. Asterisk CDR (Call Detail Record) data correlated with employee IDs let our HRMS auto-compute attendance and productivity for agents on calls. This single integration saved a multi-person team's worth of manual reconciliation.

Where this generation broke

Around 1,000+ agents and serving clients in multiple countries, two problems started compounding:

  1. Carrier-grade reliability at scale was a full-time job. SIP trunks fail, providers have outages, BGP routes flap. Maintaining 99.95%+ uptime across regions started requiring 24/7 NOC-style coverage. We didn't want to be a carrier; we wanted to be a staffing company.

  2. The cloud was eating the PBX. Twilio's programmable voice APIs let us build flows in code instead of dialplan, with per-call cost transparency, automatic regional failover, and an API our developers actually enjoyed.

Generation 3 — Twilio + SIP trunks (hybrid)

The current architecture is hybrid:

[Twilio Voice API] ─SIP─→ [OpenSIPS (still in front)] ─→ [Asterisk where needed]
        ↑
   programmable voice
   (IVR, queues, recording,
    routing, transcription)

Most flows live in Twilio now — TwiML or Twilio Studio handles IVR, queueing, recording, transcription, and the API surface that our internal apps use. SIP trunks are contracted directly with carriers for the price-sensitive routes (outbound to US/UK/AU). Asterisk remains for a few legacy on-prem integrations and specialized flows. OpenSIPS stays in front for SIP-layer routing decisions.

Why this isn't "just use Twilio"

The tempting story is "everyone moves to Twilio and is happy." Reality: at scale, per-minute pricing on Twilio is 3–5× direct SIP trunk pricing. For high-volume routes, you absolutely want SIP trunks. The right architecture is:

  • Twilio for programmable flows + low-volume routes. You're paying for the API and developer velocity.
  • Direct SIP trunks for high-volume routes. You're paying for raw transit.
  • Both behind a unified SIP layer (OpenSIPS or Twilio Elastic SIP Trunking) so applications don't need to know which path a call took.

This hybrid is the right model in 2026 and will be the right model in 2030. The mix shifts; the principle doesn't.

Cost model — what to expect at scale

Rough order-of-magnitude for 1,000+ agents, mixed inbound/outbound, US/UK/AU/IN coverage:

| Component | Monthly order of magnitude | |---|---| | Twilio (programmable + low-volume) | $$ | | Direct SIP trunks (high-volume routes) | $$$ | | Asterisk/OpenSIPS infra (cloud VMs) | $ | | Call recording storage (object store) | $ | | Engineering ops (1 FTE equiv) | $$$$ |

The biggest line item is engineering ops, not telco. People underestimate this. If your VoIP architecture requires more than 0.5 FTE of attention per month, you're under-investing in automation.

What I'd build today for a new B2B voice product

If I were greenfielding a B2B voice product today (and I'm doing something close at GrowMore Solutions for outbound automation):

  1. Twilio Voice API for the application layer. Don't write SIP code unless you have to.
  2. Elastic SIP Trunking from Twilio (or Telnyx) for outbound minutes. Negotiable pricing, programmable.
  3. OpenSIPS only if you need multi-carrier failover or special routing. Otherwise, skip it.
  4. Object storage for recordings from day one. Don't ever let recordings live on call-handling disks.
  5. CDR pipeline into a real data warehouse. Snowflake/BigQuery/Postgres — whatever — but pipe CDR to it from day one. Future-you and future-clients will both thank you.

Use cases — what each generation actually handled

The architecture decisions only matter against the workloads they had to support. Concrete moments:

Use case 1 — The COVID transition (Asterisk + OpenSIPS earned its keep)

When 1,200 agents went home in March 2020 (full story: the COVID remote-work transition playbook), the telephony layer was the part we worried about most and the part that just worked. Within an hour of Day 1 lockdown, SIP softphones registered to our OpenSIPS edge from 1,100+ employee homes. Inbound DIDs rang the agent at home as if they were at the office. Outbound calls to client numbers in the US, UK, AU went through unchanged. We didn't lose a single call. The architectural decision in 2014 to move from on-prem PBX hardware to a SIP-based softswitch (Asterisk + OpenSIPS) on cloud VMs was the difference between business continuity and business shutdown.

Use case 2 — A US healthcare client's HIPAA-grade voice flow

In 2017 we onboarded a US healthcare BPO client whose compliance posture required:

  • All voice calls recorded and stored with encryption-at-rest, 7-year retention
  • Audit logs of every recording access
  • Per-call patient-data tagging via IVR (caller enters MRN before being routed)
  • Segregated recording storage — their calls in a separate S3 bucket, not co-mingled with other clients

We built a dedicated Asterisk dialplan branch for this client. The IVR captured the MRN and tagged the CDR record. Recordings were written directly to an isolated S3 bucket with KMS encryption. Access logs went into a separate CloudTrail. Their internal audit team accessed the recordings through a signed S3 pre-signed URL flow we built. The flexibility of Asterisk's dialplan — combined with cloud object storage — let us deliver a HIPAA-compliant voice product on top of the same platform that ran our standard call flows.

Use case 3 — The 50-IVR setup for an outsourced helpdesk client

For an enterprise outsourced helpdesk client in 2019, we built ~50 distinct IVR flows — one per client product line — all routing into a unified agent queue. Each flow:

  • Played a custom greeting in the appropriate brand voice
  • Asked one or two qualifying questions
  • Routed to skill-tagged agents
  • Recorded the call with product-line metadata
  • Logged the IVR path into CDR for analytics

Building 50 IVRs in dialplan would have been painful. We built it as a config-driven system: a Postgres table held the IVR config; an Asterisk dialplan macro read the config and executed the right branches. The client's IT team could update IVR copy via a small admin UI without our IT involvement. Config-driven dialplan turned what would have been a quarter of dev work into a self-service tool.

Use case 4 — International number procurement at scale

At peak we had ~150 DIDs across the US, UK, Australia, Canada, plus 40+ toll-free numbers. Each had different regulatory requirements (US 911 routing, UK Ofcom registration, AU number portability rules). We standardized on Twilio for new numbers because their API let us provision in minutes and managed the regulatory paperwork. For older numbers we kept the SIP trunks with local carriers — cheaper for high-volume routes. Twilio for agility, direct SIP for cost. The hybrid model is the right answer at scale.

Use case 5 — Resilience against carrier outages

Twice in five years a major SIP trunk carrier had multi-hour outages. Both times, OpenSIPS' carrier-failover routing automatically shifted traffic to the secondary trunk. Inbound calls landed on the same DIDs; outbound calls completed via the secondary route. Our clients didn't notice. The defensive engineering — multi-carrier with automatic failover — paid off in two specific incidents that, if we'd been on a single trunk, would have cost hours of revenue and damaged client trust.

The meta-point

VoIP architecture isn't a static choice — it's a function of where you are on the scale curve and what kind of B2B customers you're serving. PAP2 was correct for 60 agents. Asterisk + OpenSIPS was correct for 1,000. Twilio + SIP trunks is correct now.

The mistake is to pick the architecture you'll need in 5 years and pay for it today, or to pick the architecture you needed 5 years ago and refuse to migrate.

Build for the next 18 months. Plan the migration path for the 18 after that. Repeat.