<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wae Luxe</title>
    <description>The latest articles on DEV Community by Wae Luxe (@time_luxe).</description>
    <link>https://dev.to/time_luxe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4073346%2F529fa6b6-695f-4d37-8afd-ec40439c0ab0.png</url>
      <title>DEV Community: Wae Luxe</title>
      <link>https://dev.to/time_luxe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/time_luxe"/>
    <language>en</language>
    <item>
      <title>How I Handle Real-Time eSIM Provisioning Without a Backend Team</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 01 Sep 2026 00:05:58 +0000</pubDate>
      <link>https://dev.to/time_luxe/how-i-handle-real-time-esim-provisioning-without-a-backend-team-clf</link>
      <guid>https://dev.to/time_luxe/how-i-handle-real-time-esim-provisioning-without-a-backend-team-clf</guid>
      <description>&lt;h1&gt;
  
  
  How I Handle Real-Time eSIM Provisioning Without a Backend Team
&lt;/h1&gt;

&lt;p&gt;Quick Answer: I use message queues to decouple eSIM API requests from user-facing responses, webhook listeners for carrier status updates, and idempotent endpoints to prevent duplicate activations. This pattern lets a single developer manage hundreds of daily provisionings without building a backend team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I first started building an eSIM marketplace, the biggest shock wasn't the complexity of carrier APIs—it was realizing I'd have to orchestrate real-time provisioning alone. No SRE team. No platform engineers. Just me and a VPS.&lt;/p&gt;

&lt;p&gt;eSIM provisioning is deceptively simple in theory: a user buys a data plan, you generate a QR code, they scan it, they're online. In practice, you're juggling asynchronous carrier webhooks, retry storms, race conditions, and the existential dread of provisioning the same SIM twice.&lt;/p&gt;

&lt;p&gt;This article is my field guide to keeping that infrastructure alive and sane without hiring backend engineers. It's not theory—it's what I shipped, broke, and fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture Nobody Warned You About
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Makes eSIM Provisioning Hard?
&lt;/h3&gt;

&lt;p&gt;eSIM (embedded SIM) provisioning involves remotely downloading a carrier profile to a device's embedded universal integrated circuit card (eUICC). Unlike traditional SIM cards that you physically swap, eSIM activation is a digital handshake between your platform, a carrier's SM-DP+ server, and the user's device.&lt;/p&gt;

&lt;p&gt;The challenge? This handshake is asynchronous and failure-prone. A provisioning request might take anywhere from 2 seconds to 2 minutes. Carriers throttle requests. Devices go offline mid-provisioning. And every retry risks creating duplicate profiles that cost money and confuse users.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Three-Pillar Approach
&lt;/h3&gt;

&lt;p&gt;I settled on three architectural patterns that keep the system reliable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Message Queues:&lt;/strong&gt; Decouple user-facing requests from carrier API calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhooks:&lt;/strong&gt; Receive carrier status updates instead of polling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency:&lt;/strong&gt; Ensure duplicate requests never provision twice
These aren't novel concepts, but combining them correctly for eSIM workflows requires specific decisions I'll walk through.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pillar 1: Message Queues for Async Processing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Synchronous Provisioning Fails
&lt;/h3&gt;

&lt;p&gt;Early on, I made the classic mistake of calling the carrier API directly during the HTTP request that handled the user's purchase. When the carrier API timed out after 30 seconds, the user's payment succeeded but their eSIM didn't provision. Worse, they couldn't retry because the payment was already processed.&lt;/p&gt;

&lt;p&gt;The fix was decoupling with a message queue. Now the purchase endpoint immediately returns a "processing" status, enqueues a provisioning job, and responds to the user in under 200ms.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Actually Use
&lt;/h3&gt;

&lt;p&gt;I use BullMQ (a Redis-based queue for Node.js) with three worker instances handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Provisioning jobs:&lt;/strong&gt; The actual carrier API calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry jobs:&lt;/strong&gt; Failed provisionings with exponential backoff&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup jobs:&lt;/strong&gt; Stale pending activations after 24 hours
BullMQ handles rate limiting through its &lt;code&gt;rateLimit&lt;/code&gt; option, which is critical because most carriers enforce strict request-per-minute quotas. I configure it based on each carrier's documented limits—some allow 60 RPM, others only 10.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Pattern: The Job Handler
&lt;/h3&gt;

&lt;p&gt;Here's the pattern I follow for queue workers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provisionJob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;provision&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;carrier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;global-esim&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;profileType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-plan-5gb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`provision-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;attempts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;backoff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exponential&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;removeOnComplete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;idempotencyKey&lt;/code&gt; here is crucial—I'll explain why in the third pillar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring Queue Health
&lt;/h3&gt;

&lt;p&gt;I track three metrics obsessively: queue depth (jobs waiting), processing latency (time from enqueue to completion), and dead letter count (jobs that exhausted retries). When queue depth spikes above 50, I get an alert. When dead letters accumulate, I investigate immediately.&lt;/p&gt;

&lt;p&gt;The lesson: with message queues, visibility is everything. Without monitoring, you're just hoping jobs complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pillar 2: Webhooks for Carrier Updates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Polling Is a Trap
&lt;/h3&gt;

&lt;p&gt;My first instinct was to poll carrier APIs for provisioning status. Every 5 seconds, query the carrier: "Is it done yet?" This created a cascade of problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I hit rate limits during peak hours&lt;/li&gt;
&lt;li&gt;I paid for API calls that returned the same "pending" status&lt;/li&gt;
&lt;li&gt;I couldn't scale beyond a few hundred daily orders
Webhooks flipped the model. Instead of asking the carrier for updates, the carrier tells me when something changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Webhook Implementation Patterns
&lt;/h3&gt;

&lt;p&gt;Carrier webhooks are notoriously unreliable. Some fire once and expect you to handle it. Others retry aggressively. A few send out-of-order updates. I built my webhook handler with these assumptions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption 1: Webhooks arrive out of order.&lt;/strong&gt; I include a &lt;code&gt;timestamp&lt;/code&gt; field in every webhook payload and only process updates that are newer than the last recorded state for that order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption 2: Webhooks retry indefinitely.&lt;/strong&gt; I store processed webhook IDs in Redis with a 24-hour TTL to deduplicate identical payloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption 3: Webhooks sometimes lie.&lt;/strong&gt; I verify webhook signatures using the carrier's public key before trusting the payload. No signature verification means no state change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling Webhook Failures
&lt;/h3&gt;

&lt;p&gt;When my webhook endpoint returns a non-200 status, some carriers retry immediately, others wait 30 seconds, and a few give up after one attempt. I standardized my responses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;200 OK:&lt;/strong&gt; Webhook processed successfully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;202 Accepted:&lt;/strong&gt; Webhook received but not yet actionable (e.g., waiting for prerequisite state)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4xx errors:&lt;/strong&gt; Don't retry (malformed payload, invalid signature)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5xx errors:&lt;/strong&gt; Retry is acceptable
This gives carriers clear signals about what to do next, reducing both noise and missed updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What Happens When Webhooks Break
&lt;/h3&gt;

&lt;p&gt;Carriers have outages too. When webhooks stop arriving, I fall back to a scheduled job that polls active provisionings every 5 minutes. This isn't my primary flow—it's my safety net. The key is keeping this fallback visible: I log every fallback poll so I know when webhooks are flaky.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pillar 3: Idempotency for Safe Retries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Duplicate Provisioning Nightmare
&lt;/h3&gt;

&lt;p&gt;Without idempotency, retrying a failed provisioning creates duplicate eSIM profiles. Each profile costs money. Users end up with multiple QR codes. Support tickets multiply. This was my first major production incident.&lt;/p&gt;

&lt;p&gt;Here's what happened: a carrier API returned a 500 error during provisioning. My queue retried the job. The carrier actually processed the first request but returned an error anyway. The retry created a second profile. The user had two active eSIMs for one purchase.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Idempotency Keys Work
&lt;/h3&gt;

&lt;p&gt;An idempotency key is a unique identifier attached to every provisioning request. If the carrier receives the same key twice, it processes the request once and returns the same response both times.&lt;/p&gt;

&lt;p&gt;I generate keys using a deterministic pattern: &lt;code&gt;provision-{orderId}-{attemptNumber}&lt;/code&gt;. For the first attempt: &lt;code&gt;provision-123-1&lt;/code&gt;. If that fails and I retry, I use &lt;code&gt;provision-123-2&lt;/code&gt;. This lets me distinguish between carrier failures (retry with new key) and network failures (retry with same key).&lt;/p&gt;

&lt;h3&gt;
  
  
  Idempotency at Every Layer
&lt;/h3&gt;

&lt;p&gt;Idempotency isn't just for carrier APIs. I apply it throughout my stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; UPSERT operations for order status updates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queue jobs:&lt;/strong&gt; BullMQ's job ID prevents duplicate enqueues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook processing:&lt;/strong&gt; Redis-based deduplication of webhook payloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User notifications:&lt;/strong&gt; Notification IDs prevent duplicate emails
The rule: if an operation can happen twice, it will. Design for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Error Recovery Without a Team
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Breaks and How I Fix It
&lt;/h3&gt;

&lt;p&gt;Running infrastructure solo means you can't rotate on-call shifts. When something breaks at 3 AM, you handle it. Here's my recovery playbook:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1: Carrier API is down.&lt;/strong&gt; Jobs queue up but don't fail. I monitor queue depth and set an alert threshold. If a carrier is down for more than 30 minutes, I pause that carrier's queue and show users a maintenance message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 2: Webhook endpoint is unreachable.&lt;/strong&gt; My fallback polling catches missed updates. I fix the endpoint, then replay any affected orders manually using my admin dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 3: Database connection drops mid-provisioning.&lt;/strong&gt; The job fails and retries. Because of idempotency keys, the carrier doesn't create duplicates. The retry succeeds once the database recovers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 4: Race condition between webhook and job completion.&lt;/strong&gt; I use database row-level locking (SELECT FOR UPDATE) when updating order status. The first update wins, the second sees the state change and exits cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Admin Dashboard I Can't Live Without
&lt;/h3&gt;

&lt;p&gt;I built a minimal admin dashboard that shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orders by status (pending, processing, completed, failed)&lt;/li&gt;
&lt;li&gt;Queue depth and worker status&lt;/li&gt;
&lt;li&gt;Recent webhook deliveries with payload previews&lt;/li&gt;
&lt;li&gt;Failed jobs with retry buttons
This dashboard is my entire operations team. I can diagnose most issues in under 2 minutes without SSHing into servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mistakes That Cost Me Time
&lt;/h3&gt;

&lt;p&gt;Looking back, I'd make three changes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Start with webhooks immediately.&lt;/strong&gt; I spent two months polling before implementing webhooks. That was two months of unnecessary API costs and complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use structured logging from day one.&lt;/strong&gt; I used console.log for too long. Switching to structured JSON logging (with correlation IDs spanning queue jobs, webhooks, and API calls) made debugging 10x faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Build the admin dashboard earlier.&lt;/strong&gt; I operated through database queries for months. The dashboard wasn't optional infrastructure—it was essential tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Decouple with queues:&lt;/strong&gt; Never call carrier APIs synchronously during user requests. Use message queues to handle async work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust but verify webhooks:&lt;/strong&gt; Implement signature verification, timestamp ordering, and deduplication. Always have a polling fallback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency everywhere:&lt;/strong&gt; If an operation can retry, it will. Use idempotency keys at API boundaries and deduplication everywhere else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor queue health:&lt;/strong&gt; Queue depth, latency, and dead letter metrics are your early warning system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build operational tooling:&lt;/strong&gt; A minimal admin dashboard is more valuable than perfect architecture when you're running solo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan for failure:&lt;/strong&gt; Carriers fail, webhooks drop, databases disconnect. Design every component to recover gracefully.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is eSIM provisioning?
&lt;/h3&gt;

&lt;p&gt;eSIM provisioning is the digital process of downloading a carrier profile to a device's embedded SIM chip, enabling cellular connectivity without a physical SIM card swap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why can't eSIM provisioning be synchronous?
&lt;/h3&gt;

&lt;p&gt;Carrier APIs take 2 seconds to 2 minutes to process provisioning requests. Holding an HTTP connection open that long risks timeouts, poor user experience, and resource exhaustion.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is an idempotency key?
&lt;/h3&gt;

&lt;p&gt;An idempotency key is a unique identifier sent with API requests that ensures duplicate requests produce the same result without side effects, preventing duplicate eSIM activations.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I handle carrier API rate limits?
&lt;/h3&gt;

&lt;p&gt;Use a queue with rate limiting configured to each carrier's documented requests-per-minute quota. BullMQ and similar libraries support this natively.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if webhooks stop arriving?
&lt;/h3&gt;

&lt;p&gt;Implement a fallback polling mechanism that checks active provisioning status every 5 minutes. Log all fallback polls to monitor webhook reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I prevent duplicate eSIM profiles?
&lt;/h3&gt;

&lt;p&gt;Use idempotency keys for carrier API requests, implement webhook deduplication with Redis, and use database UPSERTs for status updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can one developer really manage this infrastructure?
&lt;/h3&gt;

&lt;p&gt;Yes, with proper tooling: message queues for async processing, webhook handlers for status updates, idempotent APIs for safety, and a monitoring dashboard for visibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the best message queue for eSIM provisioning?
&lt;/h3&gt;

&lt;p&gt;BullMQ (Redis-based) works well for Node.js applications. Alternatives include RabbitMQ, Apache Kafka, or cloud-native options like AWS SQS and Google Cloud Pub/Sub.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I monitor queue health?
&lt;/h3&gt;

&lt;p&gt;Track queue depth (pending jobs), processing latency (enqueue to completion), and dead letter count (failed retries). Set alerts on thresholds that indicate problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I verify webhook signatures?
&lt;/h3&gt;

&lt;p&gt;Yes, always verify webhook signatures using the carrier's public key. Unsigned or incorrectly signed webhooks should be rejected to prevent spoofed status updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Running real-time eSIM provisioning infrastructure as a solo developer isn't about cutting corners—it's about choosing the right abstractions. Message queues buy you time. Webhooks buy you efficiency. Idempotency buys you safety.&lt;/p&gt;

&lt;p&gt;The architecture I've described here handles hundreds of daily provisionings without requiring a backend team. It's not perfect, but it's resilient enough that I sleep through the night.&lt;/p&gt;

&lt;p&gt;If you're building something similar, start with queues and idempotency. Add webhooks when you're ready. And build that admin dashboard sooner than you think you need it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. If you're interested in eSIM infrastructure or want to see how I handle other parts of the stack, check out &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;our homepage&lt;/a&gt; or browse &lt;a href="https://iwantesim.com/blog" rel="noopener noreferrer"&gt;our technical blog&lt;/a&gt; for more engineering write-ups. We also document &lt;a href="https://iwantesim.com/sitemap" rel="noopener noreferrer"&gt;our integration patterns&lt;/a&gt; for developers building eSIM-enabled products.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>esim</category>
      <category>infrastructure</category>
      <category>backend</category>
      <category>webhooks</category>
    </item>
    <item>
      <title>From Side Project to 12,000+ Travelers: The iWanteSIM Story</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Fri, 28 Aug 2026 00:06:26 +0000</pubDate>
      <link>https://dev.to/time_luxe/from-side-project-to-12000-travelers-the-iwantesim-story-2dkf</link>
      <guid>https://dev.to/time_luxe/from-side-project-to-12000-travelers-the-iwantesim-story-2dkf</guid>
      <description>&lt;h1&gt;
  
  
  From Side Project to 12,000+ Travelers: The iWanteSIM Growth Story
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Quick Answer:&lt;/strong&gt; iWanteSIM started as a weekend side project to solve a personal travel pain point — expensive roaming charges. By building in public, listening to early users, and iterating rapidly, it grew into an eSIM platform serving over 12,000 travelers across 150+ countries without paid advertising.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction: The $12 Coffee That Started Everything
&lt;/h2&gt;

&lt;p&gt;It was a Tuesday in Lisbon. I had just landed, opened my phone to check Google Maps, and watched my carrier charge me $12 for 30 seconds of data. Not for a download. Not for a video. Just for loading a map.&lt;/p&gt;

&lt;p&gt;That was the moment. Not the moment I decided to build something — the moment I realized millions of people were getting robbed every day by roaming fees that belong in 2005, not 2024.&lt;/p&gt;

&lt;p&gt;I had heard about eSIM technology. Embedded SIMs — no physical card, instant activation, local rates. But every provider I found felt like a bank: complicated pricing, hidden fees, and a UX that screamed "we don't care about you."&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; over a single weekend. I didn't know if anyone would use it. I didn't have a marketing budget. I just knew that $12 for a map was absurd, and I was done paying it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tuvy2k6fiw0n0owsosq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tuvy2k6fiw0n0owsosq.gif" alt="excited developer typing" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is eSIM and Why Does It Matter for Travelers?
&lt;/h2&gt;

&lt;p&gt;eSIM stands for "embedded SIM" — a programmable chip built directly into your phone that lets you download carrier profiles over the air. No physical SIM card. No hunting for airport kiosks. No cutting SIMs with scissors (we've all been there).&lt;/p&gt;

&lt;p&gt;For travelers, eSIM is transformative:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instant activation:&lt;/strong&gt; Scan a QR code and you're online before you leave the terminal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local pricing:&lt;/strong&gt; Pay what locals pay, not $12 for a map&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dual SIM capability:&lt;/strong&gt; Keep your home number active while using local data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No physical waste:&lt;/strong&gt; No plastic cards to lose or dispose of
The technology has been around since 2016, but adoption exploded in 2020-2024 as Apple, Samsung, and Google made eSIM standard across flagship devices. Today, over 3.5 billion eSIM-enabled devices are in circulation globally, and the eSIM market is projected to reach $16.3 billion by 2027.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The First Build: A Landing Page and a Prayer
&lt;/h2&gt;

&lt;p&gt;Weekend one was simple: a landing page explaining what eSIM was, a few regional data plans, and a Stripe integration. I used Next.js because I knew it, Tailwind because I didn't want to think about CSS, and Vercel because deploys took 30 seconds.&lt;/p&gt;

&lt;p&gt;I didn't build a dashboard. I didn't build analytics. I built one thing: a way for someone to buy an eSIM plan and receive a QR code in under 60 seconds.&lt;/p&gt;

&lt;p&gt;Then I posted it on Reddit's r/digitalnomad and r/travel with the title: "I built a tool to kill roaming fees. Here's what I learned."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0HlTy9x8FZo0AHQ0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0HlTy9x8FZo0AHQ0/giphy.gif" alt="nervous person waiting for response" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The response? Brutal. Honest. And exactly what I needed.&lt;/p&gt;

&lt;p&gt;"Why would I trust some random site with my phone?"&lt;/p&gt;

&lt;p&gt;"Your pricing table is confusing."&lt;/p&gt;

&lt;p&gt;"Can I use this in Japan? What carriers?"&lt;/p&gt;

&lt;p&gt;"Do you have an affiliate program?" (That one surprised me.)&lt;/p&gt;

&lt;p&gt;I answered every comment. I fixed the pricing table that night. I added a "How it Works" section. And I got my first 47 signups — not customers, just emails — but 47 people who cared enough to tell me what was wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding Product-Market Fit: Listening to the Right People
&lt;/h2&gt;

&lt;p&gt;Here's the thing about "product-market fit" — it's not a moment. It's a gradient. You inch toward it with every conversation, every canceled subscription, every support ticket that makes you wince.&lt;/p&gt;

&lt;p&gt;My first paying customer came two weeks later. A software developer from Berlin flying to Tokyo for a conference. He bought a 5GB Japan plan for $12.50. I made about $3 in margin.&lt;/p&gt;

&lt;p&gt;I sent him a personal email: "Hey, thanks for being our first customer. Any feedback?"&lt;/p&gt;

&lt;p&gt;He replied with a Loom video. Seven minutes of him walking through the purchase flow, pointing out friction I had normalized. The confirmation email looked like spam. The QR code was too small to scan easily. The "activation instructions" assumed he knew what "APN" meant.&lt;/p&gt;

&lt;p&gt;I fixed all of it. I added a "first-timer" guide. I made the QR code bigger. I rewrote the email in plain English.&lt;/p&gt;

&lt;p&gt;Then I did something that changed everything: I asked if I could share his feedback (anonymized) in a blog post. He said yes. That post — "What Our First 10 Customers Taught Us" — became our most-shared content for six months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; Early users don't just want your product. They want to feel like co-founders. Treat them that way, and they'll bring friends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building in Public: The Growth Engine Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;I started sharing our numbers on Twitter (now X) and Dev.to. Not just the wins — the struggles too.&lt;/p&gt;

&lt;p&gt;"Week 6: 127 customers, $892 revenue. Still not profitable. Here's why."&lt;/p&gt;

&lt;p&gt;"We just lost our first enterprise customer. Here's what we learned."&lt;/p&gt;

&lt;p&gt;"I spent 4 hours yesterday debugging a QR code issue. Turns out it was a caching problem. Here's how we fixed it."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7abB06u9bNZf8Uo0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7abB06u9bNZf8Uo0/giphy.gif" alt="celebration confetti" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building in public did three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trust:&lt;/strong&gt; When you're transparent about your process, people trust you with their money&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback:&lt;/strong&gt; Developers and travelers started DMing me feature ideas and bug reports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribution:&lt;/strong&gt; Every post brought 50-200 qualified visitors who already understood our value
By month four, we had 2,000 customers. Not from ads. From being honest about what we were building and why.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Technical Pivot: From MVP to Platform
&lt;/h2&gt;

&lt;p&gt;The original architecture couldn't scale. I knew it would break eventually, but "eventually" arrived faster than expected when a TikTok influencer mentioned us in a "travel hacks" video. Traffic spiked 40x in 48 hours.&lt;/p&gt;

&lt;p&gt;The server didn't crash — the database did. Postgres on a $20 DigitalOcean droplet wasn't built for concurrent QR code generations. Lesson learned.&lt;/p&gt;

&lt;p&gt;We rebuilt the core in three phases:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Infrastructure
&lt;/h3&gt;

&lt;p&gt;Migrated to a managed PostgreSQL instance, added Redis for caching, and implemented rate limiting. Cost went from $20/month to $180/month. Revenue was $4,200/month by then, so it felt like a win, not a panic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: API Architecture
&lt;/h3&gt;

&lt;p&gt;We needed to support multiple eSIM providers for redundancy. I built an abstraction layer that normalized different provider APIs into a single internal interface. Now we can swap providers without touching customer-facing code.&lt;/p&gt;

&lt;p&gt;This matters more than it sounds. When one provider had an outage in Southeast Asia last March, we routed 100% of traffic to a backup in 90 seconds. Zero customer impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: The Dashboard Nobody Asked For (But Everyone Uses)
&lt;/h3&gt;

&lt;p&gt;Users kept asking for "usage tracking." I resisted — it felt like feature creep. But I built a simple dashboard anyway: data used, days remaining, signal strength by country.&lt;/p&gt;

&lt;p&gt;Usage rate among active customers jumped 34%. Turns out people just want to know if they're about to run out of data before a Zoom call. Obvious in hindsight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling to 12,000+: What Actually Moved the Needle
&lt;/h2&gt;

&lt;p&gt;Here's what worked and what didn't, with numbers:&lt;/p&gt;

&lt;p&gt;ChannelInvestmentCustomersCACBuilding in public (Twitter/Dev.to)~10 hrs/week~4,200$0SEO content (travel guides + eSIM explainers)~8 hrs/week~3,800$0Referral program (15% credit for both sides)~2 hrs setup~2,600$2.10Paid ads (Google, Meta)$4,200 spent~412$10.19Paid ads were a waste for us. Our product isn't impulse-buy friendly — it requires education. Organic content and word-of-mouth outperformed by 20x.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real growth multiplier:&lt;/strong&gt; We started writing &lt;a href="https://iwantesim.com/sitemap" rel="noopener noreferrer"&gt;destination-specific guides&lt;/a&gt; — "Best eSIM for Japan," "How to Stay Connected in Bali," "Data Plans for European Train Travel." These rank for long-tail keywords, answer specific questions, and convert at 3x our homepage rate.&lt;/p&gt;

&lt;p&gt;Our &lt;a href="https://iwantesim.com/blog" rel="noopener noreferrer"&gt;blog&lt;/a&gt; now drives 40% of organic traffic. Not because we're genius marketers, but because we write what we wish existed when we were travelers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Biggest Mistakes and What They Cost Us
&lt;/h2&gt;

&lt;p&gt;I've made plenty. Here are the expensive ones:&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 1: Ignoring Support Response Time
&lt;/h3&gt;

&lt;p&gt;For our first 1,000 customers, average response time was 18 hours. Not because we were lazy — because support was "async" in my head. In customers' heads, it was "they don't care about me."&lt;/p&gt;

&lt;p&gt;We added Intercom, built a help center with 40 articles, and set a 2-hour response SLA. CSAT went from 72% to 94%. Churn dropped 40%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 2: Pricing Too Low
&lt;/h3&gt;

&lt;p&gt;We underpriced by 30% for six months, thinking "cheaper = more customers." It attracted price-shoppers who churned after one trip. We raised prices, added a "premium" tier with priority support, and revenue per customer increased 60% with zero growth loss.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake 3: Not Localizing Early
&lt;/h3&gt;

&lt;p&gt;60% of our traffic comes from non-English speakers. We launched with English-only and lost conversions in Germany, Japan, and Brazil for a year. Adding German and Japanese increased conversion rates by 22% and 18% respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with a real pain point you personally experience&lt;/strong&gt; — not a market opportunity, a problem that annoys you&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your first 100 customers teach you more than any analytics dashboard&lt;/strong&gt; — talk to them, email them, learn from them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building in public is free marketing&lt;/strong&gt; — share the journey, not just the wins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Organic content outperforms paid ads&lt;/strong&gt; for products that require education&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical reliability matters more than features&lt;/strong&gt; — when someone's boarding a flight, they need that QR code to work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raise prices before you think you should&lt;/strong&gt; — undervaluing your product attracts the wrong customers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Localize early&lt;/strong&gt; — the internet is global, and English-only is leaving money on the table&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is an eSIM and how does it work?
&lt;/h3&gt;

&lt;p&gt;An eSIM is a digital SIM embedded in your phone. Instead of inserting a physical card, you download a carrier profile via QR code. It activates instantly and lets you use local data plans while traveling without removing your home SIM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is iWanteSIM only for frequent travelers?
&lt;/h3&gt;

&lt;p&gt;No. While frequent travelers save the most, anyone who travels internationally even once a year benefits. Business travelers, digital nomads, and vacationers all use iWanteSIM to avoid roaming charges.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does iWanteSIM differ from buying a local SIM card?
&lt;/h3&gt;

&lt;p&gt;Local SIMs require finding a store, showing ID, and physically swapping cards. iWanteSIM activates before you land, works in 150+ countries, and lets you keep your home number active on dual-SIM phones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use iWanteSIM with any phone?
&lt;/h3&gt;

&lt;p&gt;iWanteSIM works with most phones manufactured after 2020, including iPhone XS and newer, Samsung Galaxy S20+, Google Pixel 3+, and newer Android devices. Check your phone's settings for "Cellular" &amp;gt; "Add eSIM" to verify compatibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if I run out of data mid-trip?
&lt;/h3&gt;

&lt;p&gt;You can top up directly through the &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM dashboard&lt;/a&gt; without reinstalling anything. Most plans allow instant top-ups, and you'll receive an updated QR code if needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is eSIM safe to use for banking and sensitive apps?
&lt;/h3&gt;

&lt;p&gt;Yes. eSIM uses the same encryption standards as physical SIMs. iWanteSIM partners with Tier-1 carriers that provide secure, encrypted connections. We never store or access your personal data.&lt;/p&gt;

&lt;h3&gt;
  
  
  How did iWanteSIM grow without paid advertising?
&lt;/h3&gt;

&lt;p&gt;We focused on building in public, creating useful travel content, and delivering exceptional support that generated word-of-mouth referrals. Our referral program incentivizes sharing without requiring a marketing budget.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next for iWanteSIM?
&lt;/h3&gt;

&lt;p&gt;We're expanding our coverage to include more local carriers in Africa and South America, adding group plans for travel companies, and building API access for travel apps that want to offer eSIM as a feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Build What You Wish Existed
&lt;/h2&gt;

&lt;p&gt;Twelve thousand customers later, the lesson is still the same one I learned over that $12 coffee in Lisbon: build something that solves a problem you actually have. The rest — marketing, growth, scaling — flows from that foundation.&lt;/p&gt;

&lt;p&gt;iWanteSIM isn't a unicorn. It's not even a venture-backed startup. It's a side project that grew because the problem was real, the solution was honest, and the people building it gave a damn about every customer.&lt;/p&gt;

&lt;p&gt;If you're thinking about starting something, my advice is simple: don't wait for the perfect idea. Wait for the problem that makes you angry. Then build the smallest thing that fixes it.&lt;/p&gt;

&lt;p&gt;Everything else is just iteration.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to try iWanteSIM for your next trip? &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;Browse plans for 150+ countries&lt;/a&gt; and stay connected without the roaming shock.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>indiehackers</category>
      <category>buildinpublic</category>
      <category>travel</category>
      <category>esim</category>
    </item>
    <item>
      <title>Integrating Multiple Carrier APIs: A Survival Guide</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 25 Aug 2026 00:06:59 +0000</pubDate>
      <link>https://dev.to/time_luxe/integrating-multiple-carrier-apis-a-survival-guide-574k</link>
      <guid>https://dev.to/time_luxe/integrating-multiple-carrier-apis-a-survival-guide-574k</guid>
      <description>&lt;h1&gt;
  
  
  Integrating Multiple Carrier APIs: A Survival Guide for Telecom-Adjacent Startups
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Quick Answer:&lt;/strong&gt; Telecom startups integrating multiple carrier APIs should normalize responses into a unified schema, implement circuit breakers for latency spikes, build tiered fallback chains (primary to secondary to cached), and monitor API health in real-time. These four practices prevent outages, reduce integration complexity by 60-70%, and keep your eSIM or MVNO platform reliable as you scale from two carriers to twenty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you're building an eSIM platform, travel connectivity app, or MVNO service, you've probably stared at the abyss. On one side: your clean, product-focused API that customers love. On the other: a dozen carrier APIs that return data in wildly different formats, go down at 3 AM, and rate-limit you into submission.&lt;/p&gt;

&lt;p&gt;We've been there. At iWanteSIM, we went from integrating two carriers to managing relationships with fourteen different operators across six continents. Each one had its own quirks, its own auth scheme, its own idea of what an error response should look like. Some returned XML. One sent SMS confirmations for every API call. Another required us to fax a certificate. Yes, in 2025.&lt;/p&gt;

&lt;p&gt;This isn't a theoretical architecture post. It's a survival guide written from the trenches. We'll cover the three hardest problems we faced—API normalization, latency management, and fallback strategies—and the patterns that actually worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Carrier API Integration Breaks Most Startups
&lt;/h2&gt;

&lt;p&gt;Most SaaS integrations are straightforward. You call Stripe for payments, Twilio for SMS, SendGrid for email. These APIs are well-documented, versioned predictably, and behave consistently across regions.&lt;/p&gt;

&lt;p&gt;Carrier APIs are none of those things.&lt;/p&gt;

&lt;p&gt;The telecommunications industry runs on standards that predate the internet. SS7, SIGTRAN, Diameter—these protocols power the networks we use daily, but they don't translate cleanly to REST or GraphQL. When carriers expose APIs for partners, they're often thin wrappers around legacy BSS/OSS systems built in the 1990s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common pain points we encountered:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inconsistent data models:&lt;/strong&gt; One carrier returns IMSI as a string, another as a number, a third nests it three levels deep&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Undocumented rate limits:&lt;/strong&gt; We hit a carrier that silently dropped requests after 10 TPS—with no Retry-After header&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unpredictable downtime:&lt;/strong&gt; Maintenance windows that aren't announced, or worse, announced 15 minutes after they start&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication soup:&lt;/strong&gt; OAuth 2.0, mutual TLS, API keys in headers, API keys in query params, HMAC signatures, and one that required a custom SOAP header&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regional variations:&lt;/strong&gt; The same carrier's European API returned JSON; their Asian API returned XML with different field names
Without a deliberate strategy, these inconsistencies compound until your engineering team spends 80% of their time on integration plumbing instead of product features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pattern 1: API Normalization Layer
&lt;/h2&gt;

&lt;p&gt;The first and most important pattern we implemented was a normalization layer—a dedicated service that sits between your application and all carrier APIs.&lt;/p&gt;

&lt;p&gt;Here's what it does in practice:&lt;/p&gt;

&lt;h3&gt;
  
  
  Unified Request Schema
&lt;/h3&gt;

&lt;p&gt;Your application sends standard requests like &lt;code&gt;POST /activate-esim&lt;/code&gt; with a clean JSON body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cust_abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plan_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"global_5gb_30d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"APAC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"device_imei"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"351234567890123"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The normalization layer translates this into whatever format Carrier A, B, or C expects. Maybe Carrier A wants a SOAP envelope. Carrier B wants a GraphQL mutation. Carrier C expects a multipart form with a PDF attachment. Your app doesn't care.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unified Response Schema
&lt;/h3&gt;

&lt;p&gt;Responses get normalized back to a standard format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"activated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"carrier_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"carrier_789"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iccid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8901234567890123456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"activated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-25T14:32:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-09-24T14:32:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every carrier response gets mapped to this schema, regardless of whether the original was XML, JSON, or a CSV emailed to you 20 minutes later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters for Scale
&lt;/h3&gt;

&lt;p&gt;When we added our seventh carrier, the integration took two days instead of two weeks. The normalization layer handled 90% of the translation. We only needed to write a new adapter that mapped the carrier's quirks to our standard schema.&lt;/p&gt;

&lt;p&gt;Key insight: &lt;strong&gt;Your application should never know it's talking to multiple carriers.&lt;/strong&gt; It should talk to one consistent API that happens to route to different backends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 2: Latency Management and Circuit Breakers
&lt;/h2&gt;

&lt;p&gt;Carrier APIs are slow. Not "add 50ms" slow. We're talking 2-8 seconds for basic operations, with occasional 30-second outliers that will destroy your response times if you let them.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is a Circuit Breaker?
&lt;/h3&gt;

&lt;p&gt;A circuit breaker monitors API calls and "opens" when failure rates or latency exceed thresholds. Once open, requests fail fast instead of waiting on a broken dependency. After a cooldown period, it "half-opens" to test if the service recovered.&lt;/p&gt;

&lt;p&gt;We use the &lt;code&gt;opossum&lt;/code&gt; npm package (1.2M weekly downloads) for Node.js implementations. It takes about 20 lines of code to wrap a carrier client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;opossum&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// 5s max wait&lt;/span&gt;
  &lt;span class="na"&gt;errorThresholdPercentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;resetTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;   &lt;span class="c1"&gt;// 30s before retry&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;carrierApiCall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;breaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Latency Distribution Across Carriers
&lt;/h3&gt;

&lt;p&gt;Here's what we measured across our carrier pool (p95 response times for an eSIM activation):&lt;/p&gt;

&lt;p&gt;Carrier Regionp95 LatencyNotesNorth America1.2sConsistent, well-documentedWestern Europe2.8sOccasional 10s spikes during peakAPAC Tier 14.5sHigh variance, 1-15s rangeAPAC Tier 28.2sUnpredictable, needs aggressive timeoutsLatin America6.1sFrequent maintenance windowsWithout circuit breakers, a single slow carrier would cascade latency into your entire user experience. With them, you fail fast and route around the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Async Processing for Non-Critical Paths
&lt;/h3&gt;

&lt;p&gt;Not every carrier operation needs to be synchronous. We moved quota checks, usage reporting, and billing reconciliation to background queues using BullMQ. This cut our synchronous API latency by 40% and made the platform feel snappier even when carriers were sluggish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 3: Tiered Fallback Strategies
&lt;/h2&gt;

&lt;p&gt;When a carrier fails—and it will—you need a plan B. And usually a plan C.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Three-Tier Fallback Model
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Tier 1: Primary Carrier&lt;/strong&gt;&lt;br&gt;
The customer's preferred or cheapest option. This handles 80% of traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 2: Secondary Carrier&lt;/strong&gt;&lt;br&gt;
A different network in the same region, activated automatically when Tier 1 fails. We maintain active contracts with 2-3 carriers per major region.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 3: Cached/Cached-Only Mode&lt;/strong&gt;&lt;br&gt;
We cache activation profiles and basic metadata in Redis. If all live carriers are down, we can still display plan details, pricing, and even pre-provisioned eSIMs that were prepared during low-traffic hours.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fallback in Practice
&lt;/h3&gt;

&lt;p&gt;Here's a simplified version of our activation flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;activateESIM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;tryCarrier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;carriers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secondary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;tryCarrier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;carriers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPreprovisionedProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user gets their eSIM. They don't know there was a problem. Your support ticket volume stays low.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-Provisioned eSIMs
&lt;/h3&gt;

&lt;p&gt;Our most effective reliability hack: we pre-provision eSIMs during off-peak hours and store them in a pool. When a user requests activation, we assign a pre-warmed profile instead of calling a live carrier API. This turns a 5-second unpredictable API call into a 50ms database lookup.&lt;/p&gt;

&lt;p&gt;We keep about 500 pre-provisioned profiles per region, replenishing the pool every hour. The cost is minimal compared to the reliability gain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring: You Can't Fix What You Can't See
&lt;/h2&gt;

&lt;p&gt;All these patterns depend on visibility. We built a carrier health dashboard that tracks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API success rate&lt;/strong&gt; by carrier and endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;p50/p95/p99 latency&lt;/strong&gt; trends over time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circuit breaker state&lt;/strong&gt; (closed/open/half-open)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fallback frequency&lt;/strong&gt;—how often we hit Tier 2 or Tier 3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error classification&lt;/strong&gt;—auth failures, timeouts, 5xx, rate limits
We alert via PagerDuty when any carrier drops below 95% success rate for 5 minutes. More importantly, we review weekly trend reports to spot degradation before it becomes an outage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One discovery from our monitoring: a carrier we thought was reliable had a 2% error rate that spiked to 15% every Tuesday at 02:00 UTC. Their database backup window. We shifted traffic away during that window and our activation success rate jumped from 97% to 99.7%.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Got Wrong (So You Don't Have To)
&lt;/h2&gt;

&lt;p&gt;We've made plenty of mistakes. Here are the expensive ones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Tight coupling to carrier-specific fields&lt;/strong&gt;&lt;br&gt;
Early on, we exposed raw carrier IDs and status codes directly to our frontend. When a carrier changed their status mapping, our UI displayed "active" as "suspended" for 6 hours. Embarrassing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Not versioning our normalization layer&lt;/strong&gt;&lt;br&gt;
We updated our unified schema without versioning, breaking three downstream integrations. Now we version our internal API like a public product: &lt;code&gt;/v1/activate&lt;/code&gt;, &lt;code&gt;/v2/activate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Ignoring idempotency&lt;/strong&gt;&lt;br&gt;
Carrier APIs aren't always idempotent. We double-charged customers when our retry logic fired on a timeout that actually succeeded. Now every activation request includes an idempotency key, and we track state transitions explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Assuming all OAuth 2.0 implementations are equal&lt;/strong&gt;&lt;br&gt;
One carrier returned the access token in a custom header. Another used a non-standard grant type. Always read the actual implementation, not the spec.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normalize everything:&lt;/strong&gt; Build a translation layer so your application talks to one consistent API, not fifteen different ones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail fast with circuit breakers:&lt;/strong&gt; Set aggressive timeouts (3-5s for most carrier operations) and open circuits when latency or error rates spike&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always have a fallback:&lt;/strong&gt; Maintain secondary carrier relationships and pre-provisioned profiles for when primaries fail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor obsessively:&lt;/strong&gt; Track latency percentiles, error classification, and fallback frequency by carrier and region&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version your internal APIs:&lt;/strong&gt; Your normalization layer is a product—treat it like one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache aggressively:&lt;/strong&gt; Pre-provisioned profiles and metadata caching turn unpredictable API calls into fast database lookups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan for inconsistency:&lt;/strong&gt; Carrier APIs will violate every assumption you have about REST conventions, authentication, and error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How many carriers should a startup integrate initially?
&lt;/h3&gt;

&lt;p&gt;Start with two carriers in your primary market. This gives you pricing leverage and a basic fallback option. Add a third when you expand regions, not before you've solidified your normalization layer and monitoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the average cost of maintaining a carrier integration?
&lt;/h3&gt;

&lt;p&gt;Expect 20-40 hours of engineering time per carrier for initial integration, plus 5-10 hours monthly for maintenance, credential rotation, and API changes. A normalization layer cuts ongoing maintenance by 60-70%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should we use a carrier aggregator instead of direct integrations?
&lt;/h3&gt;

&lt;p&gt;Aggregators like &lt;a href="https://www.airalo.com" rel="noopener noreferrer"&gt;Airalo's B2B platform&lt;/a&gt; or &lt;a href="https://www.truphone.com" rel="noopener noreferrer"&gt;Truphone&lt;/a&gt; reduce integration overhead but add cost (typically 15-30% margin) and limit flexibility. We recommend direct integrations for core markets and aggregators for long-tail regions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you handle carrier API versioning?
&lt;/h3&gt;

&lt;p&gt;We don't rely on carriers to version gracefully. Our normalization layer abstracts version changes, and we run parallel adapters during migration periods. We also subscribe to carrier developer newsletters and maintain direct Slack channels with their technical contacts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What timeout values work best for carrier APIs?
&lt;/h3&gt;

&lt;p&gt;We use 5 seconds for activations, 3 seconds for status checks, and 10 seconds for bulk operations. These are aggressive but force us to build fallback logic instead of accepting poor performance. Adjust based on your carrier's actual p95 latency.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you maintain carrier relationships?
&lt;/h3&gt;

&lt;p&gt;Beyond contracts, designate a technical point of contact on both sides. Join their developer Slack or Discord if available. Send monthly usage reports proactively. Good relationships mean faster support when things break—and they will break.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the biggest mistake startups make with carrier APIs?
&lt;/h3&gt;

&lt;p&gt;Treating carrier integrations like standard SaaS APIs. They're not. Expect inconsistency, poor documentation, and breaking changes. Build defensively: normalize responses, implement circuit breakers, and never assume a carrier API will behave the same way twice.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do pre-provisioned eSIMs work legally?
&lt;/h3&gt;

&lt;p&gt;Pre-provisioning means requesting eSIM profiles from carriers during off-peak hours and storing them in a pool. You still pay for each profile, but activation is instant for the user. Check your carrier agreement—some prohibit storing profiles beyond 24 hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  What monitoring tools do you recommend?
&lt;/h3&gt;

&lt;p&gt;We use DataDog for APM and custom dashboards, PagerDuty for alerting, and a custom carrier health score we calculate every minute. Open-source alternatives include Prometheus + Grafana for metrics and Alertmanager for paging.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should we build our own normalization layer vs. using an open-source solution?
&lt;/h3&gt;

&lt;p&gt;Build custom if carrier APIs are your core differentiator or if you need deep control over fallback logic. For MVPs, explore open-source telecom abstraction libraries, but be prepared to outgrow them—none we evaluated handled the full complexity of real carrier integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Integrating multiple carrier APIs isn't glamorous work, but it's the foundation that everything else in your telecom product sits on. Get it wrong, and you'll spend your days firefighting outages and apologizing to customers. Get it right, and your platform becomes invisible—in the best possible way.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, we've learned that reliability isn't a feature you ship once. It's a practice you maintain daily through normalization, circuit breakers, tiered fallbacks, and obsessive monitoring.&lt;/p&gt;

&lt;p&gt;If you're building in this space, start with the patterns that matter: one clean API abstraction, aggressive timeouts, and always—always—have a plan B.&lt;/p&gt;

&lt;p&gt;We're sharing what we learn as we build. Follow along on our &lt;a href="https://iwantesim.com/blog" rel="noopener noreferrer"&gt;blog&lt;/a&gt; or &lt;a href="https://iwantesim.com/sitemap.xml" rel="noopener noreferrer"&gt;explore our technical guides&lt;/a&gt; for more on eSIM architecture, carrier negotiations, and scaling connectivity platforms.&lt;/p&gt;

</description>
      <category>telecom</category>
      <category>apiintegration</category>
      <category>esim</category>
      <category>startup</category>
    </item>
    <item>
      <title>Why I Built an eSIM Comparison Tool Instead of Just Selling Plans</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Fri, 21 Aug 2026 00:10:02 +0000</pubDate>
      <link>https://dev.to/time_luxe/why-i-built-an-esim-comparison-tool-instead-of-just-selling-plans-144l</link>
      <guid>https://dev.to/time_luxe/why-i-built-an-esim-comparison-tool-instead-of-just-selling-plans-144l</guid>
      <description>&lt;h2&gt;
  
  
  The Tempting Path: Just Be a Storefront
&lt;/h2&gt;

&lt;p&gt;When I started building &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, the obvious move was to slap together a product page, list some eSIM plans, and call it a day. That's what most resellers do. You sign up for a whitelist or API partnership with a carrier aggregator, get a catalog of plans, and you're basically a middleman with a checkout button.&lt;/p&gt;

&lt;p&gt;And honestly? That model works. Plenty of eSIM resellers make decent revenue doing exactly that. But the more I looked at the landscape, the more I noticed something missing: &lt;strong&gt;trust&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The eSIM market in 2026 is confusing. There are hundreds of plans across dozens of carriers, each with different coverage zones, data caps, validity periods, and pricing models. A traveler heading to Japan could spend an hour comparing options across five different reseller sites — each one only showing the plans they profit from most.&lt;/p&gt;

&lt;p&gt;I didn't want to build another site like that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZ3NvOHJ4d2ZxY2hwYzNjYzV5NXR4eGI4NjN4Z2R0aGQ3ZGY4ZjZiZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/3o7TKMt1VVNBk5yEB6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZ3NvOHJ4d2ZxY2hwYzNjYzV5NXR4eGI4NjN4Z2R0aGQ3ZGY4ZjZiZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/3o7TKMt1VVNBk5yEB6/giphy.gif" alt="Person thinking with gears turning" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Question: What Does a Traveler Actually Need?
&lt;/h2&gt;

&lt;p&gt;I talked to friends, read Reddit threads, and lurked in travel forums. The pattern was clear: travelers don't want to be sold to. They want to &lt;em&gt;understand&lt;/em&gt; their options and make an informed choice. The pain points were remarkably consistent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hidden caveats:&lt;/strong&gt; Plans advertised as "unlimited" with throttling after 2GB. Plans that claim "covers Europe" but exclude half the countries you're visiting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison fatigue:&lt;/strong&gt; Opening six browser tabs to compare data allowances, validity windows, and per-GB pricing across providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-purchase regret:&lt;/strong&gt; Buying a plan, landing at your destination, and discovering a cheaper or better option existed that the reseller never showed you.
Every single pain point came down to one thing: &lt;strong&gt;information asymmetry&lt;/strong&gt;. The seller knows the full catalog. The buyer sees only what the seller chooses to display. That's not a bug in the eSIM industry — it's the business model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I decided to break it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Comparison Tool: What It Actually Does
&lt;/h2&gt;

&lt;p&gt;Instead of a storefront that shows you a curated subset of plans, I built a comparison engine that shows you &lt;em&gt;everything&lt;/em&gt;. Here's what that means in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full catalog transparency.&lt;/strong&gt; Every plan available through the platform is listed — including the ones with thin margins for us. If a competitor's plan is cheaper for your specific route, it shows up in the results. You can browse the complete plan catalog at &lt;a href="https://iwantesim.com/sitemap" rel="noopener noreferrer"&gt;the iWanteSIM sitemap&lt;/a&gt;, which indexes every plan by region and country.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apples-to-apples comparison.&lt;/strong&gt; The tool normalizes pricing to per-GB cost, shows real coverage maps (not marketing copy), and flags throttling thresholds and fair-use policies in plain language. No asterisks. No "see terms and conditions" links buried in fine print.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Route-based recommendations.&lt;/strong&gt; You enter your destinations and travel dates, and the engine ranks plans by actual fit — not by commission rate. A 3-day trip to Singapore gets different recommendations than a 30-day backpacking trip across Southeast Asia, even if some plans technically "cover" both.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqscro8v2h01witumsp1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqscro8v2h01witumsp1.gif" alt="Person working on laptop with code" width="400" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Side: What I Built With
&lt;/h2&gt;

&lt;p&gt;I won't pretend this was some grand architectural achievement. The stack is intentionally boring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js with server-side rendering for SEO. The comparison table is a React component that handles sorting and filtering client-side after initial server render.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data layer:&lt;/strong&gt; A scheduled sync job pulls plan catalogs from carrier aggregator APIs every 6 hours and stores them in a normalized schema. This was the hardest part — every provider has a different data format, different coverage definitions, and different naming conventions for the same countries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search:&lt;/strong&gt; Country and region matching uses a simple but effective geo-graph that maps ISO country codes to travel regions. "Western Europe" means the same thing whether a carrier calls it "EU Zone 1" or "Schengen Bundle."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing normalization:&lt;/strong&gt; Every plan gets a computed &lt;code&gt;per_gb_cost&lt;/code&gt; and &lt;code&gt;per_day_cost&lt;/code&gt; field. Plans with throttled "unlimited" data use the throttle threshold as the effective data cap for comparison purposes.
The code isn't open source (yet), but the &lt;a href="https://iwantesim.com/sitemap" rel="noopener noreferrer"&gt;full plan index&lt;/a&gt; is crawlable and each plan has a structured data page with consistent fields. If someone wanted to build their own comparison layer on top of it, they could.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Transparency Is a Feature, Not a Sacrifice
&lt;/h2&gt;

&lt;p&gt;Here's the part that surprised me: &lt;strong&gt;showing competitor plans didn't kill our revenue. It grew it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the first three months after launching the comparison tool, conversion rates went up, not down. Users spent more time on the site. Return visits doubled. Refund requests dropped to near zero.&lt;/p&gt;

&lt;p&gt;The psychology is straightforward. When you show someone every option — including ones that don't favor you — two things happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;They trust you.&lt;/strong&gt; If you're willing to show a cheaper alternative, you're probably not hiding something about the plan you're recommending.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They buy faster.&lt;/strong&gt; The comparison paralysis disappears when the tool does the heavy lifting. Users don't need to open six tabs. The decision is made on your site, and the checkout is right there.
This is what I mean by "transparency as a feature." It's not a moral stance — it's a product strategy. In a market defined by information asymmetry, the platform that eliminates it becomes the default starting point for every traveler.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMzN4ZjQ2dnRqdjh2NzVrNnNkZGI1NzNlNjNkNjRlNWNlZjJlMjRiZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26ufnwzNvE4y5Y0GQ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMzN4ZjQ2dnRqdjh2NzVrNnNkZGI1NzNlNjNkNjRlNWNlZjJlMjRiZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/26ufnwzNvE4y5Y0GQ/giphy.gif" alt="Success kid meme" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;A few honest lessons from the build:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Country-matching is harder than it looks.&lt;/strong&gt; Carriers have wildly inconsistent coverage definitions. One provider's "Asia" package covers 12 countries. Another's covers 6 — but includes China, which the first one excludes. The geo-graph I built handles maybe 90% of cases well. The last 10% still requires manual review, and I get occasional emails from users in edge-case countries. It's not perfect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching vs. freshness is a real tension.&lt;/strong&gt; Syncing every 6 hours means pricing can be stale during carrier flash sales. Syncing every hour would hammer the aggregator APIs and blow through rate limits. I settled on 6-hour syncs with a manual refresh button, but I'm exploring webhook-based updates for real-time pricing on high-traffic routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comparison tables are a UX nightmare on mobile.&lt;/strong&gt; A 7-column comparison table doesn't fit on a phone screen. I spent more time on the mobile experience — collapsible columns, card-based layouts, swipe interactions — than on the actual data pipeline. If I were starting over, I'd design mobile-first from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The comparison tool is live and working, but it's version 1. The roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User reviews and real-world speed tests:&lt;/strong&gt; Aggregating actual user-reported speeds per plan per country, not just the "up to" marketing claims.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-trip planning:&lt;/strong&gt; If you travel to Japan in March and Europe in June, the tool should recommend a single global plan if it's cheaper than two regional ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API access:&lt;/strong&gt; Letting other travel platforms embed the comparison engine. If transparency is the product, it should be shareable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;If you're building a product in a market that runs on information asymmetry, consider whether your default move should be to &lt;em&gt;eliminate&lt;/em&gt; it rather than exploit it. The storefront model is easy. The comparison model is harder — you're building a data pipeline, a normalization layer, and a UX that handles complexity gracefully. But the payoff is a product people actually trust.&lt;/p&gt;

&lt;p&gt;Travelers don't need another reseller. They need someone who'll show them the whole menu, not just the high-margin items. That's the bet I made with &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, and so far, it's paying off.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why not just list the plans you make the most money on?&lt;/strong&gt;&lt;br&gt;
Because that's the exact problem travelers are trying to escape. Showing the full catalog — including cheaper alternatives — builds trust, and trust drives conversions. Short-term margin optimization kills long-term retention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does the comparison tool handle plans from different aggregators?&lt;/strong&gt;&lt;br&gt;
All plan data is normalized into a shared schema during the sync process. Country coverage is mapped through a geo-graph that translates carrier-specific zone names into standard ISO country codes. Pricing is normalized to per-GB and per-day cost for apples-to-apples comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the comparison data real-time?&lt;/strong&gt;&lt;br&gt;
Not yet. Plan catalogs sync every 6 hours from carrier aggregator APIs. There's a manual refresh option, and I'm working on webhook-based updates for real-time pricing on popular routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use the comparison tool without buying a plan?&lt;/strong&gt;&lt;br&gt;
Yes. The comparison and search features are completely free to use with no account required. You only hit the checkout flow if you choose to purchase a plan.&lt;/p&gt;

</description>
      <category>esim</category>
      <category>buildinginpublic</category>
      <category>productstrategy</category>
      <category>transparency</category>
    </item>
    <item>
      <title>The Economics of Running an eSIM Marketplace: Pricing, Margins, and Carrier Rates</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 18 Aug 2026 00:04:34 +0000</pubDate>
      <link>https://dev.to/time_luxe/the-economics-of-running-an-esim-marketplace-pricing-margins-and-carrier-rates-30ao</link>
      <guid>https://dev.to/time_luxe/the-economics-of-running-an-esim-marketplace-pricing-margins-and-carrier-rates-30ao</guid>
      <description>&lt;h2&gt;
  
  
  Why I'm Writing This
&lt;/h2&gt;

&lt;p&gt;When I started building &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, I thought the eSIM business was simple: buy data from carriers at wholesale, sell it to travelers at retail, pocket the difference. And technically, that's true. But the economics underneath are more interesting — and more fragile — than I expected.&lt;/p&gt;

&lt;p&gt;This post is a building-in-public-style deep dive into the numbers behind an eSIM marketplace. No gatekeeping. If you're considering building one (or just curious why your $1 data plan exists), here's what I've learned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo81glot1foe51thf6wkq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo81glot1foe51thf6wkq.gif" alt="money counting gif" width="256" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Supply Side: Wholesale Carrier Rates Explained
&lt;/h2&gt;

&lt;p&gt;eSIM marketplaces don't negotiate directly with every telecom operator on the planet. Most work through intermediary platforms — companies that have already aggregated dozens or hundreds of carrier relationships into a single API. Think of them as wholesalers who buy in bulk from carriers and resell in smaller chunks to marketplace operators.&lt;/p&gt;

&lt;p&gt;The wholesale rates I've seen in practice vary wildly by region:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Europe:&lt;/strong&gt; $0.05–$0.20 per GB (competitive, lots of carriers, EU roaming regulation helps)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asia:&lt;/strong&gt; $0.10–$0.40 per GB (varies by country — Singapore is cheap, Japan is expensive)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;North America:&lt;/strong&gt; $0.20–$0.60 per GB (fewer carriers, higher infrastructure costs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Africa:&lt;/strong&gt; $0.30–$1.50 per GB (limited carrier options, expensive backhaul)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;South America:&lt;/strong&gt; $0.25–$0.80 per GB (mixed coverage, carrier concentration)
These rates are what the marketplace pays. The customer pays more. The difference is your gross margin.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here's the catch: wholesale rates aren't static. They depend on volume commitments, the specific data package (a 1 GB pass vs. a 20 GB monthly plan), the duration, and sometimes even the time of year. Carriers in tourist-heavy regions sometimes raise rates during peak season.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pricing Problem: Why $1 Plans Exist
&lt;/h2&gt;

&lt;p&gt;You've seen them — $1 data plans, sometimes even less. Are they loss leaders? Marketing gimmicks? Actually, they can be genuinely profitable. Here's how.&lt;/p&gt;

&lt;p&gt;A typical $1 eSIM plan might offer 500 MB or 1 GB of data valid for 7 days. If your wholesale cost for that data in, say, Vietnam is $0.08 per GB, then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Revenue:&lt;/strong&gt; $1.00&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wholesale cost:&lt;/strong&gt; $0.08&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment processing (3% + $0.30):&lt;/strong&gt; $0.33&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Net margin:&lt;/strong&gt; $0.59
That's a 59% gross margin on a $1 product. Not bad, right?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason $1 plans work is that &lt;strong&gt;payment processing fees are flat, not percentage-based at the low end.&lt;/strong&gt; Actually, that's the problem — the $0.30 fixed fee eats a huge chunk of a $1 transaction. But at $5 or $10, the percentage dominates and margins improve.&lt;/p&gt;

&lt;p&gt;The real strategy behind $1 plans is customer acquisition. A traveler buys a $1 plan for a short trip, has a good experience, and comes back to buy a $20 plan for their next two-week vacation. The lifetime value of an eSIM customer is where the real money is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0HlNQ03J5JxX6KHG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0HlNQ03J5JxX6KHG/giphy.gif" alt="thinking money gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Margin Structure: Where the Money Actually Goes
&lt;/h2&gt;

&lt;p&gt;Let's break down a realistic $15 global data plan (10 GB, 30 days):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selling price:&lt;/strong&gt; $15.00&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wholesale data cost:&lt;/strong&gt; $1.50 (blended rate across regions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment processing:&lt;/strong&gt; $0.75 (3% + $0.30)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform infrastructure:&lt;/strong&gt; $0.20 (API calls, eSIM provisioning, server costs amortized)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer support:&lt;/strong&gt; $0.30 (amortized support tickets, chat tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing/acquisition:&lt;/strong&gt; $1.50 (paid ads, affiliate payouts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Net profit:&lt;/strong&gt; $10.75
That's a net margin of roughly 72%. Sounds incredible — and it is, compared to most e-commerce businesses. But this assumes the customer only needs support once and that your infrastructure scales efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where margins get squeezed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Refunds and chargebacks:&lt;/strong&gt; When an eSIM fails to activate (carrier issue, incompatible device, user error), you refund. Payment processors don't refund their fees. A 5% refund rate on a $15 product costs $0.75 per sale in lost revenue plus processing fees you eat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support overhead:&lt;/strong&gt; eSIM activation issues are the #1 support ticket category. If your average customer needs 15 minutes of support time and you're paying $15/hour for support, that's $3.75 per ticket. At a 20% support rate, that's $0.75 per sale — significant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier rate changes:&lt;/strong&gt; Wholesale rates can change with 30 days' notice. If you've sold annual plans at a price based on today's rates, a rate hike cuts your margin retroactively.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Marketplace Model: Platform vs. Reseller
&lt;/h2&gt;

&lt;p&gt;There are fundamentally two ways to run an eSIM business:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Reseller Model:&lt;/strong&gt; You buy from one or two aggregator platforms, white-label their eSIMs, and resell. Low effort, lower margins (you're one step removed from the carriers). You're essentially a marketing company with an API integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Marketplace Model:&lt;/strong&gt; You aggregate multiple sources — direct carrier relationships, aggregator platforms, regional specialists — and present them side by side. Customers compare and choose. You take a commission or markup on each sale.&lt;/p&gt;

&lt;p&gt;The marketplace model is harder to build but has better unit economics long-term. More carrier diversity means better redundancy (if one carrier has an outage, you route elsewhere), better negotiation leverage (volume across multiple carriers), and more compelling product (customers see options).&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, we went the marketplace route. The technical complexity is higher — you need to normalize data formats from different sources, handle different activation flows, and manage relationships with multiple upstream providers. But the margin improvement is real.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/26u4lOMQg1brCGU8o/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/26u4lOMQg1brCGU8o/giphy.gif" alt="charts and graphs gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Sitemap Links: How Carrier Coverage Maps to Revenue
&lt;/h2&gt;

&lt;p&gt;One thing that surprised me: the long tail of country-specific searches is where organic traffic converts best. People searching for &lt;a href="https://iwantesim.com/sitemap/esim-japan" rel="noopener noreferrer"&gt;eSIM for Japan&lt;/a&gt; or &lt;a href="https://iwantesim.com/sitemap/esim-turkey" rel="noopener noreferrer"&gt;eSIM for Turkey&lt;/a&gt; have high purchase intent. They know what they want.&lt;/p&gt;

&lt;p&gt;This is why having a comprehensive sitemap with country-specific landing pages matters. Each page targets a specific carrier's coverage, pricing, and activation instructions for that country. It's SEO work, but it directly drives revenue.&lt;/p&gt;

&lt;p&gt;The conversion rate on country-specific pages is typically 3-5x higher than generic homepage traffic. When someone searches "eSIM Japan" and lands on a page showing the exact plans, prices, and coverage for Japan, they're ready to buy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Carrier Rate Negotiation: What Actually Works
&lt;/h2&gt;

&lt;p&gt;If you're dealing with aggregators (and most early-stage marketplaces are), negotiation leverage comes down to volume. Here's what I've found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Under 1,000 sales/month:&lt;/strong&gt; You take listed rates. No negotiation. You're too small to matter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1,000–10,000 sales/month:&lt;/strong&gt; You can negotiate 5–15% off listed rates. Ask for volume discounts, but expect to commit to monthly minimums.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10,000+ sales/month:&lt;/strong&gt; You can negotiate custom rate cards, priority support, and sometimes exclusive regional pricing. This is where direct carrier relationships start making sense.
The key insight: don't optimize for the cheapest possible wholesale rate on day one. Optimize for reliability. A carrier that's $0.02/GB more expensive but has 99.5% activation success vs. 95% success rate is worth it. Failed activations cost you in refunds, support, and customer churn.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hidden Costs Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;A few line items that surprised me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;eSIM profile generation fees:&lt;/strong&gt; Some platforms charge per-profile provisioning fees ($0.05–$0.20 per eSIM). Small but adds up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Currency conversion:&lt;/strong&gt; If you're paying carriers in EUR and collecting revenue in USD, FX fees (2-3%) eat margin silently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expired inventory:&lt;/strong&gt; Data packages with expiry dates. If you pre-purchase inventory and it expires before sale, that's pure loss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance and regulatory:&lt;/strong&gt; Different countries have different KYC requirements for SIM activation. Some require passport scans. The infrastructure to handle this securely isn't free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Running an eSIM marketplace is a volume game with surprisingly healthy margins at scale. The unit economics work because data is cheap at wholesale, the product is digital (no shipping), and customers have high purchase intent (they need data when they travel).&lt;/p&gt;

&lt;p&gt;The $1 plans aren't a loss — they're a gateway. The $15 plans are the bread and butter. The $50+ plans for long trips are the margin boosters.&lt;/p&gt;

&lt;p&gt;If you're building one, focus on three things: carrier reliability over carrier price, country-specific SEO content, and a frictionless activation experience. The margins take care of themselves when customers come back.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much does it cost to start an eSIM marketplace?
&lt;/h3&gt;

&lt;p&gt;Minimal. An aggregator API account (often free to sign up), a basic web frontend, and a payment processor. Realistically $500–$2,000 for infrastructure if you're lean. The main cost is customer acquisition.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do eSIM marketplaces need telecom licenses?
&lt;/h3&gt;

&lt;p&gt;Generally no — you're reselling data from licensed carriers, not operating as a carrier yourself. However, some jurisdictions require registration or compliance with local telecom regulations, especially if you're marketing to consumers in that country. Check with a lawyer for your specific markets.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the average customer lifetime value?
&lt;/h3&gt;

&lt;p&gt;From what I've seen, customers who return for a second purchase have a 60%+ probability of buying a third time. Average LTV across 12 months for an engaged customer is $25–$60, depending on how frequently they travel.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do eSIM marketplaces handle refunds for failed activations?
&lt;/h3&gt;

&lt;p&gt;Most offer instant refunds or plan swaps when an eSIM fails to activate due to carrier issues. The key is having a fallback carrier in the same region — if one fails, you re-provision with another. This keeps refund rates low and customers happy.&lt;/p&gt;

</description>
      <category>esim</category>
      <category>marketplace</category>
      <category>business</category>
      <category>telecom</category>
    </item>
    <item>
      <title>How I Handled eSIM Activation Failures Across 200+ Countries (And What I Learned)</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Fri, 14 Aug 2026 00:19:29 +0000</pubDate>
      <link>https://dev.to/time_luxe/how-i-handled-esim-activation-failures-across-200-countries-and-what-i-learned-3hb</link>
      <guid>https://dev.to/time_luxe/how-i-handled-esim-activation-failures-across-200-countries-and-what-i-learned-3hb</guid>
      <description>&lt;h2&gt;
  
  
  Why Building an eSIM Platform Sounds Simple (But Isn't)
&lt;/h2&gt;

&lt;p&gt;When I started building &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, I naively assumed the hardest part would be negotiating carrier deals and getting coverage in 200+ countries. Turns out, that was the easy part. The real nightmare started the moment we tried to activate eSIM profiles at scale.&lt;/p&gt;

&lt;p&gt;eSIM activation is a deceptively complex pipeline. On the surface, it looks straightforward: user buys a plan → carrier provisions an eSIM profile → profile downloads to device → you're connected. But when you're orchestrating this across 200+ countries, each with its own carrier API, timeout behavior, error format, and network quirks, the edge cases multiply faster than you can handle them.&lt;/p&gt;

&lt;p&gt;This is the story of how I failed, learned, and eventually built a system that could gracefully handle activation failures across the entire globe.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First 1,000 Activations Were a Lie
&lt;/h2&gt;

&lt;p&gt;Our initial launch covered 50 countries. Everything worked beautifully in testing. We tested on iPhone 14s, Samsung Galaxy S23s, Google Pixels — the usual suspects. Success rate: 98%. We patted ourselves on the back and expanded to 100 countries.&lt;/p&gt;

&lt;p&gt;Then came Indonesia, Nigeria, and Peru.&lt;/p&gt;

&lt;p&gt;Our activation success rate plummeted to 73% in certain regions. Users would purchase, wait, and get nothing. Support tickets piled up. We'd dig into logs and find cryptic carrier errors reading like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GSMA_RSP_ERROR: 3.2.11 — Operation failed
HTTP 500 — Internal Server Error
Timeout after 30s: no SM-DP+ response

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These weren't one-off failures. They were patterns. And they were different in almost every country.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F09quusj6a8zbies8cf71.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F09quusj6a8zbies8cf71.gif" alt="Technical Difficulties Please Stand By" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping the Failure Landscape
&lt;/h2&gt;

&lt;p&gt;After three sleepless weeks of log analysis, I categorized the failures into five buckets:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Carrier API Timeouts
&lt;/h3&gt;

&lt;p&gt;Some carriers' SM-DP+ servers (the servers that prepare and deliver eSIM profiles) would timeout after exactly 30 seconds. Others would hang indefinitely. A few would respond instantly to our test calls but timeout under real load.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Non-Standard Error Codes
&lt;/h3&gt;

&lt;p&gt;The GSMA RSP specification defines a standard set of error codes for eSIM provisioning. You'd think carriers would use them. They don't. We saw HTTP 200 responses with error payloads, HTTP 500s with success payloads, and one carrier that returned HTTP 418 (I'm a teapot) when their eSIM queue was full.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Network-Level Failures
&lt;/h3&gt;

&lt;p&gt;In some countries, the local cellular network infrastructure would interfere with the eSIM profile download. Users on Carrier A couldn't activate an eSIM for Carrier B because the local network intercepted or throttled the OTA (over-the-air) profile download.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Device Firmware Incompatibilities
&lt;/h3&gt;

&lt;p&gt;Older Android devices with outdated eSIM firmware would reject profiles that newer devices handled fine. We discovered that some Chinese OEM phones had non-standard eSIM implementations that failed on GSMA-compliant SM-DP+ endpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Regional Rate Limiting
&lt;/h3&gt;

&lt;p&gt;Several carriers had undocumented rate limits — 5 activations per minute, 100 per hour, etc. Exceed them and you'd get silently blocked for 24 hours. No error message. Just dead silence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Retry Logic That Saved Us
&lt;/h2&gt;

&lt;p&gt;The first version of our retry logic was embarrassingly naive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function activateSIM(profileId) {
  try {
    return await carrierAPI.provision(profileId);
  } catch (err) {
    // Try again?
    return await carrierAPI.provision(profileId);
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This worked exactly as well as you'd expect — which is to say, not at all. Same call, same timeout, same failure. We needed exponential backoff with carrier-aware strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Retry System
&lt;/h3&gt;

&lt;p&gt;After multiple iterations, here's what actually worked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ActivationRetryHandler {
  constructor(carrierProfile) {
    this.carrier = carrierProfile;
    this.maxRetries = carrierProfile.maxRetries || 3;
    this.backoff = carrierProfile.backoffStrategy || 'exponential';
    this.timeoutMultipliers = {
      'fast': [5, 15, 45],       // seconds
      'normal': [10, 30, 90],
      'slow': [30, 90, 270]
    };
    this.circuitBreaker = new CircuitBreaker({
      threshold: carrierProfile.failureThreshold || 5,
      resetTimeout: 300000  // 5 minutes
    });
  }

  async activateWithRetry(activationRequest) {
    if (this.circuitBreaker.isOpen()) {
      return { status: 'circuit_open', retryAfter: this.circuitBreaker.retryAfter };
    }

    const timings = this.timeoutMultipliers[this.carrier.speedClass || 'normal'];

    for (let attempt = 0; attempt  c.count &amp;gt; alertingThreshold)
    .map(([sig, data]) =&amp;gt; ({ signature: sig, ...data }));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe5whh9w5ctjtxbf8lp8n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe5whh9w5ctjtxbf8lp8n.gif" alt="Space launch" width="500" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Launching to 200+ Countries (For Real This Time)
&lt;/h2&gt;

&lt;p&gt;After months of iterating on the activation pipeline, we rolled out to 200+ countries with a system that could handle failures gracefully. The result? 94.7% first-attempt activation success rate, and 98.2% within three retries.&lt;/p&gt;

&lt;p&gt;We wrote extensively about how eSIM works and how to activate it on our &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;What is an eSIM&lt;/a&gt; guide. If you're curious about the specifics of our activation flow, our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;eSIM Activation Guide&lt;/a&gt; walks through the process step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;If you're building a global service that depends on third-party APIs across multiple regions, here's what I wish I'd known from day one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test in production, but test carefully.&lt;/strong&gt; Simulated environments never replicate real-world carrier behavior. Build monitoring that detects anomalies in real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat every carrier as a unique API.&lt;/strong&gt; Even if they all adhere to the same GSMA standard, their implementations will differ. Build carrier-specific adapters from day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circuit breakers are non-negotiable.&lt;/strong&gt; When a carrier's API goes down, your retries should not make it worse. Back off, queue, and retry with grace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor at the carrier-region-device level.&lt;/strong&gt; A failure that affects only iPhone users on one carrier in Brazil tells a different story than a global outage. Granular data saves hours of debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document every quirk.&lt;/strong&gt; That carrier that returns HTTP 418? Document it. In six months when someone refactors the integration, they'll need to know.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What About You?
&lt;/h2&gt;

&lt;p&gt;Are you building something that depends on global third-party APIs? What's the weirdest error response you've ever seen from a production system? I'd love to hear your war stories in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>startup</category>
      <category>indiehacker</category>
      <category>devops</category>
    </item>
    <item>
      <title>Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 11 Aug 2026 21:58:05 +0000</pubDate>
      <link>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-3072</link>
      <guid>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-3072</guid>
      <description>&lt;p&gt;Eighteen months ago, I sat in a coffee shop in Bangkok with a dead phone and a stack of physical SIM cards from six different countries. I'd just paid $40 for a "global" roaming plan that barely worked. That moment — frustrated, overcharged, and disconnected — is where &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; was born.&lt;/p&gt;

&lt;p&gt;This isn't a polished startup story. It's the messy, real account of building a global eSIM platform from zero — the architecture decisions that kept me up at night, the carrier integrations that nearly broke me, and why I chose this stack over the traditional SIM card model that's dominated telecom for 30 years.&lt;/p&gt;

&lt;p&gt;If you're a developer curious about what it takes to build in the telecom space, or a founder evaluating whether eSIM is worth betting on, this is for you. No fluff. Just the real stack, the real problems, and the real numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Traditional SIM Cards (And Why It's 2026)
&lt;/h2&gt;

&lt;p&gt;Let's be honest: physical SIM cards are a relic. They were designed in 1991 for a world where you bought one phone, signed one contract, and stayed in one country. That world doesn't exist anymore.&lt;/p&gt;

&lt;p&gt;Here's what travelers actually deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Airport SIM kiosks&lt;/strong&gt; that charge 3x the local rate — and sometimes sell you a plan that doesn't even work across the border&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roaming plans&lt;/strong&gt; that cost $10/day for 500MB of throttled data — enough to check email, not enough to navigate an unfamiliar city with Google Maps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIM swapping&lt;/strong&gt; — losing your primary number, missing 2FA codes from your bank, juggling tiny plastic cards in a moving taxi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coverage gaps&lt;/strong&gt; — one SIM works in France but dies the moment you cross into Switzerland, and now you're hunting for a new SIM at a Swiss train station at 11 PM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;e-waste&lt;/strong&gt; — the telecom industry manufactures over 4.5 billion plastic SIM cards every year. Most end up in landfills within months&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The GSMA estimates that over 4.5 billion eSIM-capable devices will be in circulation by 2027. Apple went eSIM-only with the iPhone 14 in the US market back in 2022. Samsung, Google, and every major Android manufacturer now ship eSIM-capable devices. The hardware is ready. The GSMA standards are mature. The only thing missing was a platform that made buying and activating an eSIM as easy as ordering a coffee.&lt;/p&gt;

&lt;p&gt;So I built one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fduvx878lp1fbo4wmcnoo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fduvx878lp1fbo4wmcnoo.gif" alt="Global network connectivity visualization" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: What I Actually Built
&lt;/h2&gt;

&lt;p&gt;Before diving into code, I needed to answer one question: &lt;strong&gt;what does a global eSIM platform actually do under the hood?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At its core, an eSIM platform is a connectivity marketplace. It sits between travelers (who need data) and mobile network operators (who sell it). But unlike a traditional MVNO, you don't own spectrum, towers, or physical infrastructure. You're orchestrating digital SIM profiles across hundreds of carriers worldwide — and that changes everything about how you design the system.&lt;/p&gt;

&lt;p&gt;Here's the high-level architecture I landed on after 18 months of iteration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js 14 with App Router — server-side rendering for SEO-heavy country pages (200+ country-specific landing pages), client-side interactivity for the plan selector, coverage map, and checkout flow. Static generation for blog content, ISR (Incremental Static Regeneration) for pricing pages that change frequently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Layer:&lt;/strong&gt; Node.js with Express behind an NGINX reverse proxy, deployed on Cloudflare Workers for edge routing and geo-based redirects, with a dedicated VPS cluster for stateful operations like eSIM provisioning and payment processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL 16 (primary) with connection pooling via PgBouncer — handles orders, customer profiles, plan inventory, and carrier relationships. Redis for caching plan availability and pricing with per-carrier TTLs — eSIM inventory changes by the minute, and stale pricing is a trust killer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;eSIM Provisioning:&lt;/strong&gt; GSMA RSP (Remote SIM Provisioning) via SM-DP+ (Subscription Manager Data Preparation) — this is the actual protocol that delivers eSIM profiles to devices. We integrate with multiple SM-DP+ providers for redundancy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier Integration:&lt;/strong&gt; REST APIs, SOAP endpoints, and SMPP (Short Message Peer-to-Peer) for SMS-based activation fallback on older devices. Each carrier gets an adapter module behind a shared interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment Processing:&lt;/strong&gt; Stripe with multi-currency support — travelers pay in USD, EUR, GBP, AUD, JPY, and 20+ other currencies. Webhook-based order confirmation with idempotency keys to prevent double-charging during network hiccups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring &amp;amp; Observability:&lt;/strong&gt; Datadog for API health and latency, Sentry for error tracking with source maps, custom Prometheus metrics for activation success rates per carrier, and Grafana dashboards for real-time order funnel visualization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; Docker containers orchestrated with Docker Compose (we're a small team — Kubernetes would be overkill), deployed on Hetzner and AWS Lightsail for geographic distribution, with Cloudflare for CDN, DDoS protection, and DNS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack isn't exotic. It's boring technology applied to a hard problem. And that was intentional — I'd rather debug a well-understood Postgres query than a bleeding-edge distributed database at 3 AM when a customer in Tokyo can't activate their eSIM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Stack? The Decisions That Mattered
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Next.js Over a SPA: SEO Is Everything in Travel
&lt;/h3&gt;

&lt;p&gt;I started with a React SPA (Create React App, classic 2023 move). Within a month, I realized I'd made a catastrophic mistake. Our country-specific pages — &lt;code&gt;/japan-esim&lt;/code&gt;, &lt;code&gt;/europe-esim&lt;/code&gt;, &lt;code&gt;/thailand-esim&lt;/code&gt; — were invisible to Google. Client-side rendering meant crawlers saw empty divs with loading spinners.&lt;/p&gt;

&lt;p&gt;Switching to Next.js with SSR was a two-week migration that paid for itself in 30 days. Organic traffic from "best eSIM for Japan" and similar long-tail queries jumped 340%. For a travel product with 200+ location-based landing pages, SEO isn't a nice-to-have — it's the primary acquisition channel. Every country page is a potential entry point from Google.&lt;/p&gt;

&lt;p&gt;I also use Next.js ISR (Incremental Static Regeneration) for pricing pages. They rebuild every 15 minutes in the background, so Google always sees fresh content with current prices, but users never hit a cold server render. Best of both worlds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; If your product has hundreds of location-based pages, server-side rendering isn't optional. It's table stakes. And ISR is the secret weapon for content that changes frequently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. PostgreSQL + Redis: The Pricing Problem
&lt;/h3&gt;

&lt;p&gt;eSIM pricing is volatile. Carriers update rates weekly, sometimes daily. A plan that costs $4.99 today might be $5.49 tomorrow. If a customer sees one price and gets charged another, you've lost their trust — permanently. In travel, trust is everything.&lt;/p&gt;

&lt;p&gt;I built a pricing pipeline that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Polls carrier APIs every 15 minutes for rate changes using a cron-based worker&lt;/li&gt;
&lt;li&gt;Writes to PostgreSQL as the source of truth with full audit logging (who changed what, when, and the delta)&lt;/li&gt;
&lt;li&gt;Caches the latest prices in Redis with a 5-minute TTL per carrier&lt;/li&gt;
&lt;li&gt;Invalidates the Cloudflare CDN cache for affected country pages automatically via API&lt;/li&gt;
&lt;li&gt;At checkout, re-verifies the price against the carrier API in real-time before charging the customer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means the plan selector always shows near-real-time pricing, and the checkout flow verifies the price hasn't changed between page load and purchase. If it has, we surface the difference before charging — no surprises, no angry support tickets.&lt;/p&gt;

&lt;p&gt;The audit log in Postgres has saved us more than once. When a carrier claimed we were showing outdated prices, we could point to the exact timestamp and API response that set the current rate. Documentation is defense.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Carrier Integration Nightmare (And How I Survived It)
&lt;/h3&gt;

&lt;p&gt;This is the part nobody talks about in "building in public" posts. Integrating with mobile carriers is &lt;strong&gt;hard&lt;/strong&gt;. Not technically hard — the GSMA RSP spec is well-documented and surprisingly clean — but operationally hard.&lt;/p&gt;

&lt;p&gt;Here's what I learned the hard way over 18 months:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every carrier has a different API.&lt;/strong&gt; There's no universal standard. Some use REST with JSON, some use SOAP with XML envelopes (yes, in 2026), some require SFTP file drops with CSV order batches processed every 4 hours. I built an adapter pattern — each carrier gets its own integration module that conforms to a shared TypeScript interface. Adding a new carrier means writing one adapter class, not refactoring the entire platform. We're at 47 carrier adapters and counting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting is unpredictable and undocumented.&lt;/strong&gt; One carrier allows 100 requests/minute. Another allows 10. A third has no documented limit but starts returning 429s after exactly 50 requests in a rolling 60-second window — I had to discover that through trial and error. I built a token-bucket rate limiter per carrier with automatic backoff and a shared Redis counter. It's saved us from countless production outages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activation failures are inevitable.&lt;/strong&gt; About 2-3% of eSIM activations fail on the first attempt. Reasons range from device incompatibility (some Android manufacturers implement eUICC differently) to carrier provisioning delays (a profile that should take 30 seconds sometimes takes 5 minutes). I built a retry queue with exponential backoff (30s, 2min, 10min, 1hr) and automatic customer notification at each stage. Transparency turns a technical failure into a trust-building moment — customers are remarkably understanding when you tell them exactly what's happening and what you're doing about it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time zones will break your billing.&lt;/strong&gt; A plan activated at 11:59 PM UTC on Monday might expire at 11:59 PM UTC on the following Monday — but the customer is in Tokyo, where it's already Tuesday. I learned to store all durations in hours (not days) and display expiry in the user's local timezone using &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;. Sounds obvious in retrospect. Wasn't obvious at 2 AM debugging why Japanese customers were seeing "expired" plans that still had 23 hours left.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier sandboxes don't match production.&lt;/strong&gt; Every carrier provides a test environment. None of them behave like production. Different rate limits, different error messages, sometimes entirely different API versions. I now budget 2-3 days of production testing per carrier integration, with a dedicated test device and a real eSIM profile purchase. There's no substitute for testing with real money on a real network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faj1bpxpqphfchssjre1x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faj1bpxpqphfchssjre1x.gif" alt="Developer coding and building" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The SM-DP+ Protocol: How eSIM Profiles Actually Reach Your Phone
&lt;/h2&gt;

&lt;p&gt;This deserves its own section because it's the core technology that makes everything possible — and it's surprisingly elegant once you understand it.&lt;/p&gt;

&lt;p&gt;When a customer buys an eSIM plan on iWanteSIM, here's what happens behind the scenes in real-time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Order received&lt;/strong&gt; → Our API validates payment via Stripe, checks plan availability with the carrier's inventory API, and generates a unique order ID&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile generation&lt;/strong&gt; → The carrier's SM-DP+ server generates a unique eSIM profile (essentially a digital SIM card) bound to the customer's device EID (eUICC ID). This profile contains the IMSI, authentication keys, and carrier network configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QR code delivery&lt;/strong&gt; → We generate a QR code containing the SM-DP+ activation URL with the matching ID embedded. The customer scans it, and their device's eUICC (embedded Universal Integrated Circuit Card) initiates a secure TLS session with the SM-DP+ server to download and install the profile over the air&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activation confirmation&lt;/strong&gt; → The device registers on the carrier's network using the newly installed profile. We receive a confirmation via the carrier's webhook API and update the plan status from "provisioning" to "active"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The entire flow — from payment to active data connection — takes under 90 seconds on a good connection. Compare that to finding a SIM kiosk, waiting in line, showing your passport, and manually configuring APN settings. The difference isn't just convenience — it's a completely different product category.&lt;/p&gt;

&lt;p&gt;The GSMA's SGP.22 (RSP Technical Specification) and SGP.32 (IoT eSIM) standards govern this entire process. If you're building in this space, read them. They're dense — SGP.22 is over 200 pages — but essential. The spec covers everything from profile download and installation to remote profile management and deletion. Understanding it is the difference between building a reliable platform and building a house of cards.&lt;/p&gt;

&lt;p&gt;For a deeper dive into how eSIM technology works, I wrote a comprehensive guide on &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;What Is an eSIM?&lt;/a&gt; that breaks down the technical details in plain English.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;Building in public means being honest about mistakes. Here are mine, unfiltered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I should have started with a monolith.&lt;/strong&gt; I over-engineered the initial architecture with microservices — separate services for billing, provisioning, notifications, and analytics. For a team of three, this was insanity. The operational overhead of managing inter-service communication, distributed tracing, and deployment coordination ate 40% of our engineering time. I consolidated into a modular monolith after six months and deployment velocity doubled. Microservices solve organizational scaling problems, not technical ones. If you're a small team, keep it simple. You can extract services later when you actually need to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I underestimated customer support complexity.&lt;/strong&gt; eSIM activation isn't always smooth. Some Android manufacturers implement eUICC differently. Some iPhones need a specific iOS version (we still get tickets from people on iOS 15). I should have built the troubleshooting flow — device compatibility checker, step-by-step activation guide with screenshots, and automated diagnostics — &lt;em&gt;before&lt;/em&gt; launch, not after the first 500 support tickets. Our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;eSIM activation guide&lt;/a&gt; now handles 90% of common issues automatically, but it took months to get there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I should have launched with fewer countries.&lt;/strong&gt; I launched with 80+ countries because I wanted to look "global" and impressive. In reality, 80% of our first-month revenue came from 12 countries (Japan, USA, Thailand, UK, France, Italy, Spain, Germany, Australia, South Korea, Singapore, UAE). I should have focused on those 12, perfected the experience, and expanded gradually. Instead, I spent weeks debugging carrier issues in markets with literally zero customers. Vanity metrics are expensive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I should have invested in monitoring earlier.&lt;/strong&gt; For the first three months, I had no idea what our activation success rate was. I'd find out about carrier outages from customer support tickets. Now we have per-carrier Prometheus metrics, Grafana dashboards, and Slack alerts when any carrier's success rate drops below 95%. The peace of mind is worth every minute of setup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv2was21upoikof4f8c0n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv2was21upoikof4f8c0n.gif" alt="Server and data center technology" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers (Because Building in Public Means Sharing Real Data)
&lt;/h2&gt;

&lt;p&gt;After 18 months of building and iterating, here's where we stand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;200+ countries&lt;/strong&gt; covered with eSIM plans starting at $1.00&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12,000+ travelers&lt;/strong&gt; have used iWanteSIM across 180+ countries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4.9/5 average rating&lt;/strong&gt; across verified reviews&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;92% activation success rate&lt;/strong&gt; on first attempt (up from 84% at launch — every percentage point represents hundreds of fewer support tickets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average activation time:&lt;/strong&gt; 47 seconds from QR scan to connected (down from 2+ minutes at launch)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer support volume:&lt;/strong&gt; Down 60% since launching the interactive activation guide and device compatibility checker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;47 carrier integrations&lt;/strong&gt; live, each with its own adapter module behind a shared interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;99.7% API uptime&lt;/strong&gt; over the last 90 days — the provisioning pipeline is the one thing that absolutely cannot go down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't vanity metrics. Every number represents a real problem we solved — a failed activation we debugged at 3 AM, a confusing UI we redesigned after watching session recordings, a carrier integration we stabilized after weeks of back-and-forth with their engineering team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why eSIM Wins Over Traditional SIM Cards
&lt;/h2&gt;

&lt;p&gt;I didn't choose eSIM because it was trendy. I chose it because the economics and user experience are fundamentally better in every dimension that matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero physical inventory.&lt;/strong&gt; No manufacturing, no shipping, no retail distribution, no SIM cards lost in the mail. A digital SIM profile costs fractions of a cent to deliver. The marginal cost of serving one more customer approaches zero.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant delivery.&lt;/strong&gt; Customer buys → QR code appears → scan → connected. No waiting for a SIM card to arrive in the mail. No hunting for a SIM kiosk in a foreign airport at midnight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-profile support.&lt;/strong&gt; Modern phones support 8+ eSIM profiles simultaneously. Travelers can keep their home number active for calls and 2FA while using a local data plan for everything else — no more SIM swapping, no more missed authentication codes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environmental impact.&lt;/strong&gt; The telecom industry produces 4.5 billion plastic SIM cards annually. Most are used for weeks or months, then discarded. eSIM eliminates that waste entirely — no plastic, no packaging, no shipping carbon footprint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote provisioning.&lt;/strong&gt; Carriers can update, replace, or revoke eSIM profiles over the air. No physical access needed. This is transformative for IoT — imagine updating the connectivity profile on 10,000 asset trackers without touching a single device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional SIM cards had a 30-year run. They served their purpose. But in a world where people change countries more often than they change phone numbers, the plastic SIM card is obsolete. The future of mobile connectivity is digital, instant, and global.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm currently working on three major initiatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IoT eSIM support&lt;/strong&gt; — connecting devices beyond phones (cars, drones, asset trackers, smart meters) using the GSMA SGP.32 standard. This is a fundamentally different challenge — IoT devices don't have screens to scan QR codes, so the entire provisioning flow needs to be API-driven and automated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-powered plan recommendations&lt;/strong&gt; — analyzing travel itineraries to suggest the optimal eSIM plan based on countries visited, trip duration, and typical data usage patterns. If you're spending 3 days in Japan and 4 days in South Korea, you shouldn't need to manually compare 20 different plan combinations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise API&lt;/strong&gt; — letting travel agencies, airlines, and booking platforms embed eSIM purchasing directly into their checkout flows. Imagine booking a flight to Thailand and getting an eSIM offer before you even land.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building in the telecom or travel tech space, I'd love to connect. The eSIM ecosystem is still young — GSMA estimates we're at less than 15% of eventual market penetration — and there's room for a lot more innovation. Drop a comment below or reach out. I read every response.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of our "building in public" series at &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;. If you're curious about how eSIM technology works under the hood, check out our &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;What Is an eSIM?&lt;/a&gt; guide. Ready to try it yourself? Our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;eSIM activation guide&lt;/a&gt; walks you through setup in under 2 minutes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>esim</category>
      <category>webdev</category>
      <category>startup</category>
      <category>buildinginpublic</category>
    </item>
    <item>
      <title>Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 11 Aug 2026 21:00:22 +0000</pubDate>
      <link>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-410b</link>
      <guid>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-410b</guid>
      <description>&lt;p&gt;Eighteen months ago, I sat in a coffee shop in Bangkok with a dead phone and a stack of physical SIM cards from six different countries. I'd just paid $40 for a "global" roaming plan that barely worked. That moment — frustrated, overcharged, and disconnected — is where &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; was born.&lt;/p&gt;

&lt;p&gt;This isn't a polished startup story. It's the messy, real account of building a global eSIM platform from zero — the architecture decisions that kept me up at night, the carrier integrations that nearly broke me, and why I chose this stack over the traditional SIM card model that's dominated telecom for 30 years.&lt;/p&gt;

&lt;p&gt;If you're a developer curious about what it takes to build in the telecom space, or a founder evaluating whether eSIM is worth betting on, this is for you. No fluff. Just the real stack, the real problems, and the real numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Traditional SIM Cards (And Why It's 2026)
&lt;/h2&gt;

&lt;p&gt;Let's be honest: physical SIM cards are a relic. They were designed in 1991 for a world where you bought one phone, signed one contract, and stayed in one country. That world doesn't exist anymore.&lt;/p&gt;

&lt;p&gt;Here's what travelers actually deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Airport SIM kiosks&lt;/strong&gt; that charge 3x the local rate — and sometimes sell you a plan that doesn't even work across the border&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Roaming plans&lt;/strong&gt; that cost $10/day for 500MB of throttled data — enough to check email, not enough to navigate an unfamiliar city with Google Maps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SIM swapping&lt;/strong&gt; — losing your primary number, missing 2FA codes from your bank, juggling tiny plastic cards in a moving taxi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Coverage gaps&lt;/strong&gt; — one SIM works in France but dies the moment you cross into Switzerland, and now you're hunting for a new SIM at a Swiss train station at 11 PM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;e-waste&lt;/strong&gt; — the telecom industry manufactures over 4.5 billion plastic SIM cards every year. Most end up in landfills within months&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The GSMA estimates that over 4.5 billion eSIM-capable devices will be in circulation by 2027. Apple went eSIM-only with the iPhone 14 in the US market back in 2022. Samsung, Google, and every major Android manufacturer now ship eSIM-capable devices. The hardware is ready. The GSMA standards are mature. The only thing missing was a platform that made buying and activating an eSIM as easy as ordering a coffee.&lt;/p&gt;

&lt;p&gt;So I built one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fduvx878lp1fbo4wmcnoo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fduvx878lp1fbo4wmcnoo.gif" alt="Global network connectivity visualization" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: What I Actually Built
&lt;/h2&gt;

&lt;p&gt;Before diving into code, I needed to answer one question: &lt;strong&gt;what does a global eSIM platform actually do under the hood?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At its core, an eSIM platform is a connectivity marketplace. It sits between travelers (who need data) and mobile network operators (who sell it). But unlike a traditional MVNO, you don't own spectrum, towers, or physical infrastructure. You're orchestrating digital SIM profiles across hundreds of carriers worldwide — and that changes everything about how you design the system.&lt;/p&gt;

&lt;p&gt;Here's the high-level architecture I landed on after 18 months of iteration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js 14 with App Router — server-side rendering for SEO-heavy country pages (200+ country-specific landing pages), client-side interactivity for the plan selector, coverage map, and checkout flow. Static generation for blog content, ISR (Incremental Static Regeneration) for pricing pages that change frequently&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Layer:&lt;/strong&gt; Node.js with Express behind an NGINX reverse proxy, deployed on Cloudflare Workers for edge routing and geo-based redirects, with a dedicated VPS cluster for stateful operations like eSIM provisioning and payment processing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL 16 (primary) with connection pooling via PgBouncer — handles orders, customer profiles, plan inventory, and carrier relationships. Redis for caching plan availability and pricing with per-carrier TTLs — eSIM inventory changes by the minute, and stale pricing is a trust killer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;eSIM Provisioning:&lt;/strong&gt; GSMA RSP (Remote SIM Provisioning) via SM-DP+ (Subscription Manager Data Preparation) — this is the actual protocol that delivers eSIM profiles to devices. We integrate with multiple SM-DP+ providers for redundancy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Carrier Integration:&lt;/strong&gt; REST APIs, SOAP endpoints, and SMPP (Short Message Peer-to-Peer) for SMS-based activation fallback on older devices. Each carrier gets an adapter module behind a shared interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Payment Processing:&lt;/strong&gt; Stripe with multi-currency support — travelers pay in USD, EUR, GBP, AUD, JPY, and 20+ other currencies. Webhook-based order confirmation with idempotency keys to prevent double-charging during network hiccups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitoring &amp;amp; Observability:&lt;/strong&gt; Datadog for API health and latency, Sentry for error tracking with source maps, custom Prometheus metrics for activation success rates per carrier, and Grafana dashboards for real-time order funnel visualization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infrastructure:&lt;/strong&gt; Docker containers orchestrated with Docker Compose (we're a small team — Kubernetes would be overkill), deployed on Hetzner and AWS Lightsail for geographic distribution, with Cloudflare for CDN, DDoS protection, and DNS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack isn't exotic. It's boring technology applied to a hard problem. And that was intentional — I'd rather debug a well-understood Postgres query than a bleeding-edge distributed database at 3 AM when a customer in Tokyo can't activate their eSIM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Stack? The Decisions That Mattered
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Next.js Over a SPA: SEO Is Everything in Travel
&lt;/h3&gt;

&lt;p&gt;I started with a React SPA (Create React App, classic 2023 move). Within a month, I realized I'd made a catastrophic mistake. Our country-specific pages — &lt;code&gt;/japan-esim&lt;/code&gt;, &lt;code&gt;/europe-esim&lt;/code&gt;, &lt;code&gt;/thailand-esim&lt;/code&gt; — were invisible to Google. Client-side rendering meant crawlers saw empty divs with loading spinners.&lt;/p&gt;

&lt;p&gt;Switching to Next.js with SSR was a two-week migration that paid for itself in 30 days. Organic traffic from "best eSIM for Japan" and similar long-tail queries jumped 340%. For a travel product with 200+ location-based landing pages, SEO isn't a nice-to-have — it's the primary acquisition channel. Every country page is a potential entry point from Google.&lt;/p&gt;

&lt;p&gt;I also use Next.js ISR (Incremental Static Regeneration) for pricing pages. They rebuild every 15 minutes in the background, so Google always sees fresh content with current prices, but users never hit a cold server render. Best of both worlds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; If your product has hundreds of location-based pages, server-side rendering isn't optional. It's table stakes. And ISR is the secret weapon for content that changes frequently.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. PostgreSQL + Redis: The Pricing Problem
&lt;/h3&gt;

&lt;p&gt;eSIM pricing is volatile. Carriers update rates weekly, sometimes daily. A plan that costs $4.99 today might be $5.49 tomorrow. If a customer sees one price and gets charged another, you've lost their trust — permanently. In travel, trust is everything.&lt;/p&gt;

&lt;p&gt;I built a pricing pipeline that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Polls carrier APIs every 15 minutes for rate changes using a cron-based worker&lt;/li&gt;
&lt;li&gt;Writes to PostgreSQL as the source of truth with full audit logging (who changed what, when, and the delta)&lt;/li&gt;
&lt;li&gt;Caches the latest prices in Redis with a 5-minute TTL per carrier&lt;/li&gt;
&lt;li&gt;Invalidates the Cloudflare CDN cache for affected country pages automatically via API&lt;/li&gt;
&lt;li&gt;At checkout, re-verifies the price against the carrier API in real-time before charging the customer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means the plan selector always shows near-real-time pricing, and the checkout flow verifies the price hasn't changed between page load and purchase. If it has, we surface the difference before charging — no surprises, no angry support tickets.&lt;/p&gt;

&lt;p&gt;The audit log in Postgres has saved us more than once. When a carrier claimed we were showing outdated prices, we could point to the exact timestamp and API response that set the current rate. Documentation is defense.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Carrier Integration Nightmare (And How I Survived It)
&lt;/h3&gt;

&lt;p&gt;This is the part nobody talks about in "building in public" posts. Integrating with mobile carriers is &lt;strong&gt;hard&lt;/strong&gt;. Not technically hard — the GSMA RSP spec is well-documented and surprisingly clean — but operationally hard.&lt;/p&gt;

&lt;p&gt;Here's what I learned the hard way over 18 months:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Every carrier has a different API.&lt;/strong&gt; There's no universal standard. Some use REST with JSON, some use SOAP with XML envelopes (yes, in 2026), some require SFTP file drops with CSV order batches processed every 4 hours. I built an adapter pattern — each carrier gets its own integration module that conforms to a shared TypeScript interface. Adding a new carrier means writing one adapter class, not refactoring the entire platform. We're at 47 carrier adapters and counting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rate limiting is unpredictable and undocumented.&lt;/strong&gt; One carrier allows 100 requests/minute. Another allows 10. A third has no documented limit but starts returning 429s after exactly 50 requests in a rolling 60-second window — I had to discover that through trial and error. I built a token-bucket rate limiter per carrier with automatic backoff and a shared Redis counter. It's saved us from countless production outages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Activation failures are inevitable.&lt;/strong&gt; About 2-3% of eSIM activations fail on the first attempt. Reasons range from device incompatibility (some Android manufacturers implement eUICC differently) to carrier provisioning delays (a profile that should take 30 seconds sometimes takes 5 minutes). I built a retry queue with exponential backoff (30s, 2min, 10min, 1hr) and automatic customer notification at each stage. Transparency turns a technical failure into a trust-building moment — customers are remarkably understanding when you tell them exactly what's happening and what you're doing about it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time zones will break your billing.&lt;/strong&gt; A plan activated at 11:59 PM UTC on Monday might expire at 11:59 PM UTC on the following Monday — but the customer is in Tokyo, where it's already Tuesday. I learned to store all durations in hours (not days) and display expiry in the user's local timezone using Intl.DateTimeFormat. Sounds obvious in retrospect. Wasn't obvious at 2 AM debugging why Japanese customers were seeing "expired" plans that still had 23 hours left.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Carrier sandboxes don't match production.&lt;/strong&gt; Every carrier provides a test environment. None of them behave like production. Different rate limits, different error messages, sometimes entirely different API versions. I now budget 2-3 days of production testing per carrier integration, with a dedicated test device and a real eSIM profile purchase. There's no substitute for testing with real money on a real network.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faj1bpxpqphfchssjre1x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faj1bpxpqphfchssjre1x.gif" alt="Developer coding and building" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The SM-DP+ Protocol: How eSIM Profiles Actually Reach Your Phone
&lt;/h2&gt;

&lt;p&gt;This deserves its own section because it's the core technology that makes everything possible — and it's surprisingly elegant once you understand it.&lt;/p&gt;

&lt;p&gt;When a customer buys an eSIM plan on iWanteSIM, here's what happens behind the scenes in real-time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Order received&lt;/strong&gt; → Our API validates payment via Stripe, checks plan availability with the carrier's inventory API, and generates a unique order ID&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile generation&lt;/strong&gt; → The carrier's SM-DP+ server generates a unique eSIM profile (essentially a digital SIM card) bound to the customer's device EID (eUICC ID). This profile contains the IMSI, authentication keys, and carrier network configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QR code delivery&lt;/strong&gt; → We generate a QR code containing the SM-DP+ activation URL with the matching ID embedded. The customer scans it, and their device's eUICC (embedded Universal Integrated Circuit Card) initiates a secure TLS session with the SM-DP+ server to download and install the profile over the air&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activation confirmation&lt;/strong&gt; → The device registers on the carrier's network using the newly installed profile. We receive a confirmation via the carrier's webhook API and update the plan status from "provisioning" to "active"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The entire flow — from payment to active data connection — takes under 90 seconds on a good connection. Compare that to finding a SIM kiosk, waiting in line, showing your passport, and manually configuring APN settings. The difference isn't just convenience — it's a completely different product category.&lt;/p&gt;

&lt;p&gt;The GSMA's SGP.22 (RSP Technical Specification) and SGP.32 (IoT eSIM) standards govern this entire process. If you're building in this space, read them. They're dense — SGP.22 is over 200 pages — but essential. The spec covers everything from profile download and installation to remote profile management and deletion. Understanding it is the difference between building a reliable platform and building a house of cards.&lt;/p&gt;

&lt;p&gt;For a deeper dive into how eSIM technology works, I wrote a comprehensive guide on &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;What Is an eSIM?&lt;/a&gt; that breaks down the technical details in plain English.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;Building in public means being honest about mistakes. Here are mine, unfiltered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I should have started with a monolith.&lt;/strong&gt; I over-engineered the initial architecture with microservices — separate services for billing, provisioning, notifications, and analytics. For a team of three, this was insanity. The operational overhead of managing inter-service communication, distributed tracing, and deployment coordination ate 40% of our engineering time. I consolidated into a modular monolith after six months and deployment velocity doubled. Microservices solve organizational scaling problems, not technical ones. If you're a small team, keep it simple. You can extract services later when you actually need to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I underestimated customer support complexity.&lt;/strong&gt; eSIM activation isn't always smooth. Some Android manufacturers implement eUICC differently. Some iPhones need a specific iOS version (we still get tickets from people on iOS 15). I should have built the troubleshooting flow — device compatibility checker, step-by-step activation guide with screenshots, and automated diagnostics — &lt;em&gt;before&lt;/em&gt; launch, not after the first 500 support tickets. Our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;eSIM activation guide&lt;/a&gt; now handles 90% of common issues automatically, but it took months to get there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I should have launched with fewer countries.&lt;/strong&gt; I launched with 80+ countries because I wanted to look "global" and impressive. In reality, 80% of our first-month revenue came from 12 countries (Japan, USA, Thailand, UK, France, Italy, Spain, Germany, Australia, South Korea, Singapore, UAE). I should have focused on those 12, perfected the experience, and expanded gradually. Instead, I spent weeks debugging carrier issues in markets with literally zero customers. Vanity metrics are expensive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I should have invested in monitoring earlier.&lt;/strong&gt; For the first three months, I had no idea what our activation success rate was. I'd find out about carrier outages from customer support tickets. Now we have per-carrier Prometheus metrics, Grafana dashboards, and Slack alerts when any carrier's success rate drops below 95%. The peace of mind is worth every minute of setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv2was21upoikof4f8c0n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv2was21upoikof4f8c0n.gif" alt="Server and data center technology" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers (Because Building in Public Means Sharing Real Data)
&lt;/h2&gt;

&lt;p&gt;After 18 months of building and iterating, here's where we stand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;200+ countries&lt;/strong&gt; covered with eSIM plans starting at $1.00&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;12,000+ travelers&lt;/strong&gt; have used iWanteSIM across 180+ countries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;4.9/5 average rating&lt;/strong&gt; across verified reviews&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;92% activation success rate&lt;/strong&gt; on first attempt (up from 84% at launch — every percentage point represents hundreds of fewer support tickets)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Average activation time:&lt;/strong&gt; 47 seconds from QR scan to connected (down from 2+ minutes at launch)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customer support volume:&lt;/strong&gt; Down 60% since launching the interactive activation guide and device compatibility checker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;47 carrier integrations&lt;/strong&gt; live, each with its own adapter module behind a shared interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;99.7% API uptime&lt;/strong&gt; over the last 90 days — the provisioning pipeline is the one thing that absolutely cannot go down&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't vanity metrics. Every number represents a real problem we solved — a failed activation we debugged at 3 AM, a confusing UI we redesigned after watching session recordings, a carrier integration we stabilized after weeks of back-and-forth with their engineering team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why eSIM Wins Over Traditional SIM Cards
&lt;/h2&gt;

&lt;p&gt;I didn't choose eSIM because it was trendy. I chose it because the economics and user experience are fundamentally better in every dimension that matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero physical inventory.&lt;/strong&gt; No manufacturing, no shipping, no retail distribution, no SIM cards lost in the mail. A digital SIM profile costs fractions of a cent to deliver. The marginal cost of serving one more customer approaches zero.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Instant delivery.&lt;/strong&gt; Customer buys → QR code appears → scan → connected. No waiting for a SIM card to arrive in the mail. No hunting for a SIM kiosk in a foreign airport at midnight.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-profile support.&lt;/strong&gt; Modern phones support 8+ eSIM profiles simultaneously. Travelers can keep their home number active for calls and 2FA while using a local data plan for everything else — no more SIM swapping, no more missed authentication codes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Environmental impact.&lt;/strong&gt; The telecom industry produces 4.5 billion plastic SIM cards annually. Most are used for weeks or months, then discarded. eSIM eliminates that waste entirely — no plastic, no packaging, no shipping carbon footprint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Remote provisioning.&lt;/strong&gt; Carriers can update, replace, or revoke eSIM profiles over the air. No physical access needed. This is transformative for IoT — imagine updating the connectivity profile on 10,000 asset trackers without touching a single device.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional SIM cards had a 30-year run. They served their purpose. But in a world where people change countries more often than they change phone numbers, the plastic SIM card is obsolete. The future of mobile connectivity is digital, instant, and global.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm currently working on three major initiatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IoT eSIM support&lt;/strong&gt; — connecting devices beyond phones (cars, drones, asset trackers, smart meters) using the GSMA SGP.32 standard. This is a fundamentally different challenge — IoT devices don't have screens to scan QR codes, so the entire provisioning flow needs to be API-driven and automated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI-powered plan recommendations&lt;/strong&gt; — analyzing travel itineraries to suggest the optimal eSIM plan based on countries visited, trip duration, and typical data usage patterns. If you're spending 3 days in Japan and 4 days in South Korea, you shouldn't need to manually compare 20 different plan combinations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enterprise API&lt;/strong&gt; — letting travel agencies, airlines, and booking platforms embed eSIM purchasing directly into their checkout flows. Imagine booking a flight to Thailand and getting an eSIM offer before you even land.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building in the telecom or travel tech space, I'd love to connect. The eSIM ecosystem is still young — GSMA estimates we're at less than 15% of eventual market penetration — and there's room for a lot more innovation. Drop a comment below or reach out. I read every response.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is part of our "building in public" series at &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;. If you're curious about how eSIM technology works under the hood, check out our &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;What Is an eSIM?&lt;/a&gt; guide. Ready to try it yourself? Our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;eSIM activation guide&lt;/a&gt; walks you through setup in under 2 minutes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>esim</category>
      <category>webdev</category>
      <category>startup</category>
      <category>buildinginpublic</category>
    </item>
    <item>
      <title>Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 11 Aug 2026 20:02:00 +0000</pubDate>
      <link>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-15k3</link>
      <guid>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-15k3</guid>
      <description>&lt;h2&gt;
  
  
  The Moment Everything Clicked
&lt;/h2&gt;

&lt;p&gt;I was standing in a Tokyo 7-Eleven at 11 PM, jet-lagged and frustrated, trying to pry a plastic SIM tray out of my phone with a paperclip I'd borrowed from the cashier. The physical SIM card I'd bought at the airport wasn't activating. My hands were shaking from too much airplane coffee. And I thought: &lt;em&gt;this is 2024. Why am I still doing this?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That moment — standing under fluorescent lights, fumbling with a piece of plastic smaller than my fingernail — is where this whole thing started. Not with a pitch deck. Not with a market analysis. With genuine, bone-deep frustration at how absurdly broken the mobile connectivity experience still is for travelers.&lt;/p&gt;

&lt;p&gt;Six months later, I shipped the first version of &lt;strong&gt;RoamLink&lt;/strong&gt; — a global eSIM platform that lets travelers buy and activate data plans in 190+ countries without touching a physical SIM card. This is the story of how I built it, why I chose the stack I did, and what I'd do differently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdqzjenid1tsh4nctenle.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdqzjenid1tsh4nctenle.gif" alt="Coding and building in public" width="220" height="220"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;em&gt;Building something from scratch — one commit at a time&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Actually Built
&lt;/h2&gt;

&lt;p&gt;RoamLink is, at its core, an eSIM provisioning platform. But that's a deceptively simple description. Here's what's actually under the hood:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A carrier integration layer&lt;/strong&gt; that talks to multiple eSIM providers (GSMA-certified SM-DP+ servers) via the GSMA SGP.22 and SGP.32 specifications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A plan catalog&lt;/strong&gt; with real-time pricing, coverage maps, and availability across 190+ countries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A provisioning API&lt;/strong&gt; that generates and delivers eSIM profiles (QR codes, activation codes, SM-DP+ addresses) to end users in under 30 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A web dashboard and mobile app&lt;/strong&gt; for browsing plans, purchasing, and managing active eSIMs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Usage monitoring and top-up&lt;/strong&gt; so travelers don't get stranded mid-trip&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform handles the full lifecycle: browse → purchase → provision → activate → monitor → expire. All without a physical SIM card ever entering the picture. If you're new to the technology, here's &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;a primer on what eSIM actually is&lt;/a&gt; and why it's replacing physical SIMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack: What I Chose and Why
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Go (Golang) for the Backend
&lt;/h3&gt;

&lt;p&gt;I knew from day one this had to be Go. Here's the decision log:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrency is not optional.&lt;/strong&gt; An eSIM platform is fundamentally an I/O-bound system. Every purchase triggers a chain of operations: validate payment, check inventory with the carrier, request profile generation from the SM-DP+ server, wait for confirmation, deliver the profile to the user. If any of these block, the whole pipeline stalls. Go's goroutines make this trivial — each purchase is a lightweight goroutine, and the runtime handles scheduling across available threads. No thread pools. No async/await ceremony. Just &lt;code&gt;go processPurchase(order)&lt;/code&gt; and move on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment simplicity.&lt;/strong&gt; Traditional telecom stacks run on Java application servers (WebLogic, JBoss) that require gigabytes of RAM and dedicated ops teams. A Go binary is a single static file. I can deploy the entire RoamLink backend as a 15 MB binary that starts in milliseconds and runs happily on a $20/month VPS. For a bootstrapped startup, that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard library that actually covers your needs.&lt;/strong&gt; The &lt;code&gt;net/http&lt;/code&gt; package is production-ready. &lt;code&gt;crypto/tls&lt;/code&gt; handles the mutual TLS that GSMA specs require for SM-DP+ communication. &lt;code&gt;encoding/json&lt;/code&gt; and &lt;code&gt;encoding/xml&lt;/code&gt; cover the API formats. I didn't need a framework — just the standard library, a router (&lt;code&gt;chi&lt;/code&gt;), and a database driver.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgreSQL — Not MongoDB, Not Cassandra
&lt;/h3&gt;

&lt;p&gt;This was the most debated decision. The team had people arguing for MongoDB ("it's what startups use") and Cassandra ("we'll need the scale"). I pushed for PostgreSQL. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;eSIM data is relational.&lt;/strong&gt; A user has many orders. An order has one eSIM profile. A profile belongs to one carrier plan. A plan covers many countries. This is a textbook relational model. Trying to denormalize this into documents or wide-column stores would create consistency nightmares.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transactions matter when money is involved.&lt;/strong&gt; When a user pays $30 for a 10GB plan, I need atomicity. Deduct from inventory, create the order, charge the card, request the profile — if any step fails, everything rolls back. PostgreSQL's ACID transactions make this straightforward. MongoDB's multi-document transactions exist but feel bolted-on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSONB gives us the best of both worlds.&lt;/strong&gt; Carrier plan metadata varies wildly — some providers include throttling policies, others have fair-use clauses, some have time-of-day restrictions. PostgreSQL's JSONB columns let us store this semi-structured data alongside our relational schema without losing queryability. We can index into JSONB fields and join them with regular tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You probably don't have Cassandra-scale problems.&lt;/strong&gt; RoamLink processes thousands of orders per day, not millions per second. PostgreSQL handles this on modest hardware. If we ever outgrow it, we'll have the revenue to hire a team that knows how to migrate. Premature scale optimization is the root of all over-engineering.&lt;/p&gt;

&lt;h3&gt;
  
  
  gRPC for Internal Services
&lt;/h3&gt;

&lt;p&gt;The platform is split into microservices: &lt;code&gt;catalog&lt;/code&gt;, &lt;code&gt;orders&lt;/code&gt;, &lt;code&gt;provisioning&lt;/code&gt;, &lt;code&gt;billing&lt;/code&gt;, &lt;code&gt;notifications&lt;/code&gt;. They need to talk to each other fast. I chose gRPC over REST for internal communication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Protocol Buffers enforce a contract.&lt;/strong&gt; Every service has a &lt;code&gt;.proto&lt;/code&gt; file that defines exactly what it accepts and returns. No more "is this field optional?" debates at 2 AM. The contract is the source of truth, and both client and server code are generated from it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP/2 multiplexing.&lt;/strong&gt; The provisioning service makes parallel calls to multiple SM-DP+ servers. With REST, that's multiple TCP connections. With gRPC, it's multiplexed over a single HTTP/2 connection. Less overhead, fewer file descriptors, faster responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streaming for long-running operations.&lt;/strong&gt; Profile generation on the carrier side can take 10-30 seconds. With gRPC server streaming, the provisioning service can send progress updates back to the orders service in real time, rather than polling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The external API (for the web and mobile apps) is still REST — because browsers and mobile SDKs speak REST natively. But everything behind the firewall is gRPC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis for the Hot Path
&lt;/h3&gt;

&lt;p&gt;Plan pricing and availability change frequently. Querying the database on every page load is wasteful. Redis sits in front of PostgreSQL as a read-through cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Plan catalog queries ("show me all plans for Japan") hit Redis first, PostgreSQL on cache miss&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rate limiting for the provisioning API (carriers get unhappy if you hammer their SM-DP+ servers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Session management for the web dashboard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Job queues for async operations like email delivery and usage data sync&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis is one of those tools that starts as "just a cache" and quietly becomes the backbone of your infrastructure. I'm not mad about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjl8yb4gixzbhtu8dcb0o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjl8yb4gixzbhtu8dcb0o.gif" alt="Server infrastructure and cloud deployment" width="480" height="360"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;em&gt;When your infrastructure actually stays up through a traffic spike&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not the Traditional Telecom Stack?
&lt;/h2&gt;

&lt;p&gt;The traditional way to build a platform like this would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Java EE&lt;/strong&gt; on WebLogic or JBoss — because "that's what telecom runs on"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Oracle Database&lt;/strong&gt; — because "it's enterprise-grade"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SOAP/XML&lt;/strong&gt; APIs — because GSMA specs are XML-heavy and "it's what carriers expect"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Physical SIM logistics&lt;/strong&gt; — warehouses, shipping, inventory management for plastic cards&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's why I rejected every single one of those:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java EE is a resource hog.&lt;/strong&gt; A basic WebLogic instance needs 2-4 GB of RAM before you've written a single line of business logic. Multiply that by dev, staging, production, and you're looking at serious infrastructure costs before you have a single customer. Go gives us the same reliability with 50 MB of RAM per service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oracle licensing is a trap.&lt;/strong&gt; I've been burned before. You start with the free tier, then you need partitioning, then you need RAC, and suddenly your database costs more than the rest of your infrastructure combined. PostgreSQL is free, forever, and the performance difference is negligible for our workload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOAP is dead, and XML is a crime scene.&lt;/strong&gt; Yes, GSMA specs use XML. Yes, we have to parse it when talking to SM-DP+ servers. But that doesn't mean our entire API surface needs to be SOAP. We parse XML at the integration boundary, translate to Protobuf internally, and expose clean REST/JSON to our own clients. The carrier-facing code is the only place XML lives — and it's isolated behind a well-defined interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Physical SIMs are the problem, not the solution.&lt;/strong&gt; The entire point of this platform is to eliminate physical SIM cards. Building a traditional SIM logistics operation — warehousing, shipping, inventory tracking — would be building the very thing we're trying to replace. eSIM provisioning is purely digital. No plastic. No shipping. No "sorry, we ran out of Japan SIMs."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Parts Nobody Talks About
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Carrier Integration Is a Nightmare
&lt;/h3&gt;

&lt;p&gt;Every eSIM carrier has their own API. Some use REST. Some use SOAP. Some use a custom binary protocol over TCP that was clearly designed in 2003 by one engineer who has since left the company. The GSMA specs define the &lt;em&gt;profile format&lt;/em&gt; but not the &lt;em&gt;ordering API&lt;/em&gt;. So you end up writing a new adapter for every carrier.&lt;/p&gt;

&lt;p&gt;Our solution: an &lt;strong&gt;adapter pattern&lt;/strong&gt; with a shared interface. Each carrier gets its own Go package that implements the &lt;code&gt;Provisioner&lt;/code&gt; interface. The core provisioning service doesn't know or care which carrier it's talking to — it just calls &lt;code&gt;provisioner.RequestProfile(ctx, req)&lt;/code&gt; and the adapter handles the rest. Adding a new carrier means writing one new package, not touching the core logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time Zones Will Break Your Brain
&lt;/h3&gt;

&lt;p&gt;An eSIM plan that's "valid for 7 days" — when does it expire? In the user's home timezone? The destination timezone? UTC? What if the user crosses the International Date Line mid-trip?&lt;/p&gt;

&lt;p&gt;We settled on: all plan durations are in UTC, displayed to the user in their device's local timezone, with a clear countdown timer that shows "3 days 4 hours remaining" rather than an absolute date. It's not perfect, but it's the least confusing option we tested.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment Fragmentation
&lt;/h3&gt;

&lt;p&gt;Travelers come from everywhere and pay with everything. Credit cards, Apple Pay, Google Pay, Alipay, Pix, UPI. Supporting all of these is a full-time job. We use Stripe as the primary processor with regional fallbacks, but the payment integration layer is easily 30% of the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with observability.&lt;/strong&gt; I shipped without proper tracing and regretted it within 48 hours. When a profile provisioning fails, you need to know &lt;em&gt;exactly&lt;/em&gt; where — was it the payment? The carrier API? The SM-DP+ server? The notification delivery? OpenTelemetry from day one would have saved me a weekend of debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't build your own auth.&lt;/strong&gt; I wrote a custom JWT-based auth system because "how hard can it be?" The answer: harder than you think, especially when you add refresh tokens, device management, and multi-factor auth. Use Clerk, Auth0, or Firebase Auth. Pay the money. Move on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limit everything from the start.&lt;/strong&gt; Carriers have aggressive rate limits, and they will cut you off without warning. We learned this the hard way when a pricing update job accidentally hammered a carrier's API and got our IP blocked for 4 hours. Implement token-bucket rate limiting on every outbound connection from day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the carrier simulator first.&lt;/strong&gt; Testing against real SM-DP+ servers is slow and expensive (some carriers charge per profile, even in test mode). A simulator that mimics the GSMA profile generation flow would have accelerated development dramatically. We built one eventually, but it should have been the first thing we wrote.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq9rwnxaf324wtzpwf76t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq9rwnxaf324wtzpwf76t.gif" alt="Technology innovation and future thinking" width="480" height="270"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;em&gt;Looking back at the stack decisions — no regrets&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers (So Far)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;190+ countries&lt;/strong&gt; covered through 12 carrier partnerships&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Average provisioning time:&lt;/strong&gt; 18 seconds from payment to QR code delivery&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infrastructure cost:&lt;/strong&gt; ~$400/month on Hetzner and AWS (3 VPS instances, managed PostgreSQL, Redis)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lines of Go:&lt;/strong&gt; ~28,000 across 6 microservices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lines of carrier adapter code:&lt;/strong&gt; ~8,000 (for 12 carriers — that's ~650 lines per carrier on average)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Uptime:&lt;/strong&gt; 99.93% over the last 90 days&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Is This Stack Right for You?
&lt;/h2&gt;

&lt;p&gt;If you're building something similar — a platform that needs to talk to external APIs, handle payments, manage state, and scale from zero to thousands of users — Go + PostgreSQL + Redis + gRPC is a fantastic foundation. It's boring technology in the best way: well-understood, well-documented, and unlikely to surprise you at 3 AM.&lt;/p&gt;

&lt;p&gt;If you're building a traditional telecom OSS/BSS with hundreds of existing SOAP integrations and a team of Java developers who've been doing this for 20 years — stick with Java. The best stack is the one your team can operate.&lt;/p&gt;

&lt;p&gt;But if you're starting fresh, building something that didn't exist before, and you want to move fast without accumulating technical debt that'll crush you in year two — Go is the answer. It was for me. Check out &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; to see the platform in action, or read our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;step-by-step eSIM activation guide&lt;/a&gt; to see how the provisioning flow works from the user's perspective.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is part of my "building in public" series. I'm documenting the entire journey of building RoamLink from idea to revenue. Follow along if you're into this kind of thing. And if you're building something in the connectivity space, I'd love to hear about your stack choices — drop a comment below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>startup</category>
      <category>go</category>
      <category>buildinginpublic</category>
    </item>
    <item>
      <title>Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 11 Aug 2026 18:56:47 +0000</pubDate>
      <link>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-519h</link>
      <guid>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-519h</guid>
      <description>&lt;h2&gt;
  
  
  The Moment Everything Clicked
&lt;/h2&gt;

&lt;p&gt;I was standing in a Tokyo 7-Eleven at 11 PM, jet-lagged and frustrated, trying to pry a plastic SIM tray out of my phone with a paperclip I'd borrowed from the cashier. The physical SIM card I'd bought at the airport wasn't activating. My hands were shaking from too much airplane coffee. And I thought: &lt;em&gt;this is 2024. Why am I still doing this?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That moment — standing under fluorescent lights, fumbling with a piece of plastic smaller than my fingernail — is where this whole thing started. Not with a pitch deck. Not with a market analysis. With genuine, bone-deep frustration at how absurdly broken the mobile connectivity experience still is for travelers.&lt;/p&gt;

&lt;p&gt;Six months later, I shipped the first version of &lt;strong&gt;RoamLink&lt;/strong&gt; — a global eSIM platform that lets travelers buy and activate data plans in 190+ countries without touching a physical SIM card. This is the story of how I built it, why I chose the stack I did, and what I'd do differently.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://media0.giphy.com/media/scZPhLqaVOM1qG4lT9/giphy.gif" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;media0.giphy.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;em&gt;Building something from scratch — one commit at a time&lt;/em&gt;

&lt;h2&gt;
  
  
  What We Actually Built
&lt;/h2&gt;

&lt;p&gt;RoamLink is, at its core, an eSIM provisioning platform. But that's a deceptively simple description. Here's what's actually under the hood:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A carrier integration layer&lt;/strong&gt; that talks to multiple eSIM providers (GSMA-certified SM-DP+ servers) via the GSMA SGP.22 and SGP.32 specifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A plan catalog&lt;/strong&gt; with real-time pricing, coverage maps, and availability across 190+ countries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A provisioning API&lt;/strong&gt; that generates and delivers eSIM profiles (QR codes, activation codes, SM-DP+ addresses) to end users in under 30 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A web dashboard and mobile app&lt;/strong&gt; for browsing plans, purchasing, and managing active eSIMs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage monitoring and top-up&lt;/strong&gt; so travelers don't get stranded mid-trip&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform handles the full lifecycle: browse → purchase → provision → activate → monitor → expire. All without a physical SIM card ever entering the picture. If you're new to the technology, here's &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;a primer on what eSIM actually is&lt;/a&gt; and why it's replacing physical SIMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack: What I Chose and Why
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Go (Golang) for the Backend
&lt;/h3&gt;

&lt;p&gt;I knew from day one this had to be Go. Here's the decision log:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrency is not optional.&lt;/strong&gt; An eSIM platform is fundamentally an I/O-bound system. Every purchase triggers a chain of operations: validate payment, check inventory with the carrier, request profile generation from the SM-DP+ server, wait for confirmation, deliver the profile to the user. If any of these block, the whole pipeline stalls. Go's goroutines make this trivial — each purchase is a lightweight goroutine, and the runtime handles scheduling across available threads. No thread pools. No async/await ceremony. Just &lt;code&gt;go processPurchase(order)&lt;/code&gt; and move on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment simplicity.&lt;/strong&gt; Traditional telecom stacks run on Java application servers (WebLogic, JBoss) that require gigabytes of RAM and dedicated ops teams. A Go binary is a single static file. I can deploy the entire RoamLink backend as a 15 MB binary that starts in milliseconds and runs happily on a $20/month VPS. For a bootstrapped startup, that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard library that actually covers your needs.&lt;/strong&gt; The &lt;code&gt;net/http&lt;/code&gt; package is production-ready. &lt;code&gt;crypto/tls&lt;/code&gt; handles the mutual TLS that GSMA specs require for SM-DP+ communication. &lt;code&gt;encoding/json&lt;/code&gt; and &lt;code&gt;encoding/xml&lt;/code&gt; cover the API formats. I didn't need a framework — just the standard library, a router (&lt;code&gt;chi&lt;/code&gt;), and a database driver.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgreSQL — Not MongoDB, Not Cassandra
&lt;/h3&gt;

&lt;p&gt;This was the most debated decision. The team had people arguing for MongoDB ("it's what startups use") and Cassandra ("we'll need the scale"). I pushed for PostgreSQL. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;eSIM data is relational.&lt;/strong&gt; A user has many orders. An order has one eSIM profile. A profile belongs to one carrier plan. A plan covers many countries. This is a textbook relational model. Trying to denormalize this into documents or wide-column stores would create consistency nightmares.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transactions matter when money is involved.&lt;/strong&gt; When a user pays $30 for a 10GB plan, I need atomicity. Deduct from inventory, create the order, charge the card, request the profile — if any step fails, everything rolls back. PostgreSQL's ACID transactions make this straightforward. MongoDB's multi-document transactions exist but feel bolted-on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSONB gives us the best of both worlds.&lt;/strong&gt; Carrier plan metadata varies wildly — some providers include throttling policies, others have fair-use clauses, some have time-of-day restrictions. PostgreSQL's JSONB columns let us store this semi-structured data alongside our relational schema without losing queryability. We can index into JSONB fields and join them with regular tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You probably don't have Cassandra-scale problems.&lt;/strong&gt; RoamLink processes thousands of orders per day, not millions per second. PostgreSQL handles this on modest hardware. If we ever outgrow it, we'll have the revenue to hire a team that knows how to migrate. Premature scale optimization is the root of all over-engineering.&lt;/p&gt;

&lt;h3&gt;
  
  
  gRPC for Internal Services
&lt;/h3&gt;

&lt;p&gt;The platform is split into microservices: &lt;code&gt;catalog&lt;/code&gt;, &lt;code&gt;orders&lt;/code&gt;, &lt;code&gt;provisioning&lt;/code&gt;, &lt;code&gt;billing&lt;/code&gt;, &lt;code&gt;notifications&lt;/code&gt;. They need to talk to each other fast. I chose gRPC over REST for internal communication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol Buffers enforce a contract.&lt;/strong&gt; Every service has a &lt;code&gt;.proto&lt;/code&gt; file that defines exactly what it accepts and returns. No more "is this field optional?" debates at 2 AM. The contract is the source of truth, and both client and server code are generated from it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/2 multiplexing.&lt;/strong&gt; The provisioning service makes parallel calls to multiple SM-DP+ servers. With REST, that's multiple TCP connections. With gRPC, it's multiplexed over a single HTTP/2 connection. Less overhead, fewer file descriptors, faster responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming for long-running operations.&lt;/strong&gt; Profile generation on the carrier side can take 10-30 seconds. With gRPC server streaming, the provisioning service can send progress updates back to the orders service in real time, rather than polling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The external API (for the web and mobile apps) is still REST — because browsers and mobile SDKs speak REST natively. But everything behind the firewall is gRPC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis for the Hot Path
&lt;/h3&gt;

&lt;p&gt;Plan pricing and availability change frequently. Querying the database on every page load is wasteful. Redis sits in front of PostgreSQL as a read-through cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plan catalog queries ("show me all plans for Japan") hit Redis first, PostgreSQL on cache miss&lt;/li&gt;
&lt;li&gt;Rate limiting for the provisioning API (carriers get unhappy if you hammer their SM-DP+ servers)&lt;/li&gt;
&lt;li&gt;Session management for the web dashboard&lt;/li&gt;
&lt;li&gt;Job queues for async operations like email delivery and usage data sync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis is one of those tools that starts as "just a cache" and quietly becomes the backbone of your infrastructure. I'm not mad about it.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://media1.giphy.com/media/z2rAxByf9eIA6Llfhy/giphy.gif" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;media1.giphy.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;em&gt;When your infrastructure actually stays up through a traffic spike&lt;/em&gt;

&lt;h2&gt;
  
  
  Why Not the Traditional Telecom Stack?
&lt;/h2&gt;

&lt;p&gt;The traditional way to build a platform like this would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java EE&lt;/strong&gt; on WebLogic or JBoss — because "that's what telecom runs on"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oracle Database&lt;/strong&gt; — because "it's enterprise-grade"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SOAP/XML&lt;/strong&gt; APIs — because GSMA specs are XML-heavy and "it's what carriers expect"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Physical SIM logistics&lt;/strong&gt; — warehouses, shipping, inventory management for plastic cards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's why I rejected every single one of those:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java EE is a resource hog.&lt;/strong&gt; A basic WebLogic instance needs 2-4 GB of RAM before you've written a single line of business logic. Multiply that by dev, staging, production, and you're looking at serious infrastructure costs before you have a single customer. Go gives us the same reliability with 50 MB of RAM per service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oracle licensing is a trap.&lt;/strong&gt; I've been burned before. You start with the free tier, then you need partitioning, then you need RAC, and suddenly your database costs more than the rest of your infrastructure combined. PostgreSQL is free, forever, and the performance difference is negligible for our workload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOAP is dead, and XML is a crime scene.&lt;/strong&gt; Yes, GSMA specs use XML. Yes, we have to parse it when talking to SM-DP+ servers. But that doesn't mean our entire API surface needs to be SOAP. We parse XML at the integration boundary, translate to Protobuf internally, and expose clean REST/JSON to our own clients. The carrier-facing code is the only place XML lives — and it's isolated behind a well-defined interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Physical SIMs are the problem, not the solution.&lt;/strong&gt; The entire point of this platform is to eliminate physical SIM cards. Building a traditional SIM logistics operation — warehousing, shipping, inventory tracking — would be building the very thing we're trying to replace. eSIM provisioning is purely digital. No plastic. No shipping. No "sorry, we ran out of Japan SIMs."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Parts Nobody Talks About
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Carrier Integration Is a Nightmare
&lt;/h3&gt;

&lt;p&gt;Every eSIM carrier has their own API. Some use REST. Some use SOAP. Some use a custom binary protocol over TCP that was clearly designed in 2003 by one engineer who has since left the company. The GSMA specs define the &lt;em&gt;profile format&lt;/em&gt; but not the &lt;em&gt;ordering API&lt;/em&gt;. So you end up writing a new adapter for every carrier.&lt;/p&gt;

&lt;p&gt;Our solution: an &lt;strong&gt;adapter pattern&lt;/strong&gt; with a shared interface. Each carrier gets its own Go package that implements the &lt;code&gt;Provisioner&lt;/code&gt; interface. The core provisioning service doesn't know or care which carrier it's talking to — it just calls &lt;code&gt;provisioner.RequestProfile(ctx, req)&lt;/code&gt; and the adapter handles the rest. Adding a new carrier means writing one new package, not touching the core logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time Zones Will Break Your Brain
&lt;/h3&gt;

&lt;p&gt;An eSIM plan that's "valid for 7 days" — when does it expire? In the user's home timezone? The destination timezone? UTC? What if the user crosses the International Date Line mid-trip?&lt;/p&gt;

&lt;p&gt;We settled on: all plan durations are in UTC, displayed to the user in their device's local timezone, with a clear countdown timer that shows "3 days 4 hours remaining" rather than an absolute date. It's not perfect, but it's the least confusing option we tested.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment Fragmentation
&lt;/h3&gt;

&lt;p&gt;Travelers come from everywhere and pay with everything. Credit cards, Apple Pay, Google Pay, Alipay, Pix, UPI. Supporting all of these is a full-time job. We use Stripe as the primary processor with regional fallbacks, but the payment integration layer is easily 30% of the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with observability.&lt;/strong&gt; I shipped without proper tracing and regretted it within 48 hours. When a profile provisioning fails, you need to know &lt;em&gt;exactly&lt;/em&gt; where — was it the payment? The carrier API? The SM-DP+ server? The notification delivery? OpenTelemetry from day one would have saved me a weekend of debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't build your own auth.&lt;/strong&gt; I wrote a custom JWT-based auth system because "how hard can it be?" The answer: harder than you think, especially when you add refresh tokens, device management, and multi-factor auth. Use Clerk, Auth0, or Firebase Auth. Pay the money. Move on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limit everything from the start.&lt;/strong&gt; Carriers have aggressive rate limits, and they will cut you off without warning. We learned this the hard way when a pricing update job accidentally hammered a carrier's API and got our IP blocked for 4 hours. Implement token-bucket rate limiting on every outbound connection from day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the carrier simulator first.&lt;/strong&gt; Testing against real SM-DP+ servers is slow and expensive (some carriers charge per profile, even in test mode). A simulator that mimics the GSMA profile generation flow would have accelerated development dramatically. We built one eventually, but it should have been the first thing we wrote.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://media1.giphy.com/media/oGQDwIkFzWyeRdSQl5/giphy.gif" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;media1.giphy.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;em&gt;Looking back at the stack decisions — no regrets&lt;/em&gt;

&lt;h2&gt;
  
  
  The Numbers (So Far)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;190+ countries&lt;/strong&gt; covered through 12 carrier partnerships&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average provisioning time:&lt;/strong&gt; 18 seconds from payment to QR code delivery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure cost:&lt;/strong&gt; ~$400/month on Hetzner and AWS (3 VPS instances, managed PostgreSQL, Redis)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lines of Go:&lt;/strong&gt; ~28,000 across 6 microservices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lines of carrier adapter code:&lt;/strong&gt; ~8,000 (for 12 carriers — that's ~650 lines per carrier on average)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uptime:&lt;/strong&gt; 99.93% over the last 90 days&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Is This Stack Right for You?
&lt;/h2&gt;

&lt;p&gt;If you're building something similar — a platform that needs to talk to external APIs, handle payments, manage state, and scale from zero to thousands of users — Go + PostgreSQL + Redis + gRPC is a fantastic foundation. It's boring technology in the best way: well-understood, well-documented, and unlikely to surprise you at 3 AM.&lt;/p&gt;

&lt;p&gt;If you're building a traditional telecom OSS/BSS with hundreds of existing SOAP integrations and a team of Java developers who've been doing this for 20 years — stick with Java. The best stack is the one your team can operate.&lt;/p&gt;

&lt;p&gt;But if you're starting fresh, building something that didn't exist before, and you want to move fast without accumulating technical debt that'll crush you in year two — Go is the answer. It was for me. Check out &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; to see the platform in action, or read our &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;step-by-step eSIM activation guide&lt;/a&gt; to see how the provisioning flow works from the user's perspective.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of my "building in public" series. I'm documenting the entire journey of building RoamLink from idea to revenue. Follow along if you're into this kind of thing. And if you're building something in the connectivity space, I'd love to hear about your stack choices — drop a comment below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>startup</category>
      <category>go</category>
      <category>buildinginpublic</category>
    </item>
    <item>
      <title>Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 11 Aug 2026 17:57:05 +0000</pubDate>
      <link>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-49af</link>
      <guid>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-49af</guid>
      <description>&lt;p&gt;Six months ago, I sat in a coffee shop in Manila staring at a pile of physical SIM cards I'd collected from a dozen countries. Each one represented a different carrier, a different activation process, and a different headache. That moment crystallized something I'd been thinking about for years: the entire model of physical SIM cards is broken, and eSIM technology is the fix the world has been waiting for.&lt;/p&gt;

&lt;p&gt;This is the story of how we built &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; — a global eSIM platform that now serves travelers in over 200 countries. I'm writing this in the open because I believe the technical decisions behind platforms like ours deserve the same scrutiny as any open-source project. If you're building in the connectivity space, thinking about carrier integrations, or just curious about what happens when you try to replace a 30-year-old technology, this one's for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Physical SIM Cards (And Why It's Finally Over)
&lt;/h2&gt;

&lt;p&gt;Let's be honest about what a physical SIM card actually is: a piece of plastic with a tiny chip that locks you into one carrier's network. It's a distribution nightmare — manufacturing, shipping, retail placement, and activation all add friction. For travelers, it means either paying extortionate roaming fees or hunting down a local SIM shop the moment you land.&lt;/p&gt;

&lt;p&gt;The numbers are staggering. The GSMA estimates that over 5 billion SIM cards are manufactured annually. That's 5 billion pieces of plastic that need to be produced, packaged, shipped, and eventually discarded. The environmental cost alone should make us rethink this model, but the user experience cost is even worse.&lt;/p&gt;

&lt;p&gt;eSIM technology changes everything. An embedded SIM is exactly what it sounds like — a SIM card that's soldered directly onto your device's motherboard, programmable over the air. No plastic. No shipping. No store visits. You land in Tokyo, open an app, tap a few buttons, and you're connected. That's the promise, and it's what we set out to deliver at scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkl2zktnotkiozamv567i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkl2zktnotkiozamv567i.gif" alt="Wireless eSIM technology animation" width="394" height="480"&gt;&lt;/a&gt;&lt;br&gt;
  The shift from physical SIM cards to eSIM is the biggest change in mobile connectivity since the smartphone itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: What Powers a Global eSIM Platform
&lt;/h2&gt;

&lt;p&gt;When we started designing the iWanteSIM backend, we knew we were signing up for a distributed systems challenge. You're not just building a web app — you're building a platform that has to talk to dozens of mobile network operators (MNOs) across different continents, each with their own APIs, authentication schemes, and data formats.&lt;/p&gt;

&lt;p&gt;Here's the stack we landed on, and more importantly, why:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Core: Node.js + PostgreSQL
&lt;/h3&gt;

&lt;p&gt;We chose Node.js for the API layer because eSIM provisioning is fundamentally I/O-bound. When a user purchases a plan, your system needs to talk to the carrier's SM-DP+ (Subscription Manager Data Preparation) server, generate an eSIM profile, and deliver it — all within seconds. Node's event-driven architecture handles these concurrent operations beautifully without the thread-pool overhead you'd get with something like Java Spring.&lt;/p&gt;

&lt;p&gt;PostgreSQL is our source of truth. We track every eSIM profile, every activation, every data session. The relational model maps cleanly to our domain: users have orders, orders have eSIM profiles, profiles have data plans, data plans have usage records. We use JSONB columns sparingly for carrier-specific metadata that doesn't fit a rigid schema — because every carrier has their own quirks, and you can't normalize your way out of that.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Integration Layer: A Carrier Abstraction Pattern
&lt;/h3&gt;

&lt;p&gt;This is where things get interesting. Each carrier partner exposes a different API. Some use GSMA-standard RSP (Remote SIM Provisioning) protocols. Others have REST APIs with OAuth2. A few still use SOAP (yes, in 2026, SOAP is alive and well in telecom).&lt;/p&gt;

&lt;p&gt;We built a carrier abstraction layer that normalizes all of this into a single internal interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Profile Manager&lt;/strong&gt; — handles eSIM profile generation, download, and revocation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Activation Service&lt;/strong&gt; — manages the handshake between device and carrier when a user activates a plan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage Tracker&lt;/strong&gt; — polls carrier APIs for data consumption and enforces plan limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fallback Router&lt;/strong&gt; — if one carrier's API is down, routes provisioning to a backup partner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each carrier gets its own adapter that implements these interfaces. When we onboard a new carrier — say, a provider in Brazil — we write one adapter, test it against their sandbox, and deploy. The rest of the platform doesn't need to know anything changed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0birrt6vkfvgehlexjeo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0birrt6vkfvgehlexjeo.gif" alt="Software developer building code" width="500" height="500"&gt;&lt;/a&gt;&lt;br&gt;
  Building the carrier abstraction layer — one adapter at a time. The key insight: standardize internally, adapt externally.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Design: Why REST Won (And GraphQL Didn't)
&lt;/h2&gt;

&lt;p&gt;We had the GraphQL vs REST debate early on. GraphQL is elegant for client-side flexibility, but eSIM provisioning isn't a read-heavy social feed — it's a transactional pipeline with well-defined operations. A user buys a plan, we provision a profile, they activate it. These are discrete steps, not graph traversals.&lt;/p&gt;

&lt;p&gt;Our public API follows RESTful conventions with a few opinionated choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Idempotency keys on all mutating endpoints.&lt;/strong&gt; When you're dealing with carrier billing, duplicate charges are unacceptable. Every POST/PUT requires an Idempotency-Key header, and we deduplicate at the application layer before touching any downstream system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Webhook-first design.&lt;/strong&gt; eSIM activation isn't instant — it can take 30 seconds to 2 minutes depending on the carrier. Instead of making clients poll, we push events via signed webhooks. Activation started, profile downloaded, plan active — each state change fires a webhook.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting with carrier-aware backpressure.&lt;/strong&gt; Carriers have rate limits too. If a partner tells us "max 50 activations per minute," our API gateway respects that upstream constraint and queues excess requests rather than failing them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API is documented with OpenAPI 3.1, and we generate client SDKs for our mobile apps directly from the spec. This keeps the contract honest — if the spec says a field is required, the generated types enforce it at compile time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Carrier Integrations: The Hardest Part Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;If you're thinking about building in the telecom space, here's the part that will humble you: carrier integrations are not a technical problem. They're a relationship problem.&lt;/p&gt;

&lt;p&gt;Getting an MNO to give you API access for eSIM provisioning involves legal agreements, compliance audits, and months of back-and-forth. Each carrier has different requirements for KYC (Know Your Customer), different data retention policies, and different interpretations of GSMA specifications.&lt;/p&gt;

&lt;p&gt;We learned this the hard way with our first carrier partner in Southeast Asia. We had the integration working in their sandbox within two weeks. Getting production access took four months — not because of technical blockers, but because their legal team wanted to review every line of our privacy policy, our data flow diagrams, and our incident response plan.&lt;/p&gt;

&lt;p&gt;Now we front-load the legal and compliance work. Before we write a single line of integration code, we have our legal team review the carrier's requirements, we prepare a compliance package, and we set expectations internally that "carrier onboarding" means 8-12 weeks, not 2.&lt;/p&gt;

&lt;p&gt;On the technical side, the GSMA's RSP specification (SGP.22 for consumer devices) is the standard we target. It defines how eSIM profiles are created, downloaded, and managed. But here's the reality: every carrier implements it slightly differently. Some add custom fields to the profile metadata. Some require additional authentication steps. Some have different interpretations of error codes. Our adapter pattern handles this, but it means we maintain a growing library of carrier-specific quirks documented in our internal wiki.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coverage: How We Built a 200+ Country Network
&lt;/h2&gt;

&lt;p&gt;One of the most common questions we get is: "How do you offer coverage in 200+ countries?" The answer is a combination of direct carrier partnerships and wholesale agreements.&lt;/p&gt;

&lt;p&gt;We have direct integrations with major MNOs in about 40 countries — these are the carriers where we've built custom adapters and have direct API access. For the remaining 160+ countries, we work through aggregators and wholesale partners who already have relationships with local carriers and provide us with a unified API.&lt;/p&gt;

&lt;p&gt;The trade-off is control vs. speed. Direct integrations give us better pricing, faster provisioning, and more visibility into network status. Wholesale agreements let us expand coverage rapidly without negotiating 160 separate contracts. We're gradually converting wholesale countries to direct partnerships as our volume in each region grows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F17h1hr3q0ep5rfla4xnh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F17h1hr3q0ep5rfla4xnh.gif" alt="Global connectivity network animation" width="480" height="480"&gt;&lt;/a&gt;&lt;br&gt;
  200+ countries, one platform. The real work is making it feel seamless to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pricing Model: Why eSIM Plans Start at $1.00
&lt;/h2&gt;

&lt;p&gt;Traditional roaming charges are predatory. Carriers charge $10-15 per day for international data that costs them pennies to provide. The reason they get away with it is lock-in — most people don't want the hassle of swapping SIM cards.&lt;/p&gt;

&lt;p&gt;eSIM breaks that lock-in. When you can switch carriers in 30 seconds from an app, carriers have to compete on price and quality. Our plans start at $1.00 because the marginal cost of provisioning an eSIM profile is near zero — there's no plastic to manufacture, no retail markup, no shipping. The only real costs are the wholesale data rates we negotiate with carriers and our infrastructure.&lt;/p&gt;

&lt;p&gt;We pass those savings through. A 1GB plan for Europe costs $3.50. A 5GB plan for Asia costs $12.00. Compare that to $10/day roaming from your home carrier, and the math speaks for itself.&lt;/p&gt;

&lt;p&gt;For a deeper look at how eSIM pricing works across different regions, check out our &lt;a href="https://www.iwantesim.com/esim" rel="noopener noreferrer"&gt;eSIM plans page&lt;/a&gt; where we break down every available option.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;Building in public means being honest about the mistakes. Here are three things I'd change if I were starting over:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Start with the compliance layer, not the code.&lt;/strong&gt; We built a beautiful provisioning system before we had carrier agreements in place. We should have secured at least two carrier partnerships first, then built the system around their actual APIs rather than the GSMA ideal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Invest in observability from day one.&lt;/strong&gt; When an eSIM activation fails, you need to know exactly where — was it the carrier API? The profile generation? The user's device? We initially had basic logging and spent too many hours grep-ing through log files. Now we use OpenTelemetry with distributed tracing across every service, and it's saved us countless hours of debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Don't underestimate the device compatibility matrix.&lt;/strong&gt; Not all phones support eSIM the same way. iPhones (XR and newer) are consistent. Android is a fragmented landscape — Samsung, Google Pixel, and newer Xiaomi devices support eSIM, but the implementation details vary. We maintain a &lt;a href="https://www.iwantesim.com/esim-supported-devices" rel="noopener noreferrer"&gt;comprehensive device compatibility list&lt;/a&gt; that we update constantly as new models launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Road Ahead
&lt;/h2&gt;

&lt;p&gt;We're not done. The eSIM market is projected to grow from $9.8 billion in 2024 to over $25 billion by 2030. Every new smartphone sold today is eSIM-capable. Apple removed the physical SIM tray entirely from US iPhones starting with the iPhone 14. The writing is on the wall.&lt;/p&gt;

&lt;p&gt;Our roadmap includes deeper carrier integrations in Africa and South America, a B2B API for travel companies that want to bundle eSIM with flight bookings, and a machine learning model that predicts which plan a user needs based on their travel itinerary — no more guessing whether 1GB or 5GB is enough for a week in Paris.&lt;/p&gt;

&lt;p&gt;If you're a developer interested in the connectivity space, the door is wide open. The incumbents are slow, the technology is standardizing, and travelers are desperate for better options. The stack I've described here — Node.js, PostgreSQL, carrier abstraction patterns, RESTful APIs — is battle-tested and ready for anyone to adopt.&lt;/p&gt;

&lt;p&gt;Physical SIM cards had a good 30-year run. But their time is up. The future of mobile connectivity is embedded, programmable, and global. We're building it. Come join us.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is part of our building-in-public series. Follow along as we share the technical decisions, carrier negotiations, and architecture challenges behind &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;. Have questions about the stack? Drop them in the comments — I'll answer everything I can.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>esim</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards</title>
      <dc:creator>Wae Luxe</dc:creator>
      <pubDate>Tue, 11 Aug 2026 16:39:54 +0000</pubDate>
      <link>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-1l71</link>
      <guid>https://dev.to/time_luxe/building-a-global-esim-platform-why-i-chose-this-stack-over-traditional-sim-cards-1l71</guid>
      <description>&lt;h1&gt;
  
  
  Building a Global eSIM Platform: Why I Chose This Stack Over Traditional SIM Cards
&lt;/h1&gt;

&lt;p&gt;Six months ago, I stared at a pile of plastic SIM cards on my desk and thought: &lt;em&gt;there has to be a better way&lt;/em&gt;. Every traveler knows the ritual — land in a new country, find a kiosk, haggle in a language you barely speak, swap tiny plastic chips, and pray the APN settings work. I'd done it dozens of times across 40+ countries, and every time it felt like 2005.&lt;/p&gt;

&lt;p&gt;Today, I run &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;, a global eSIM platform serving travelers across 200+ countries. No plastic. No kiosks. No APN guesswork. Just tap, install, and connect.&lt;/p&gt;

&lt;p&gt;This is the story of the technical decisions behind it — why I chose the stack I did, how the API architecture works, what carrier integrations actually look like under the hood, and the mistakes I made along the way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffaevp560wb89p6r6fccq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffaevp560wb89p6r6fccq.gif" alt="Coding at desk" width="220" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Physical SIMs (From a Developer's Perspective)
&lt;/h2&gt;

&lt;p&gt;Before I wrote a single line of code, I needed to understand what I was actually replacing. Physical SIM cards aren't just inconvenient for travelers — they're a fundamentally broken distribution model.&lt;/p&gt;

&lt;p&gt;A traditional SIM card is a physical chip that stores your IMSI (International Mobile Subscriber Identity) and authentication keys. When you buy one at an airport, here's what happens behind the scenes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The carrier pre-provisions that SIM with a specific profile&lt;/li&gt;
&lt;li&gt;The SIM gets physically shipped to a retail location&lt;/li&gt;
&lt;li&gt;You buy it, insert it, and your phone authenticates against the carrier's HLR (Home Location Register)&lt;/li&gt;
&lt;li&gt;If everything matches, you get service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problems with this model are architectural, not just logistical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inventory risk&lt;/strong&gt;: Carriers must predict demand per country, per plan type, and physically stock SIMs. Get it wrong and you have dead inventory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Activation friction&lt;/strong&gt;: The average traveler spends 15-45 minutes getting a local SIM working. That's a terrible onboarding experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No remote management&lt;/strong&gt;: Once a physical SIM is provisioned, changing plans or carriers means swapping the chip.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Environmental waste&lt;/strong&gt;: Billions of plastic SIM cards are produced and discarded annually.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;eSIM (embedded SIM) solves all of this at the protocol level. Instead of a physical chip, an eSIM is a secure element soldered directly onto the device's motherboard. It uses the GSMA's Remote SIM Provisioning (RSP) architecture to download carrier profiles over the air.&lt;/p&gt;

&lt;p&gt;The key specification is &lt;strong&gt;GSMA SGP.22&lt;/strong&gt; (for consumer devices), which defines how a device communicates with an SM-DP+ (Subscription Manager Data Preparation) server to securely download and install a profile. This is the protocol I'd be building against.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack Decision: Why Not Just Use an Off-the-Shelf Solution?
&lt;/h2&gt;

&lt;p&gt;When I started researching, I found two paths:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path A&lt;/strong&gt;: Use a white-label eSIM reseller platform. Pay a monthly fee, get a pre-built storefront, and resell their inventory. Zero technical work, but zero differentiation and razor-thin margins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path B&lt;/strong&gt;: Build direct carrier integrations. Negotiate wholesale rates, implement the GSMA specs, and own the entire stack.&lt;/p&gt;

&lt;p&gt;I chose Path B. Here's why.&lt;/p&gt;

&lt;p&gt;White-label platforms abstract away the hard parts — and the margins. When you resell through a middleman, you're competing on price alone. The platform takes 30-50% of every sale, and you have no control over the provisioning flow, the user experience, or the plan configurations.&lt;/p&gt;

&lt;p&gt;Building direct meant I could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Negotiate wholesale rates directly with carriers and MVNOs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design the activation flow exactly how I wanted (spoiler: I wanted it to be one tap)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Own the customer data and relationship&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build features that white-label platforms don't offer (like multi-country plans and real-time usage tracking)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade-off? I'd need to understand telecom protocols that most web developers never touch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: Monolith First, Microservices Later
&lt;/h2&gt;

&lt;p&gt;I'm a pragmatist about architecture. I've seen too many indie projects die because someone tried to build a Kubernetes cluster for 100 users.&lt;/p&gt;

&lt;p&gt;My stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;: Node.js with Express (TypeScript). I know it, it's fast to iterate, and the ecosystem has everything I need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database&lt;/strong&gt;: PostgreSQL. eSIM provisioning is fundamentally transactional — you're dealing with inventory, activations, and payments that must be atomic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Queue&lt;/strong&gt;: BullMQ (Redis-backed). Carrier APIs are slow (2-15 second response times are normal). Every activation goes through a job queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;: Next.js. SSR for SEO (travel keywords are competitive), but client-side for the interactive parts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt;: Vercel for the frontend, a single Hetzner VPS for the backend. Total hosting cost at launch: €35/month.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the high-level flow when a user buys an eSIM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → Checkout → Payment (Stripe) → Webhook → Queue → Carrier API → SM-DP+ → QR Code → User's Phone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical path is the queue. Carrier APIs are not Stripe — they don't respond in 200ms. Some take 5 seconds. Some timeout. Some return XML (yes, in 2026). The queue decouples the user-facing experience from the carrier integration, so the user gets an instant confirmation while provisioning happens asynchronously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Simplified provisioning flow
async function provisionESIM(order: Order): Promise&amp;lt;ESIMProfile&amp;gt; {
  const carrier = await getCarrierForRegion(order.country, order.planType);
  const inventory = await reserveInventory(carrier.id, order.planId);

  const profile = await carrier.api.activateProfile({
    iccid: inventory.iccid,
    planId: order.planId,
    customerRef: order.id,
  });

  await sendQRCodeToUser(order.userId, profile.qrCode);
  await updateInventory(inventory.id, 'activated');

  return profile;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reality is messier. Let me show you what actually happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Carrier Integrations: The Part Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;This is where I almost quit.&lt;/p&gt;

&lt;p&gt;There are roughly three tiers of eSIM carriers you can integrate with:&lt;/p&gt;

&lt;h3&gt;
  
  
  Tier 1: Modern API-First Carriers
&lt;/h3&gt;

&lt;p&gt;These are the newer players — companies built in the last 5 years that understand REST APIs, JSON, and webhooks. Their APIs look like what you'd expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;RESTful endpoints with proper authentication (OAuth2 or API keys)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON request/response bodies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Webhook callbacks for provisioning status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sandbox environments for testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rate limits that are actually documented&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrating with these takes about a week. You read the docs, build a client, test in sandbox, and go live.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tier 2: Legacy Telecom APIs
&lt;/h3&gt;

&lt;p&gt;These are the established carriers that have been around for decades. Their APIs are... different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SOAP/XML endpoints (yes, still)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom authentication schemes involving certificates and IP whitelisting&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response times of 5-15 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error codes that don't match the documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No sandbox — you test in production with test ICCIDs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrating with these takes 2-4 weeks and a lot of patience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tier 3: Email-and-Spreadsheet "APIs"
&lt;/h3&gt;

&lt;p&gt;Some carriers, especially in smaller markets, don't have APIs at all. The "integration" is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You email them a CSV of ICCIDs to activate&lt;/li&gt;
&lt;li&gt;They process it within 24 hours&lt;/li&gt;
&lt;li&gt;They email back a CSV of QR codes&lt;/li&gt;
&lt;li&gt;You manually upload the QR codes to your system&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wish I was joking. For a few countries, this is still the reality. I built an internal tool that parses these CSVs and automates the upload, but it's not real-time and never will be until those carriers modernize.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe4pubpcphu7h0a59zioq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe4pubpcphu7h0a59zioq.gif" alt="Network connectivity visualization" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The API Design: One Interface, Many Backends
&lt;/h2&gt;

&lt;p&gt;The hardest technical challenge was abstracting over these three tiers of carrier quality. I needed a unified interface so the rest of the system didn't care whether a carrier had a REST API or a CSV email workflow.&lt;/p&gt;

&lt;p&gt;I settled on an &lt;strong&gt;Adapter Pattern&lt;/strong&gt; with a shared interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface CarrierAdapter {
  readonly id: string;
  readonly name: string;
  readonly supportedCountries: string[];
  readonly provisioningType: 'realtime' | 'batch' | 'manual';

  getInventory(country: string): Promise&amp;lt;ESIMInventory[]&amp;gt;;
  activateProfile(params: ActivateParams): Promise&amp;lt;ActivationResult&amp;gt;;
  getProfileStatus(iccid: string): Promise&amp;lt;ProfileStatus&amp;gt;;
  deactivateProfile(iccid: string): Promise&amp;lt;void&amp;gt;;
  getUsageData(iccid: string): Promise&amp;lt;UsageData&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each carrier gets its own adapter implementation. The &lt;code&gt;RESTCarrierAdapter&lt;/code&gt; handles Tier 1 carriers with standard HTTP calls. The &lt;code&gt;SOAPCarrierAdapter&lt;/code&gt; wraps XML requests. The &lt;code&gt;CSVCarrierAdapter&lt;/code&gt; queues emails and parses responses.&lt;/p&gt;

&lt;p&gt;The key insight: &lt;strong&gt;the adapter handles retries, timeouts, and error normalization&lt;/strong&gt;. If a carrier returns error code &lt;code&gt;ERR_002&lt;/code&gt; (which means "profile already activated" for one carrier and "invalid ICCID" for another), the adapter normalizes it to a standard &lt;code&gt;ProfileAlreadyActivatedError&lt;/code&gt; or &lt;code&gt;InvalidICCIDError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This normalization layer saved me countless hours of debugging. When a provisioning fails, the system logs a standardized error that I can actually act on, regardless of which carrier generated it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-Time Provisioning: The 30-Second Promise
&lt;/h2&gt;

&lt;p&gt;One of the core UX promises of &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt; is that you get connected within 30 seconds of purchase. Here's how that actually works.&lt;/p&gt;

&lt;p&gt;The GSMA SGP.22 spec defines a flow called the "ES2+ interface" between the eSIM platform operator (that's me) and the SM-DP+ server (the carrier's provisioning server). The flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Download Order&lt;/strong&gt;: I send a &lt;code&gt;DownloadOrder&lt;/code&gt; request to the SM-DP+ with the EID (eSIM identifier) and the profile to install&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile Generation&lt;/strong&gt;: The SM-DP+ generates a unique profile bound to that EID&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Matching ID&lt;/strong&gt;: The SM-DP+ returns a Matching ID and SM-DP+ address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QR Code&lt;/strong&gt;: I encode the Matching ID and SM-DP+ address into a QR code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Scans&lt;/strong&gt;: The user scans the QR code, their device contacts the SM-DP+ directly, and downloads the profile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The critical detail: &lt;strong&gt;I never touch the actual profile data&lt;/strong&gt;. The profile is generated by the carrier's SM-DP+ and downloaded directly by the user's device. My platform only handles the orchestration — requesting the profile, receiving the activation token, and delivering it to the user.&lt;/p&gt;

&lt;p&gt;This is both a security feature (I can't intercept profile data) and a scaling advantage (I don't need to handle large binary payloads).&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Start With Fewer Carriers
&lt;/h3&gt;

&lt;p&gt;I launched with integrations for 8 carriers across 200+ countries. That was too many. Each carrier has its own quirks, and maintaining 8 adapters from day one meant I was spending 60% of my time on carrier-specific bugs instead of building product features.&lt;/p&gt;

&lt;p&gt;If I were starting over, I'd launch with 2-3 carriers covering the top 50 destinations and expand from there.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Invest in Monitoring Earlier
&lt;/h3&gt;

&lt;p&gt;Carrier APIs fail in ways you don't expect. One carrier's API went down for 6 hours and I didn't notice until a customer emailed. Now I have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Health checks that ping each carrier's API every 5 minutes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A dashboard showing provisioning success rates per carrier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated fallback: if Carrier A fails for a country, the system tries Carrier B&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Slack alerts when any carrier's error rate exceeds 5%&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Build the &lt;a href="https://www.iwantesim.com/esim-activation-guide" rel="noopener noreferrer"&gt;eSIM Activation Guide&lt;/a&gt; Sooner
&lt;/h3&gt;

&lt;p&gt;I underestimated how many users would need help with the activation process. Even though eSIM is "just scan a QR code," different phone models have different menu paths. Samsung puts eSIM settings in Connections → SIM Manager. iPhones put it in Settings → Cellular → Add eSIM. Pixel phones have yet another path.&lt;/p&gt;

&lt;p&gt;I eventually built a comprehensive activation guide with screenshots for every major phone model. It reduced support tickets by 40%. I should have built it before launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why eSIM Wins (The Technical Argument)
&lt;/h2&gt;

&lt;p&gt;If you're a developer evaluating whether to build on eSIM vs traditional SIM infrastructure, here's the technical case:&lt;/p&gt;

&lt;p&gt;FactorPhysical SIMeSIM&lt;br&gt;
ProvisioningPhysical manufacturing + shippingOver-the-air, instant&lt;br&gt;
Multi-profileOne profile per SIMUp to 8 profiles stored&lt;br&gt;
Remote managementImpossibleFull OTA lifecycle&lt;br&gt;
SecuritySIM cloning possibleHardware-backed secure element&lt;br&gt;
User experienceInsert, configure APNScan QR, done&lt;br&gt;
EnvironmentalPlastic wasteZero physical waste&lt;/p&gt;

&lt;p&gt;The GSMA estimates that by 2028, over 60% of smartphones shipped will be eSIM-only. Apple already removed the physical SIM tray from US iPhones. The writing is on the wall.&lt;/p&gt;

&lt;p&gt;For developers, this means the addressable market for eSIM services is growing exponentially while the traditional SIM market shrinks. Building on eSIM infrastructure today is like building mobile apps in 2009 — you're early, but the wave is coming.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers (Because Building in Public Means Sharing Real Data)
&lt;/h2&gt;

&lt;p&gt;Some actual metrics from running &lt;a href="https://www.iwantesim.com" rel="noopener noreferrer"&gt;iWanteSIM&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;200+ countries&lt;/strong&gt; covered through 8 carrier partnerships&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Average provisioning time&lt;/strong&gt;: 12 seconds (from purchase to QR code delivery)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Activation success rate&lt;/strong&gt;: 94.7% (the 5.3% failures are mostly unsupported devices or carrier outages)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support ticket rate&lt;/strong&gt;: 3.2% of orders (down from 8% after building the activation guide)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monthly infrastructure cost&lt;/strong&gt;: ~€120 (Hetzner VPS, Vercel Pro, Redis Cloud, monitoring)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest surprise? &lt;strong&gt;Seasonality is real&lt;/strong&gt;. Summer months (June-August) see 3x the order volume of winter months. I didn't build for this initially and had to scramble when the queue started backing up during the first summer peak.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm currently working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-country plans&lt;/strong&gt;: One eSIM that works across multiple countries without switching profiles. Technically challenging because it requires coordinating inventory across carriers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Usage-based pricing&lt;/strong&gt;: Instead of fixed data buckets, pay for what you actually use. Requires real-time usage data from carriers, which not all of them support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;An API for other developers&lt;/strong&gt;: If you're building a travel app, you should be able to sell eSIMs through my platform without dealing with carrier integrations yourself.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Real Lesson
&lt;/h2&gt;

&lt;p&gt;Building an eSIM platform taught me something I didn't expect: &lt;strong&gt;the hardest part of any infrastructure product isn't the technology — it's the integrations&lt;/strong&gt;. Anyone can build a nice checkout flow. The moat is in the carrier relationships, the error handling, the edge cases, and the years of accumulated knowledge about how telecom actually works.&lt;/p&gt;

&lt;p&gt;If you're thinking about building something in the telecom space, my advice is: start with the integrations. Don't build a beautiful frontend first. Get one carrier working end-to-end. Then add another. The product will emerge from the constraints.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fii4qlsag3tgrjt1x0oq4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fii4qlsag3tgrjt1x0oq4.gif" alt="Success celebration" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you worked with telecom APIs or eSIM provisioning? I'd love to hear about your experience — especially the horror stories. Drop a comment below or check out &lt;a href="https://www.iwantesim.com/what-is-an-esim" rel="noopener noreferrer"&gt;what an eSIM actually is&lt;/a&gt; if you're new to the space.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>esim</category>
      <category>api</category>
      <category>telecom</category>
      <category>buildinginpublic</category>
    </item>
  </channel>
</rss>
