<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Matthew O'Riordan's blog]]></title><description><![CDATA[All things realtime, WebSockets, Ably and tech-related.]]></description><link>https://blog.mattheworiordan.com</link><image><url>https://substackcdn.com/image/fetch/$s_!3fsF!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eacf3c0-ef5e-4f3b-af97-e63f52160885_226x226.png</url><title>Matthew O&apos;Riordan&apos;s blog</title><link>https://blog.mattheworiordan.com</link></image><generator>Substack</generator><lastBuildDate>Mon, 06 Apr 2026 19:59:03 GMT</lastBuildDate><atom:link href="https://blog.mattheworiordan.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Matthew O'Riordan]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[mattheworiordan@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[mattheworiordan@substack.com]]></itunes:email><itunes:name><![CDATA[Matthew O'Riordan]]></itunes:name></itunes:owner><itunes:author><![CDATA[Matthew O'Riordan]]></itunes:author><googleplay:owner><![CDATA[mattheworiordan@substack.com]]></googleplay:owner><googleplay:email><![CDATA[mattheworiordan@substack.com]]></googleplay:email><googleplay:author><![CDATA[Matthew O'Riordan]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[I reverse-engineered Apple’s Reminders sync engine. Here’s what I found]]></title><description><![CDATA[How Apple's remindd daemon uses CRDT vector clocks for sync, why no CLI tool supports sections, and the three bugs that took days each to find.]]></description><link>https://blog.mattheworiordan.com/p/i-reverse-engineered-apples-reminders</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/i-reverse-engineered-apples-reminders</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Mon, 06 Apr 2026 10:31:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rI9V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I use Apple Reminders because my family does. Groceries, household chores, dogs, babysitting - all shared lists with my partner and nanny. If it were just me, I&#8217;d probably use something more developer-oriented. But Reminders is the one thing everyone in the house can use without thinking about it, and iCloud sync means changes show up on every device instantly.</p><p>The problem is, I also want to automate it. I&#8217;ve been building a personal automation system that ties together Obsidian, AI agents, and Apple Reminders. I needed to create reminders, assign them to sections, set up recurrence rules, and have it all sync to everyone&#8217;s phones. From the terminal. Programmatically. And increasingly, through AI agents using MCP servers, Claude Code skills, and OpenClaw.</p><p>The existing CLI tools (<a href="https://github.com/steipete/remindctl">remindctl</a>, <a href="https://github.com/keith/reminders-cli">reminders-cli</a>) use Apple&#8217;s EventKit API. They handle basic operations fine. But they can&#8217;t create sections, assign reminders to sections, or reliably sync everything to iCloud. I figured someone had solved this already. Nobody had. So I built <a href="https://github.com/mattheworiordan/remi">remi</a>.</p><h2><strong>It started with sections, but the problems went deeper</strong></h2><p>Sections are the organizational feature Apple added to Reminders in macOS 13. You group reminders under headings like &#8220;Weekly,&#8221; &#8220;Monthly,&#8221; &#8220;Urgent.&#8221; It&#8217;s how I organize my household routine - 40+ recurring tasks across 11 sections.</p><p>EventKit, Apple&#8217;s public API, has zero awareness of sections. No property, no method, no query. This is why every existing CLI tool ignores them.</p><p>But sections were just where the problems started. I also found:</p><ul><li><p><strong>Recurrence rules don&#8217;t persist when added after creation.</strong> You have to add them before the first <code>save()</code> call, or they silently disappear.</p></li><li><p><strong>Date-only reminders get a &#8220;00:00&#8221; time if you set hour/minute to zero.</strong> You have to omit time fields entirely.</p></li><li><p><strong>Subtask relationships aren&#8217;t exposed through EventKit.</strong> The <code>ZPARENTREMINDER</code> column exists in SQLite but Apple never surfaced it publicly.</p></li><li><p><strong>iCloud sync just doesn&#8217;t happen</strong> unless you understand how Apple&#8217;s sync daemon decides what to push.</p></li></ul><p>Each of these individually is annoying. Together, they mean no existing tool can reliably manage Apple Reminders with the full feature set people actually use.</p><h2><strong>Three layers deep into Apple&#8217;s stack</strong></h2><p>Building remi required going through three separate systems, each more undocumented than the last:</p><p><strong>Layer 1: EventKit</strong> handles the basics. Creating reminders, setting due dates, recurrence rules, marking things complete. This is the safe, supported layer. All the other CLI tools stop here.</p><p><strong>Layer 2: ReminderKit</strong> is Apple&#8217;s private framework at <code>/System/Library/PrivateFrameworks/ReminderKit.framework</code>. It exposes section CRUD through Core Data. Since it goes through Core Data properly, section changes sync to iCloud automatically. You access it at runtime via <code>NSClassFromString</code>. It could break with any macOS update. But it&#8217;s the only way to create sections that actually sync.</p><p><strong>Layer 3: SQLite + CRDT token maps</strong> is where things got genuinely interesting. Section membership (assigning a reminder to a section) isn&#8217;t exposed by EventKit OR ReminderKit. The only way to do it is to write directly to Apple&#8217;s Reminders SQLite database. And getting those writes to sync to iCloud required reverse-engineering Apple&#8217;s sync daemon.</p><h2><strong>How remindd actually works</strong></h2><p>Apple&#8217;s <code>remindd</code> daemon manages iCloud sync for Reminders. I expected it to use <code>NSPersistentCloudKitContainer</code>, Apple&#8217;s standard Core Data + CloudKit integration. It doesn&#8217;t.</p><p><code>remindd</code> runs a custom CloudKit sync engine with CRDT-style vector clocks for field-level conflict resolution. Each syncable field on a list record has an entry in a &#8220;resolution token map&#8221; stored in the database:</p><pre><code> {
   &#8220;map&#8221;: {
     &#8220;membershipsOfRemindersInSectionsChecksum&#8221;: {
       &#8220;counter&#8221;: 5,
       &#8220;modificationTime&#8221;: 796647639.739,
       &#8220;replicaID&#8221;: &#8220;C8116DE3-F9C5-4C94-B3FF-1A10D5184298&#8221;
     }
   }
 }</code></pre><p>When <code>remindd</code> prepares a CloudKit push, it compares each field&#8217;s counter against the last-synced state. Fields with incremented counters get included. Fields without changes get skipped.</p><p>Simply writing to the SQLite database does nothing for sync. The counter doesn&#8217;t change, so <code>remindd</code> doesn&#8217;t know anything changed. Your data sits there locally, forever.</p><h2><strong>Three bugs that took days each to find</strong></h2><p><strong>Bug 1: Token map entries need to be nested inside a &#8220;map&#8221; key with a replicaID.</strong> I initially wrote the membership counter at the top level of the JSON. <code>remindd</code> ignored it completely. Apple nests all token map entries inside a <code>"map"</code> key, and each entry needs a UUID called <code>replicaID</code>. Neither of these is documented anywhere. I found it by comparing my database entries against a list where sections were syncing correctly via the Reminders UI.</p><p><strong>Bug 2: The SQLite connection must be closed before triggering sync.</strong> After writing membership data, I trigger a sync cycle by making a trivial EventKit edit. But if the database connection is still open, the WAL (Write-Ahead Log) hasn&#8217;t been checkpointed, and <code>remindd</code> reads stale data. My changes were being written correctly but <code>remindd</code> was reading the pre-change state. Adding a <code>sqlite3_close()</code> followed by a 500ms delay before the sync trigger fixed it.</p><p><strong>Bug 3: Editing a reminder doesn&#8217;t trigger a list-level push.</strong> This was the hardest. The standard technique for triggering sync is to toggle a trailing space on a reminder&#8217;s notes field. This triggers <code>remindd</code> to push the reminder record. But membership data lives on the <em>list</em> record, not the reminder record. <code>remindd</code> wasn&#8217;t checking the list&#8217;s token map when only a reminder changed.</p><p>The fix: create and immediately delete a temporary reminder. This forces <code>remindd</code> to update <code>reminderIDsMergeableOrdering</code> on the list record, which triggers a full list-level CloudKit push that includes the membership data.</p><p>Each of these took 1-2 days to diagnose. The symptoms were always the same: everything looked correct locally, but changes never appeared on other devices. No error messages. No crash. Just silence.</p><h2><strong>The result</strong></h2><p><a href="https://github.com/mattheworiordan/remi">remi</a> wraps all of this behind a simple CLI:</p><pre><code> remi create-section &#8220;Groceries&#8221; &#8220;Produce&#8221;
 remi add &#8220;Groceries&#8221; &#8220;Bananas&#8221; --section &#8220;Produce&#8221;
 remi move &#8220;Groceries&#8221; &#8220;Bananas&#8221; --to-section &#8220;Dairy&#8221;
 remi today
 remi overdue</code></pre><p>Underneath: EventKit, ReminderKit, SQLite, SHA-512 checksums, CRDT vector clocks, WAL checkpointing, and temporary reminder sync triggers. All syncing to every Apple device via iCloud.</p><p>It also supports natural language dates (<code>--due "next tuesday"</code>), recurrence rules (<code>--repeat "every 2 weeks"</code>), fuzzy name matching (<code>remi list shopping</code> finds &#8220;Groceries / Shopping List&#8221;), JSON output for automation, and an MCP server for AI agent integration (<code>remi --mcp</code>).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rI9V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rI9V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 424w, https://substackcdn.com/image/fetch/$s_!rI9V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 848w, https://substackcdn.com/image/fetch/$s_!rI9V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 1272w, https://substackcdn.com/image/fetch/$s_!rI9V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rI9V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png" width="1456" height="465" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:465,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82244,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.mattheworiordan.com/i/193336535?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rI9V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 424w, https://substackcdn.com/image/fetch/$s_!rI9V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 848w, https://substackcdn.com/image/fetch/$s_!rI9V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 1272w, https://substackcdn.com/image/fetch/$s_!rI9V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66fc3d3e-7926-429d-b616-9f869465c1c4_1898x606.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Why I&#8217;m sharing this</strong></h2><p>I built remi because I needed it for my family&#8217;s shared reminders. But I think other people will want this too.</p><p>If you&#8217;re using AI agents (Claude, OpenClaw, or any MCP-compatible tool) and want them to manage your reminders properly, including sections, there hasn&#8217;t been a way to do that. remi ships as an MCP server, a Claude Code plugin, a skills.sh skill, and an OpenClaw skill. Install it once and your agents can manage your reminders.</p><p>If you&#8217;re a developer who lives in the terminal and wants a proper Reminders CLI, the existing tools are good at what they do but they stop at EventKit&#8217;s boundaries. remi goes further.</p><p>And if you&#8217;re building your own tools that interact with Apple Reminders, the <a href="https://github.com/mattheworiordan/remi/blob/main/docs/APPLE_REMINDERS_INTERNALS.md">internals document</a> will save you days. The token map structure, the sync trigger mechanism, the ReminderKit bridge pattern - none of this is documented by Apple.</p><p><a href="https://github.com/mattheworiordan/remi">remi is on GitHub</a>. Install with <code>brew tap mattheworiordan/tap &amp;&amp; brew install remi</code>. I&#8217;d love feedback.</p><div><hr></div><p><em>remi is available via <a href="https://github.com/mattheworiordan/homebrew-tap">Homebrew</a>, <a href="https://www.npmjs.com/package/@mattheworiordan/remi">npm</a>, <a href="https://github.com/mattheworiordan/remi">Claude Code plugin</a>, <a href="https://skills.sh">skills.sh</a>, <a href="https://clawhub.com">OpenClaw</a>, and the <a href="https://registry.modelcontextprotocol.io">MCP Registry</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Transparent pricing that rewards success, not penalizes it"]]></title><description><![CDATA[Why realtime platforms need pricing models that align with customer value, and how competitors optimize for &#8220;simple&#8221; inefficient models]]></description><link>https://blog.mattheworiordan.com/p/transparent-pricing-that-rewards</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/transparent-pricing-that-rewards</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Wed, 05 Nov 2025 23:12:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ssv3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the last week I&#8217;ve shared how Ably&#8217;s architecture enables things competitors thought were impossible: <a href="https://blog.mattheworiordan.com/p/the-impossible-architecture-how-ably">zero impact during a major AWS outage</a>, <a href="https://blog.mattheworiordan.com/p/scaling-websockets-to-billions-of">scaling WebSockets to billions of connections globally</a>, <a href="https://blog.mattheworiordan.com/p/stream-integrity-in-globally">stream integrity guarantees at global internet scale</a>.</p><p>Today: <strong>Pricing models that reward customer success instead of penalizing it.</strong></p><div><hr></div><h2><strong>Why pricing models matter</strong></h2><p>When we started Ably, we had a clear motive: deliver the best value, fairest pricing, and maximum transparency so businesses could succeed with our platform. That&#8217;s why we started the business in the first place.</p><p>Your pricing model either aligns with customer success or creates friction. It either rewards growth or penalizes it. And in realtime infrastructure, where usage patterns can vary dramatically, this matters more than almost any other SaaS category.</p><div><hr></div><h2><strong>Three approaches to pricing</strong></h2><p>The industry has evolved three primary pricing models for realtime platforms. Let&#8217;s compare them directly.</p><h3><strong>Package-based Pricing (used by Pusher)</strong></h3><p><strong>How it works</strong>: Fixed tiers that bundle multiple dimensions together (connections + messages + channels).</p><p><strong>Example</strong>: Startup plan ($49/month) = 1M messages/day + 500 concurrent connections [1]<br><br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ssv3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ssv3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 424w, https://substackcdn.com/image/fetch/$s_!Ssv3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 848w, https://substackcdn.com/image/fetch/$s_!Ssv3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 1272w, https://substackcdn.com/image/fetch/$s_!Ssv3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ssv3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png" width="1456" height="628" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:628,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ssv3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 424w, https://substackcdn.com/image/fetch/$s_!Ssv3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 848w, https://substackcdn.com/image/fetch/$s_!Ssv3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 1272w, https://substackcdn.com/image/fetch/$s_!Ssv3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b6528e-e7de-436c-90e0-81936e51eccf_2048x884.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>What happens when limits are exceeded</strong>: According to Pusher&#8217;s own documentation, when you hit message limits, you cannot publish any more events and get a 403 &#8220;over quota&#8221; error. When you hit connection limits, new connections are rejected with &#8220;over quota&#8221; errors. Resolution: Must upgrade to next plan tier. [2]</p><p><strong>The problem</strong>: If you exceed ANY single dimension, you must upgrade your ENTIRE package&#8212;even if you&#8217;re nowhere near limits on other metrics.</p><p><strong>Real customer experience</strong> (from Trustpilot review):</p><blockquote><p>&#8220;Pusher doubled our plan because we had an increased traffic for 3 days in April&#8221; and &#8220;now they refuse to decrease our plan back to what it was, so we&#8217;re paying double for no reason&#8221; [3]</p></blockquote><p><strong>Pusher themselves acknowledge this problem</strong> in their blog post &#8220;Making it easier to outgrow usage limits&#8221;:</p><blockquote><p>&#8220;Hitting your hard limits can be a frustrating experience when it happens unexpectedly&#8221; [4]</p></blockquote><p>They built emergency features (3x overage allowance, automatic upgrades) specifically because customers were complaining about service disruptions.</p><h3><strong>MAU-based pricing (PubNub)</strong></h3><p><strong>How it works</strong>: &#8220;Simple&#8221; Monthly Active User pricing that appears straightforward on the surface.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1xxV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1xxV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 424w, https://substackcdn.com/image/fetch/$s_!1xxV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 848w, https://substackcdn.com/image/fetch/$s_!1xxV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 1272w, https://substackcdn.com/image/fetch/$s_!1xxV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1xxV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png" width="1456" height="621" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:621,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1xxV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 424w, https://substackcdn.com/image/fetch/$s_!1xxV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 848w, https://substackcdn.com/image/fetch/$s_!1xxV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 1272w, https://substackcdn.com/image/fetch/$s_!1xxV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b420f3e-2ef6-475f-a717-29a8fa0fc8d2_2048x874.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>The marketing</strong>: &#8220;Simple, Transparent Pricing... based on one simple metric: Monthly Active Users. No hidden fees, no surprises.&#8221; [5]</p><p><strong>The reality</strong>: Transaction-based metering underneath with 60+ transaction types, 2KB billing buckets, and fan-out multipliers. [6]</p><p><strong>This trap means customers either</strong>:</p><ul><li><p>Overpay because they&#8217;re not using their per user quota of transactions [7]</p></li><li><p>End up surprised by the &#8220;hidden&#8221; overage charges for transactions they were told they wouldn&#8217;t be charged for [8]</p></li></ul><p><strong>Real developer experience</strong> (Jayson Lindsley&#8217;s case study):</p><ul><li><p>Told PubNub upfront he needed 3,000 active users</p></li><li><p>PubNub response: &#8220;Bundled transactions should be enough&#8221;</p></li><li><p>Result: Nearly $3,000 in unexpected overage charges</p></li><li><p>Nearly half from single operation (getMembers()) failing and retrying</p></li><li><p>Conclusion: &#8220;GetStream pays for itself - even at a higher base price&#8221;</p></li><li><p>He migrated away [8]</p></li></ul><h3><strong>Consumption-based pricing (Ably, AWS, Stripe)</strong></h3><p><strong>How it works</strong>: Pay for the resources you actually consume, measured in units that reflect value delivered.</p><p><strong>At Ably</strong>: 3 dimensions:</p><ul><li><p><strong>Messages</strong>: The core value - the data moving between devices/people, which is what users come to Ably for.</p></li><li><p><strong>Connection minutes</strong>: The amount of time devices are connected.</p></li><li><p><strong>Channel minutes</strong>: The amount of time channels, used as logical streams of data, are active.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wj9g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wj9g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 424w, https://substackcdn.com/image/fetch/$s_!Wj9g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 848w, https://substackcdn.com/image/fetch/$s_!Wj9g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 1272w, https://substackcdn.com/image/fetch/$s_!Wj9g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wj9g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png" width="1456" height="592" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce63a207-4294-4267-890e-95323e057604_2048x832.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:592,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wj9g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 424w, https://substackcdn.com/image/fetch/$s_!Wj9g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 848w, https://substackcdn.com/image/fetch/$s_!Wj9g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 1272w, https://substackcdn.com/image/fetch/$s_!Wj9g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce63a207-4294-4267-890e-95323e057604_2048x832.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Why these dimensions</strong>: ~90% of our consumption revenue comes from messages because that&#8217;s where the value lies. If you&#8217;re delivering a game, every user move is a message. If it&#8217;s sports, every score update is a message. If it&#8217;s education, every interaction is a message. The value is in the messages, so that&#8217;s the primary billing dimension. In the same way that bandwidth is the primary billing dimension for CDNs.</p><p><strong>No hidden complexity</strong>:</p><ul><li><p>No transaction-type classifications (every update is simply a message)</p></li><li><p>No bundling that forces over-provisioning</p></li><li><p>Decoupled metrics you can optimize costs independently</p></li></ul><p><strong>AWS validates this model</strong>: The most successful cloud company in the world doesn&#8217;t bundle compute, bandwidth, storage, and observability into a single EC2 package. They charge separately for each resource because that&#8217;s what aligns with customer value and enables cost optimization.</p><div><hr></div><h2><strong>Ably&#8217;s transparent approach</strong></h2><p><strong>Full disclosure</strong>: We also offer MAU pricing. Some customers prefer to budget that way.</p><p><strong>But here&#8217;s what we can tell you with certainty</strong>: Almost every customer, once they understand both models, adopts consumption-based pricing because it&#8217;s superior. We don&#8217;t force that choice&#8212;customers decide. But we&#8217;re transparent about why most of our customers choose consumption-based.</p><p><strong>The reason is simple mathematics</strong>:</p><p>With MAU, you&#8217;re either:</p><ul><li><p><strong>Scenario 1</strong>: Quiet month &#8594; Transaction quotas unused &#8594; You overpaid for capacity</p></li><li><p><strong>Scenario 2</strong>: Successful day &#8594; Monthly user count climbs &#8594; Surprisingly high bill because that one successful day cost you a month of usage</p></li><li><p><strong>Scenario 3</strong>: Busy users &#8594; Transaction quota exceeded &#8594; Your budgeted MAU cost goes out the window as you pay overages for additional transactions</p></li></ul><p>You can never match perfectly &#8594; You&#8217;re always in Scenario 1, 2 or 3</p><p>With consumption pricing: Quiet day = low cost. Busy day = pay for that day. Costs track actual usage patterns.</p><p><strong>Customer optionality</strong>: We&#8217;re not here to tell customers they&#8217;re wrong about how they want to buy. But we ensure anyone who chooses MAU can switch to consumption-based at any point. And in practice, they do&#8212;because once you understand your consumption patterns, paying for what you use versus what you might use is always more efficient.</p><div><hr></div><h2><strong>Transparency Makes Better Decisions</strong></h2><p>We&#8217;re not claiming our model is perfect for everyone. We&#8217;re claiming it&#8217;s transparent.</p><p>You can:</p><ul><li><p>See exactly what you&#8217;re paying for</p></li><li><p>Optimize costs per dimension independently</p></li><li><p>Predict costs based on actual usage patterns</p></li><li><p>Never get penalized for successful days or events</p></li></ul><p><strong>That&#8217;s not impossible. That&#8217;s just fair business.</strong></p><div><hr></div><h2><strong>Next Post</strong></h2><p>Coming next week: Something you wouldn&#8217;t expect from a company in our position.</p><p>Putting our money where our mouth is on transparency and competition.</p><p>See you then.</p><p><strong>Matthew O&#8217;Riordan<br></strong>Founder &amp; CEO, Ably</p><div><hr></div><h2><strong>References</strong></h2><p>[1] <a href="https://pusher.com/channels/pricing/">Pusher Channels Pricing</a></p><p>[2] <a href="https://docs.bird.com/pusher/channels/channels/limits/what-happens-when-i-hit-my-channels-plan-limits">Pusher Documentation: What happens when I hit my Channels plan limits</a></p><p>[3] <a href="https://www.trustpilot.com/review/pusher.com">Pusher Customer Review - Trustpilot</a></p><p>[4] <a href="https://blog.pusher.com/making-it-easier-to-outgrow-usage-limits-in-your-channels-plan/">Pusher Blog: Making it easier to outgrow usage limits in your Channels plan</a></p><p>[5] <a href="https://www.pubnub.com/pricing/">PubNub Pricing Page</a></p><p>[6] <a href="https://www.pubnub.com/pricing/transaction-classification/">PubNub Transaction Classification (60+ types, 2KB buckets)</a></p><p>[7] <a href="https://ably.com/blog/consumption-based-pricing">The true cost of MAU<br><br></a>[8] <a href="https://jaysonlindsley.dev/blog/pubnub-chat/">Jayson Lindsley: PubNub Chat Case Study ($3K overages)</a></p><p>[9] <a href="https://ably.com/blog/consumption-based-pricing">Ably Blog: Why Consumption-Based Pricing</a></p>]]></content:encoded></item><item><title><![CDATA[Stream integrity in globally distributed systems: Why most platforms can't guarantee it]]></title><description><![CDATA[How Ably provides message ordering and exactly-once delivery at global scale&#8212;and why this combination was considered impossible]]></description><link>https://blog.mattheworiordan.com/p/stream-integrity-in-globally-distributed</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/stream-integrity-in-globally-distributed</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Mon, 03 Nov 2025 19:05:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1Zy4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When <a href="https://www.linkedin.com/feed/update/urn:li:activity:7389423383484203009/">a competitor called our AWS outage results &#8220;impossible,&#8221;</a> it made me realise I need to talk more about the things we&#8217;ve achieved here at Ably, that are supposedly impossible.</p><p><strong>First</strong>, we talked about <a href="https://blog.mattheworiordan.com/p/the-impossible-architecture-how-ably">maintaining zero impact during a significant AWS outage</a>. All while PubNub experienced 10+ hours of degraded service.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mattheworiordan.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Matthew O'Riordan's blog! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Then</strong>, we covered <a href="https://blog.mattheworiordan.com/p/scaling-websockets-to-billions-of">scaling WebSockets to billions of connections globally</a>. Highlighting the achievements of Socket.io, Pusher, and PubNub.</p><p><strong>In this post</strong>: Another impossible thing by <a href="https://ably.com">Ably</a>. Guaranteeing stream integrity in a globally distributed system.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Zy4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Zy4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 424w, https://substackcdn.com/image/fetch/$s_!1Zy4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 848w, https://substackcdn.com/image/fetch/$s_!1Zy4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 1272w, https://substackcdn.com/image/fetch/$s_!1Zy4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Zy4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png" width="1456" height="706" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:706,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1Zy4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 424w, https://substackcdn.com/image/fetch/$s_!1Zy4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 848w, https://substackcdn.com/image/fetch/$s_!1Zy4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 1272w, https://substackcdn.com/image/fetch/$s_!1Zy4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10748d6-ee13-442d-8f16-69acebe2db96_1600x776.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>What is stream integrity?</strong></h2><p>When developers build realtime applications, they need confidence that:</p><ol><li><p><strong>Messages arrive in order</strong> (sequencing matters)</p></li><li><p><strong>Messages arrive exactly once</strong> (no duplicates)</p></li><li><p><strong>Messages don&#8217;t get lost</strong> (even during network interruptions)</p></li></ol><p>These aren&#8217;t &#8220;nice to have&#8221; features. They&#8217;re fundamental for building reliable realtime applications.</p><p><strong>Examples where ordering matters:</strong></p><ul><li><p><strong>Chat</strong>: Message threading, reactions to specific messages</p></li><li><p><strong>Streaming AI</strong>: OpenAI, Anthropic, Gemini APIs send token deltas&#8212;out-of-order = garbled responses</p></li><li><p><strong>Collaborative apps</strong>: Delta updates without CRDTs require strict ordering to prevent divergence</p></li><li><p><strong>Financial systems</strong>: Price updates, transaction sequences</p></li><li><p><strong>Gaming</strong>: Command sequences determine state</p></li></ul><p><strong>The developer shouldn&#8217;t have to think about this.</strong> Just like TCP/IP guarantees packet ordering, a realtime platform should guarantee message ordering so you focus on building features, not reliability infrastructure.</p><div><hr></div><h2><strong>Standing on the shoulders of the early pioneers</strong></h2><p>When we started building Ably, we learned from the realtime platforms that came before us:</p><p><strong>Socket.io</strong> (by Guillermo Rauch, now CEO of Vercel): Pioneered elegant WebSocket APIs that made realtime accessible to mainstream developers.</p><p><strong>Pusher</strong>: Proved that managed platforms could eliminate DevOps burden, scale WebSocket infrastructure and do this delightfully for developers.</p><p><strong>PubNub</strong>: Demonstrated ambition for global-scale realtime messaging across many points of presence.</p><p>Each achieved something remarkable. But each also made architectural trade-offs that limit their ability to provide stream integrity guarantees.</p><div><hr></div><h2><strong>Why they can&#8217;t guarantee ordering</strong></h2><h3><strong>Socket.io: clustering introduces race conditions</strong></h3><p>Socket.io is a brilliant open-source library designed for self-hosting. Not as a managed platform.</p><p><strong>The constraint</strong>: Beyond ~10K-30K connections per instance, you need to cluster multiple servers using Redis. When messages flow through Redis Pub/Sub across instances, race conditions emerge</p><p><strong>Result</strong>: <a href="http://socket.io">Socket.io</a> has no ordering guarantees.</p><p><strong>From creator Guillermo Rauch</strong> (<a href="https://softwareengineeringdaily.com/2016/03/03/socket-io-and-realtime-applications-with-guillermo-rauch/">Software Engineering Daily</a>):</p><blockquote><p>&#8220;I suffered from that quite a bit with Socket.io... there was only so much I could do to transfer the best practices of how to scale it at a massive concurrency. I could write a readme, but that&#8217;s as far as open source can typically go.&#8221;</p></blockquote><p><strong>Provides</strong>: Elegant WebSocket API, flexibility, open source.<br><strong>Doesn&#8217;t provide</strong>: Ordering guarantees at scale, managed clustering, geographic distribution.</p><div><hr></div><h3><strong>Pusher: parallel processing sacrifices ordering</strong></h3><p>Pusher uses native WebSocket protocol (unlike PubNub) and provides managed infrastructure - both positive.</p><p><strong>The constraint</strong>: Each app lives in a single cluster. Within that cluster, messages are processed in parallel for throughput.</p><p><strong>From Pusher&#8217;s documentation</strong> (<a href="https://docs.bird.com/pusher/channels/channels/events/why-dont-channels-events-arrive-in-order">&#8220;Why Don&#8217;t Channels Events Arrive In Order?&#8221;</a>):</p><blockquote><p>&#8220;Messages are processed by many machines in parallel on our backend.&#8221;</p></blockquote><p><strong>Result</strong>: Pusher has no ordering guarantee.</p><p><strong>Their recommended workaround</strong>: Add sequence numbers, buffer messages, sort client-side, handle gaps. <strong>You&#8217;ve built a reliability layer on top of the platform.</strong></p><p><strong>Provides</strong>: Native WebSockets, managed infrastructure, zero operations.<br><strong>Doesn&#8217;t provide</strong>: Ordering guarantees, multi-region per app, connection state recovery.</p><div><hr></div><h3><strong>PubNub: Stateless HTTP can&#8217;t guarantee sequence</strong></h3><p>As covered in <a href="https://blog.mattheworiordan.com/p/scaling-websockets-to-billions-of">my previous post, Scaling Websockets to Billions of Connections Globally</a>, PubNub uses HTTP long-polling (280-310s timeouts) instead of WebSockets.</p><p><strong>From PubNub&#8217;s support docs</strong> (<a href="https://support.pubnub.com/hc/en-us/articles/360051494392-Does-PubNub-guarantee-the-order-of-messages">&#8220;Does PubNub guarantee the order of messages?&#8221;</a>):</p><blockquote><p><strong>&#8220;No. If your application requires strict ordering, we recommend you add a sequence field to the message payload and order by it.&#8221;</strong></p></blockquote><p><strong>The reason</strong>: HTTP long-polling is stateless. Each message is an independent HTTP request. Concurrent requests can complete in different orders.</p><p><strong>On delivery</strong>: &#8220;PubNub is not a guaranteed message delivery service.&#8221;</p><p><strong>On recovery</strong>: &#8220;The default message queue size is 100 messages. Publishing over 100 messages in the window of the subscribe reconnect time inevitably results in older messages overflowing the queue and getting discarded.&#8221;</p><p><strong>Translation</strong>: Disconnect during high volume = permanent message loss.</p><p><strong>Result</strong>: PubNub has no ordering guarantee</p><p><strong>Provides</strong>: Global distribution (15+ points of presence), managed infrastructure.<br><strong>Doesn&#8217;t provide</strong>: Ordering guarantees, WebSocket protocol, reliable delivery beyond 100-message queue.</p><div><hr></div><h2><strong>The Pattern: Architectural trade-offs</strong></h2><p>Each platform made conscious design choices:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WexB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WexB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 424w, https://substackcdn.com/image/fetch/$s_!WexB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 848w, https://substackcdn.com/image/fetch/$s_!WexB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 1272w, https://substackcdn.com/image/fetch/$s_!WexB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WexB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png" width="1456" height="585" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:585,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:152540,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.mattheworiordan.com/i/177916149?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WexB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 424w, https://substackcdn.com/image/fetch/$s_!WexB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 848w, https://substackcdn.com/image/fetch/$s_!WexB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 1272w, https://substackcdn.com/image/fetch/$s_!WexB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3165f30-84fe-408b-9e2c-e1824ef1526a_1632x656.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>These aren&#8217;t failures</strong>. They&#8217;re architectural decisions that made sense for different goals. But they create a gap: <strong>What if you need global distribution AND stream integrity guarantees?</strong></p><div><hr></div><h2><strong>How Ably achieves both</strong></h2><p>When we built <a href="https://ably.com">Ably</a>, we asked: Could we provide stream integrity guarantees in a <strong>globally distributed</strong> system? Not single-region. Not single-server. But across many globally distributed datacenters with sub-40ms global latency?</p><p><strong>The answer: Yes. But it required building distributed infrastructure from the ground up with stream integrity as a first-class requirement.</strong></p><h3><strong>Our Guarantees</strong></h3><p><strong>1. Message Ordering</strong></p><p>Messages from any publisher over a single connection are delivered to all subscribers in the same order.</p><p><strong>How it works</strong>: Each message gets a unique serial number at the time of publication. These serial numbers ensure subscribers see messages from that publisher in the correct sequence. Even across regions.</p><p>We achieve this through WebSocket&#8217;s persistent connection property plus sequential message processing. And we do it while maintaining <strong>6.5ms message delivery latency within a region</strong>- proving that ordering guarantees don&#8217;t require sacrificing performance.</p><p><a href="https://ably.com/blog/data-integrity-in-ably-pub-sub">Read more: Data Integrity in Ably Pub/Sub</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GQis!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GQis!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 424w, https://substackcdn.com/image/fetch/$s_!GQis!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 848w, https://substackcdn.com/image/fetch/$s_!GQis!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 1272w, https://substackcdn.com/image/fetch/$s_!GQis!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GQis!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png" width="1456" height="497" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:497,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GQis!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 424w, https://substackcdn.com/image/fetch/$s_!GQis!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 848w, https://substackcdn.com/image/fetch/$s_!GQis!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 1272w, https://substackcdn.com/image/fetch/$s_!GQis!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40757d1d-da35-480a-88d5-265320dd2f9c_1600x546.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>2. Exactly-once delivery</strong></p><p>Once we acknowledge receipt of a message, we guarantee it will be delivered exactly once. No duplicates.</p><p><strong>How it works</strong>: Idempotent publishing with unique message IDs, plus clients resume with a serial number. That serial number tells us exactly where the client left off in the stream, so even if you lose connection, you resume from precisely where you left off - guaranteeing you never get duplicates.</p><p>We chose this model (client tracking position via serial number) instead of server tracking client position because otherwise you can&#8217;t provide guaranteed ordering in a distributed system.</p><p><a href="https://ably.com/blog/achieving-exactly-once-message-processing-with-ably">Read more: Achieving Exactly-Once Delivery</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UK5n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UK5n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 424w, https://substackcdn.com/image/fetch/$s_!UK5n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 848w, https://substackcdn.com/image/fetch/$s_!UK5n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 1272w, https://substackcdn.com/image/fetch/$s_!UK5n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UK5n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png" width="1456" height="722" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:722,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UK5n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 424w, https://substackcdn.com/image/fetch/$s_!UK5n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 848w, https://substackcdn.com/image/fetch/$s_!UK5n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 1272w, https://substackcdn.com/image/fetch/$s_!UK5n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37acad17-9934-45d0-8706-12caf1cf3bde_1600x793.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>3. Connection state recovery</strong></p><p>If a client disconnects briefly (within 2 minutes), we automatically resume with preserved state and zero message loss.</p><p>For longer disconnections, our <a href="https://ably.com/docs/storage-history/history#historical-order">History API</a> extends beyond that window, allowing clients to catch up on any duration of missed messages.</p><p><strong>No manual re-subscription. No message gap detection. No custom recovery logic.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HXoF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HXoF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 424w, https://substackcdn.com/image/fetch/$s_!HXoF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 848w, https://substackcdn.com/image/fetch/$s_!HXoF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 1272w, https://substackcdn.com/image/fetch/$s_!HXoF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HXoF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png" width="1456" height="1127" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1127,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HXoF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 424w, https://substackcdn.com/image/fetch/$s_!HXoF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 848w, https://substackcdn.com/image/fetch/$s_!HXoF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 1272w, https://substackcdn.com/image/fetch/$s_!HXoF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c1a0c8b-417d-49d1-a078-7185a1760f7d_1600x1238.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>These guarantees are in our SLA. They&#8217;re quantified in our <a href="https://ably.com/four-pillars-of-dependability">Four Pillars of Dependability</a>. They&#8217;re not marketing. They&#8217;re engineering commitments.</strong></p><div><hr></div><h2><strong>The global ordering nuance</strong></h2><p><strong>An important technical point</strong>: While it&#8217;s technically possible to enforce a single global ordering of all messages across all publishers, doing so would fundamentally compromise the low-latency, fault-tolerant distributed system that realtime applications require.</p><p><strong>Example</strong>: Publisher A in the US and Publisher B in Asia both send messages simultaneously. If we enforced global ordering, messages from nearby regions would be held back awaiting messages from distant regions, adding significant latency to all messages globally. Instead, a subscriber in Europe receives each message with minimal latency, with the tradeoff being that network physics determines which arrives first, not some artificial global sequence.</p><p><strong>What we DO guarantee</strong>: Every subscriber sees messages from each publisher (using a transport that supports ordering, such as WebSockets) in the same order. This is &#8220;causal consistency per client&#8221; and it&#8217;s what actually matters for real-world applications.</p><p><strong>Why this solves real problems</strong>: Developers need confidence that each participant&#8217;s messages maintain order. Chat from one user stays sequential. Token deltas from one AI stream arrive in sequence. Price updates from one exchange remain ordered.</p><p><strong>The alternative</strong> (single global coordination point) would:</p><ul><li><p>Add latency to every message globally</p></li><li><p>Create a single point of coordination and congestion</p></li><li><p>Sacrifice geographic distribution benefits</p></li><li><p>Introduce a critical failure point</p></li><li><p>Not solve any real-world use case we&#8217;ve encountered</p></li></ul><p><strong>Our approach</strong>: Guarantee ordering from each publisher while optimizing for low latency through regional independence.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!u3ig!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!u3ig!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 424w, https://substackcdn.com/image/fetch/$s_!u3ig!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 848w, https://substackcdn.com/image/fetch/$s_!u3ig!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!u3ig!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!u3ig!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png" width="1456" height="1528" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1528,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!u3ig!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 424w, https://substackcdn.com/image/fetch/$s_!u3ig!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 848w, https://substackcdn.com/image/fetch/$s_!u3ig!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!u3ig!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7444a48-4802-4c96-830c-0d2ca901ec59_1525x1600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://ably.com/blog/chat-architecture-reliable-message-ordering">Read more: Chat Architecture for Reliable Message Ordering</a></p><div><hr></div><h2><strong>Making the impossible possible at global scale</strong></h2><p>Providing these guarantees in a single datacenter is achievable, but hard. Providing them across <strong>11 globally distributed datacenters with active-active replication</strong>? That takes engineering at its finest &#8212; and exactly the kind of challenge we thrive on.</p><p>As mentioned in <a href="https://blog.mattheworiordan.com/p/the-impossible-architecture-how-ably">my post about the AWS outage</a>, we operate many datacenters globally including two in US-East alone.</p><p><strong>The engineering required</strong> to make this work includes:</p><ul><li><p>Persistent WebSocket connections</p></li><li><p>Regional message sequencing with serial numbers</p></li><li><p>Cross-region replication with ordering preservation</p></li><li><p>Connection state management across failover</p></li><li><p>Idempotency tracking across distributed nodes</p></li><li><p>2-minute recovery windows with queued messages</p></li></ul><p><strong>This is not impossible. It&#8217;s just crazy difficult and expensive engineering work that we chose to do.</strong></p><p>Developers shouldn&#8217;t have to implement reliability infrastructure. They should assume these basics - even though they&#8217;re extremely difficult - are in place.</p><p>Just like TCP/IP lets you operate at a higher level, realtime infrastructure should let you focus on features, not sequence numbers and deduplication.</p><div><hr></div><h2><strong>What&#8217;s coming Wednesday</strong></h2><p>Today we talked about stream integrity guarantees that most platforms can&#8217;t provide.</p><p><strong>Wednesday&#8217;s topic</strong>: Pricing that rewards success, not penalizes it (impossible? No)</p><p>MAU models and bundled pricing ultimately result in billing surprises or inefficient spending. We&#8217;ll talk through why transaction-based transparency matters and how we approach pricing that aligns with customer success.</p><p>See you Wednesday.</p><p><strong>Matthew O&#8217;Riordan<br></strong>Founder &amp; CEO, Ably</p><div><hr></div><h2><strong>Verify Everything</strong></h2><p>I&#8217;m making bold claims. <strong>Don&#8217;t trust me verify the evidence:</strong></p><p><strong>1. First Gen Realtime Solutions Documentation</strong>:</p><ul><li><p>PubNub: <a href="https://support.pubnub.com/hc/en-us/articles/360051494392-Does-PubNub-guarantee-the-order-of-messages">&#8220;Does not guarantee message order&#8221;</a></p></li><li><p>Pusher: <a href="https://docs.bird.com/pusher/channels/channels/events/why-dont-channels-events-arrive-in-order">&#8220;Messages processed by many machines in parallel&#8221;</a></p></li><li><p>Socket.io: <a href="https://socket.io/docs/v4/using-multiple-nodes/">Clustering documentation</a> showing manual Redis + sticky sessions required</p></li></ul><p><strong>2. Ably Documentation</strong>:</p><ul><li><p><a href="https://ably.com/four-pillars-of-dependability">Four Pillars of Dependability</a> - Performance, Integrity, Reliability, Availability</p></li><li><p><a href="https://ably.com/blog/data-integrity-in-ably-pub-sub">Data Integrity in Ably Pub/Sub</a> - Technical implementation details</p></li><li><p><a href="https://ably.com/blog/achieving-exactly-once-message-processing-with-ably">Achieving Exactly-Once Delivery</a></p></li><li><p><a href="https://ably.com/blog/message-durability-quality-of-service-distributed-system">Message Durability and QoS</a></p></li><li><p><a href="https://ably.com/docs/platform/architecture">Ably platform architecture</a></p></li></ul><p><strong>The evidence is public. The data is verifiable. The architectural differences are documented.</strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mattheworiordan.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Matthew O'Riordan's blog! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Scaling WebSockets to Billions of Connections Globally: Lessons from Socket.io, Pusher, and PubNub]]></title><description><![CDATA[How Ably delivers 1.5 billion daily WebSocket connections across 11 datacenters&#8212;and why this combination was considered impossible.]]></description><link>https://blog.mattheworiordan.com/p/scaling-websockets-to-billions-of</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/scaling-websockets-to-billions-of</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Fri, 31 Oct 2025 16:54:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Rk7p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last Wednesday, I wrote about how<a href="https://blog.mattheworiordan.com/p/the-impossible-architecture-how-ably"> Ably maintained zero impact during the AWS US-EAST-1 outage</a>.</p><p>Today: another thing our competitors probably thought was impossible.</p><p><strong>Scaling WebSockets globally to billions of connections daily.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Rk7p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Rk7p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 424w, https://substackcdn.com/image/fetch/$s_!Rk7p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 848w, https://substackcdn.com/image/fetch/$s_!Rk7p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 1272w, https://substackcdn.com/image/fetch/$s_!Rk7p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Rk7p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png" width="480" height="345.4945054945055" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:480,&quot;bytes&quot;:1636128,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.mattheworiordan.com/i/177668810?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Rk7p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 424w, https://substackcdn.com/image/fetch/$s_!Rk7p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 848w, https://substackcdn.com/image/fetch/$s_!Rk7p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 1272w, https://substackcdn.com/image/fetch/$s_!Rk7p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21993452-8a02-438a-9cf9-9cda4b79f8f6_1456x1048.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Standing on the Shoulders of Giants</strong></h2><p>When we started building Ably in 2016, we didn&#8217;t start from scratch. We studied the platforms that came before us, learned from their innovations, and understood their trade-offs.</p><p><strong>Three pioneers shaped our thinking:</strong></p><h3><strong>1. Socket.io: The WebSocket Pioneer</strong></h3><p><a href="https://rauchg.com/">Guillermo Rauch</a> (now CEO of Vercel) created <a href="https://socket.io/">Socket.io</a> and showed the world that WebSockets could be accessible to mainstream developers. Before Socket.io, WebSockets were complex, low-level, and hard to use. After Socket.io, millions of developers could add realtime features with elegant, event-driven APIs.</p><p>Socket.io pioneered:</p><ul><li><p>Native WebSocket protocol with automatic fallbacks</p></li><li><p>Event-based messaging that just made sense</p></li><li><p>Open source accessibility (free forever)</p></li><li><p>Excellent developer experience</p></li></ul><p><strong>What we learned</strong>: WebSocket can have beautiful APIs. Developers don&#8217;t want to think about protocols&#8212;they want to think about features.</p><h3><strong>2. Pusher: The Managed Platform</strong></h3><p><a href="https://pusher.com/">Pusher</a> took Socket.io&#8217;s WebSocket approach and made it a managed service. No servers to run. No Redis to configure. No DevOps burden. Just beautiful APIs and infrastructure that worked.</p><p>Pusher proved:</p><ul><li><p>Developers would pay for zero-operations platforms</p></li><li><p>Developer experience matters as much as features</p></li><li><p>WebSocket-based managed services were viable businesses</p></li></ul><p><strong>What we learned</strong>: The future isn&#8217;t self-hosting libraries&#8212;it&#8217;s managed platforms that eliminate operational complexity.</p><h3><strong>3. PubNub: The Global Scale Ambition</strong></h3><p><a href="https://www.pubnub.com/">PubNub</a> demonstrated that globally distributed pub/sub infrastructure could work at scale. With <a href="https://www.pubnub.com/blog/remaining-up-and-running-during-aws-outages/">15+ points of presence worldwide</a>, they showed ambition for true internet-scale realtime messaging.</p><p><strong>What we learned</strong>: Developers building global applications need infrastructure that&#8217;s already distributed globally. Single-region solutions create latency problems.</p><div><hr></div><h2><strong>The Trade-Offs Each Made</strong></h2><p>Each platform achieved something remarkable. But each also made architectural trade-offs that created limitations:</p><h3><strong>Socket.io: Elegance Without Scale Operations</strong></h3><p>Socket.io is a <strong>library</strong>, not a <strong>managed platform</strong>. You host it yourself.</p><p><strong>The trade-off</strong>:</p><ul><li><p>&#9989; <strong>Strength</strong>: Free, open source, complete control</p></li><li><p>&#10060; <strong>Limitation</strong>: Full DevOps burden, manual clustering, single-region (self-hosted)</p></li></ul><p><strong>Connection limits</strong>: Production deployments typically hit <strong>10,000-30,000 concurrent connections per Node.js instance</strong> before performance degrades. Beyond this, you need to <a href="https://socket.io/docs/v4/using-multiple-nodes/">manually cluster using Redis and sticky sessions</a>.</p><p><strong>Guillermo Rauch&#8217;s own acknowledgment</strong> (from <a href="https://softwareengineeringdaily.com/2016/03/03/socket-io-and-realtime-applications-with-guillermo-rauch/">Software Engineering Daily podcast</a>):</p><blockquote><p>&#8220;I suffered from that quite a bit with Socket.io, which was one of my open source projects because there was only so much I could do to like kind of transfer the best practices of how to scale it at a massive concurrency. I could write a readme, but that&#8217;s, that&#8217;s as far as open source can typically go.&#8221;</p></blockquote><p><strong>Real-world evidence</strong>:</p><ul><li><p><a href="https://stackoverflow.com/questions/9924822/scalability-issues-relating-to-socket-io">Trello initially used Socket.io</a> but encountered &#8220;problems with scaling up to more than 10K simultaneous client connections&#8221; and eventually built a custom WebSocket implementation handling &#8220;nearly 400,000&#8221; connections</p></li><li><p><a href="https://ably.com/topic/scaling-socketio">Disney+ Hotstar evaluated Socket.io</a> but selected MQTT instead for their social feed infrastructure</p></li></ul><p><strong>The constraint</strong>: Socket.io wasn&#8217;t designed for internet scale. It excels at small-to-medium deployments where you want flexibility and control. At massive scale, the operational complexity becomes overwhelming.</p><div><hr></div><h3><strong>Pusher: WebSockets, But Single-Region</strong></h3><p>Pusher took the right approach with WebSockets and managed infrastructure. But each Pusher app <a href="https://pusher.com/docs/channels/miscellaneous/clusters/">lives in a single cluster</a>&#8212;one datacenter location.</p><p><strong>Available clusters</strong>: <a href="https://pusher.com/docs/channels/miscellaneous/clusters/">9 regional options</a> (N. Virginia, Ohio, Oregon, Ireland, Singapore, Mumbai, Tokyo, Sydney, S&#227;o Paulo)</p><p><strong>The trade-off</strong>:</p><ul><li><p>&#9989; <strong>Strength</strong>: Simple architecture, WebSocket protocol, zero operations</p></li><li><p>&#10060; <strong>Limitation</strong>: Single-region per app means higher latency for global users, no automatic geographic failover</p></li></ul><p><strong>From Pusher&#8217;s documentation</strong> on why they chose single-region:</p><blockquote><p>&#8220;Consistency is important to Pusher, and they are not happy with the compromises needed to replicate data across clusters, such as inaccurate ordering of messages, dropped messages, or increased latency.&#8221;</p></blockquote><p>This is a <strong>valid architectural choice</strong>&#8212;single-region simplifies operations and guarantees consistency. But it creates trade-offs:</p><ul><li><p>Users far from your selected cluster experience higher latency</p></li><li><p>If your datacenter goes down, your entire app is affected</p></li><li><p><a href="https://docs.bird.com/pusher/channels/channels/connecting/how-can-i-add-a-cluster-failover-process-to-my-channels-integration">No automatic failover between clusters</a>&#8212;you must implement manual failover logic</p></li></ul><p><strong>The constraint</strong>: Pusher optimized for simplicity over geographic distribution. Great for regional applications. Problematic for global ones.</p><div><hr></div><h3><strong>PubNub: Global Distribution, But Not WebSockets</strong></h3><p>PubNub demonstrated global distribution with <a href="https://www.pubnub.com/blog/remaining-up-and-running-during-aws-outages/">15+ points of presence</a> (exact locations not publicly specified). But here&#8217;s where it gets interesting.</p><p><strong>PubNub&#8217;s own documentation</strong> reveals the protocol reality:</p><p><strong>Their blog claims</strong> (<a href="https://www.pubnub.com/blog/websockets-vs-rest-api-understanding-the-difference/">WebSockets vs REST article</a>):</p><blockquote><p>&#8220;At PubNub we have taken WebSockets to extreme scale and reliability, being able to service millions of devices across the globe and billions of messages each day being sent across the wire.&#8221;</p></blockquote><p><strong>Their technical guide says</strong> (<a href="https://www.pubnub.com/guides/websockets/">WebSockets guide</a>):</p><blockquote><p>&#8220;WebSocket shortcomings can be difficult to manage if you are not an expert in building real-time systems.&#8221;</p><p>&#8220;PubNub takes a protocol-agnostic stance, but in our current operations, we have found that long polling is the best bet for most use cases.&#8221;</p></blockquote><p><strong>Their support documentation confirms</strong> (<a href="https://support.pubnub.com/hc/en-us/articles/33934737587981">Subscribe Long Poll Mechanism</a>):</p><ul><li><p>Uses HTTP long-polling, not WebSockets</p></li><li><p>Default timeout:<a href="https://www.pubnub.com/docs/general/channels/subscribe"> 310 seconds</a></p></li><li><p><a href="https://www.pubnub.com/docs/general/presence/presence-events">Presence events</a> use &#8220;~280s server pings&#8221;</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K1p7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K1p7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 424w, https://substackcdn.com/image/fetch/$s_!K1p7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 848w, https://substackcdn.com/image/fetch/$s_!K1p7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 1272w, https://substackcdn.com/image/fetch/$s_!K1p7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K1p7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png" width="1162" height="393" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:393,&quot;width&quot;:1162,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!K1p7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 424w, https://substackcdn.com/image/fetch/$s_!K1p7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 848w, https://substackcdn.com/image/fetch/$s_!K1p7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 1272w, https://substackcdn.com/image/fetch/$s_!K1p7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a6714d-d243-494e-8da9-56d629a56a68_1162x393.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">PubNub in the Dev Console showing HTTP long polling as their transport layer</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c_ZT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c_ZT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 424w, https://substackcdn.com/image/fetch/$s_!c_ZT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 848w, https://substackcdn.com/image/fetch/$s_!c_ZT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 1272w, https://substackcdn.com/image/fetch/$s_!c_ZT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c_ZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png" width="1162" height="427" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:427,&quot;width&quot;:1162,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!c_ZT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 424w, https://substackcdn.com/image/fetch/$s_!c_ZT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 848w, https://substackcdn.com/image/fetch/$s_!c_ZT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 1272w, https://substackcdn.com/image/fetch/$s_!c_ZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ec5d33c-6bea-4e80-ba27-f94fc5cc8826_1162x427.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ably in the Dev Console showing WebSockets and WebSocket frames</figcaption></figure></div><p><strong>The trade-off</strong>:</p><ul><li><p>&#9989; <strong>Strength</strong>: Global distribution, multi-region architecture</p></li><li><p>&#10060; <strong>Limitation</strong>: HTTP long-polling instead of WebSockets (higher latency, more overhead, stateless connections)</p></li></ul><p><strong>Why HTTP long-polling matters</strong>:</p><ul><li><p>Higher latency (repeated connection setup/teardown vs persistent WebSocket)</p></li><li><p>Higher overhead (HTTP headers on every request)</p></li><li><p>Stateless (harder to provide ordering guarantees&#8212;more on this Monday)</p></li><li><p>More bandwidth usage</p></li><li><p>Worse mobile battery life</p></li></ul><p><strong>You can verify this yourself</strong>: Open browser DevTools &#8594; Network tab. Connect to a PubNub demo. You&#8217;ll see HTTP GET requests, not WebSocket frames.</p><p><strong>The constraint</strong>: PubNub achieved global distribution but traded away WebSocket&#8217;s technical benefits.</p><h2>Platform Comparison Visualised</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7dvf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7dvf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 424w, https://substackcdn.com/image/fetch/$s_!7dvf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 848w, https://substackcdn.com/image/fetch/$s_!7dvf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 1272w, https://substackcdn.com/image/fetch/$s_!7dvf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7dvf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png" width="1456" height="1705" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1705,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:433680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.mattheworiordan.com/i/177668810?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7dvf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 424w, https://substackcdn.com/image/fetch/$s_!7dvf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 848w, https://substackcdn.com/image/fetch/$s_!7dvf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 1272w, https://substackcdn.com/image/fetch/$s_!7dvf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e9141f6-8fe7-48e8-b449-fa40d8f42f28_1542x1806.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2><strong>Why This Combination Is Hard</strong></h2><p>None of these platforms could deliver <strong>all four</strong> simultaneously:</p><ol><li><p>&#9989; Native WebSocket protocol (not HTTP long-polling)</p></li><li><p>&#9989; Globally distributed architecture (not single-region)</p></li><li><p>&#9989; Billions of connections at scale</p></li><li><p>&#9989; Reliability guarantees (ordering, delivery, recovery)</p></li></ol><p><strong>Why?</strong> Because combining these is genuinely difficult engineering:</p><p><strong>Challenge 1: WebSocket State Management Across Regions</strong></p><ul><li><p>WebSockets are stateful, persistent connections</p></li><li><p>Distributing state across global datacenters while maintaining consistency is complex</p></li><li><p>Most platforms chose either WebSockets OR global distribution, not both</p></li></ul><p><strong>Challenge 2: Ordering Guarantees in Distributed Systems</strong></p><ul><li><p>The<a href="https://en.wikipedia.org/wiki/CAP_theorem"> CAP theorem</a> means trade-offs between consistency, availability, and partition tolerance</p></li><li><p>Most platforms prioritize availability over strong ordering</p></li><li><p>Providing ordering guarantees at global scale requires careful architectural decisions (more on this Monday)</p></li></ul><p><strong>Challenge 3: Operations at Scale</strong></p><ul><li><p>Socket.io: Operations burden falls on users (manual clustering, Redis, monitoring)</p></li><li><p>Pusher: Operations managed, but single-region limits scale</p></li><li><p>PubNub: Global operations, but HTTP&#8217;s stateless nature limits capabilities</p></li></ul><div><hr></div><h2><strong>What Ably Built</strong></h2><p>At Ably, we asked: <strong>Could we achieve all four?</strong></p><p>Could we combine:</p><ul><li><p>Socket.io&#8217;s WebSocket elegance</p></li><li><p>Pusher&#8217;s zero-operations experience</p></li><li><p>PubNub&#8217;s global distribution ambitions</p></li><li><p>Plus reliability guarantees none of them provide</p></li></ul><p><strong>Turns out: yes. But it required building distributed infrastructure from the ground up with all four as first-class requirements.</strong></p><h3><strong>The Architecture</strong></h3><p><strong>Multi-region active-active</strong>: <a href="https://ably.com/network">11 globally distributed core routing datacenters</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yqZk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yqZk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 424w, https://substackcdn.com/image/fetch/$s_!yqZk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 848w, https://substackcdn.com/image/fetch/$s_!yqZk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 1272w, https://substackcdn.com/image/fetch/$s_!yqZk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yqZk!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png" width="1200" height="606.5934065934066" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:736,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:987605,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.mattheworiordan.com/i/177668810?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yqZk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 424w, https://substackcdn.com/image/fetch/$s_!yqZk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 848w, https://substackcdn.com/image/fetch/$s_!yqZk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 1272w, https://substackcdn.com/image/fetch/$s_!yqZk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6de344fa-348f-4ddc-a319-17269f3cfdd9_3680x1860.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ably network, 11 regional data centers, 700+ acceleration PoPs</figcaption></figure></div><ul><li><p>Each region operates independently</p></li><li><p>Regions communicate peer-to-peer (no central hub)</p></li><li><p>Failure in one region doesn&#8217;t cascade to others</p></li><li><p><a href="https://ably.com/network">700+ edge acceleration points</a> globally</p></li></ul><p><strong>Native WebSocket protocol</strong> with intelligent fallbacks:</p><ul><li><p><a href="https://ably.com/docs/client-lib-development-guide/websocket">WebSocket specification</a> implemented in all SDKs</p></li><li><p>Automatic fallback to Comet/long-polling only when WebSocket unavailable</p></li><li><p>Binary protocol support (MessagePack) for efficiency</p></li><li><p><a href="https://github.com/ably/ably-js">Open source SDKs</a> so developers can verify implementation</p></li></ul><p><strong>Automatic clustering and failover</strong>:</p><ul><li><p>Unlike Socket.io&#8217;s manual Redis clustering, Ably&#8217;s clustering is built-in</p></li><li><p>Unlike Pusher&#8217;s single-region design, Ably automatically routes to nearest healthy datacenter</p></li><li><p>Connection state preserved during failover</p></li><li><p><a href="https://ably.com/docs/connect/states">2-minute connection recovery window</a> with automatic message recovery</p></li></ul><p><strong>Reliability guarantees</strong>:</p><ul><li><p>Message ordering for messages from a publisher over a single connection</p></li><li><p>Exactly-once delivery with idempotency</p></li><li><p>Automatic connection state recovery</p></li><li><p>(More on ordering guarantees in Monday&#8217;s post)</p></li></ul><div><hr></div><h3><strong>The Scale We&#8217;re Running</strong></h3><p><strong>Ably by the numbers</strong> (current platform stats):</p><ul><li><p><strong>2 trillion realtime API transactions monthly</strong></p></li><li><p><strong>1.5 billion daily WebSocket connections</strong></p></li><li><p><strong>30 billion monthly connections</strong></p></li><li><p><strong>2.4 billion devices reached monthly</strong></p></li><li><p><strong>37ms median roundtrip latency</strong> globally</p></li><li><p><strong>6.7ms average edge message delivery latency</strong></p></li><li><p><strong>11 globally distributed regions</strong></p></li><li><p><strong>700+ edge acceleration PoPs</strong></p></li><li><p><strong>99.999% uptime SLA</strong> (achieved 100% uptime for 5+ consecutive years)</p></li></ul><p><strong>For context</strong>:</p><ul><li><p>Ably handles <strong>~50,000x more connections</strong> than Socket.io&#8217;s per-instance limit (1.5B daily vs 30K per instance)</p></li><li><p>Delivers this across <strong>11 datacenters</strong> vs single-region deployments</p></li><li><p>With <strong>sub-40ms global latency</strong> vs routing all traffic to one location</p></li></ul><div><hr></div><h2><strong>The Engineering Philosophy</strong></h2><p><strong>Guillermo Rauch was right</strong>: You can&#8217;t transfer &#8220;massive concurrency&#8221; best practices through documentation alone.</p><p><strong>That&#8217;s why we built a platform, not a library.</strong></p><blockquote><p>Our philosophy: <strong>Do the hard infrastructure work so our customers don&#8217;t have to.</strong></p></blockquote><p>Socket.io requires customers to:</p><ul><li><p>Manage servers, Redis, load balancers</p></li><li><p>Configure sticky sessions and clustering</p></li><li><p>Implement monitoring and failover</p></li><li><p>Handle scaling, security, and operations</p></li></ul><p>Ably handles all of this:</p><ul><li><p>Zero servers to manage</p></li><li><p>Zero Redis to configure</p></li><li><p>Zero load balancers to tune</p></li><li><p>Automatic scaling, security, and operations</p></li></ul><p><strong>This isn&#8217;t about Socket.io being wrong</strong>&#8212;it&#8217;s about different tools solving different problems. Socket.io excels at providing free, flexible WebSocket capabilities for small-to-medium scale. Ably provides internet-scale infrastructure with enterprise guarantees.</p><p>The validation isn&#8217;t just our engineering&#8212;it&#8217;s that customers from all three platforms have migrated to Ably when they outgrew their original solution&#8217;s architectural constraints. Common themes: operational complexity at scale, geographic distribution requirements for global user bases, and the need for reliability guarantees their previous platform&#8217;s architecture couldn&#8217;t provide.</p><div><hr></div><h2><strong>What&#8217;s Coming Monday</strong></h2><p>Today&#8217;s post focused on <strong>achieving WebSockets at global scale</strong>&#8212;combining protocol benefits with geographic distribution and operational simplicity.</p><p>But WebSockets alone don&#8217;t guarantee reliability.</p><p><strong>Monday</strong>: How Ably&#8217;s architecture enables guarantees they can&#8217;t provide&#8212;and why this matters for financial systems, gaming, collaboration, chat and any application where message sequence matters.</p><p>See you Monday.</p><p><strong>Matthew O&#8217;Riordan<br></strong>Founder &amp; CEO, Ably</p><div><hr></div><h2><strong>Verify Everything</strong></h2><p>I&#8217;m making bold claims. Don&#8217;t trust me&#8212;verify the evidence:</p><p><strong>1. Socket.io Connection Limits</strong>:</p><ul><li><p><a href="https://stackoverflow.com/questions/9924822/scalability-issues-relating-to-socket-io">Production reports</a>: &#8220;many people have issues getting above 30k connections&#8221;</p></li><li><p><a href="https://stackoverflow.com/questions/9924822/scalability-issues-relating-to-socket-io">Trello case study</a>: Problems scaling beyond 10K</p></li><li><p><a href="https://socket.io/docs/v4/using-multiple-nodes/">Socket.io clustering docs</a>: Manual Redis + sticky sessions required</p></li></ul><p><strong>2. Pusher Single-Region Architecture</strong>:</p><ul><li><p><a href="https://pusher.com/docs/channels/miscellaneous/clusters/">Cluster configuration</a>: &#8220;When you create a Channels app, you can choose which cluster it exists in&#8221;</p></li><li><p><a href="https://docs.bird.com/pusher/channels/channels/connecting/how-can-i-add-a-cluster-failover-process-to-my-channels-integration">No automatic failover</a>: &#8220;Channels has no built in failover between clusters&#8221;</p></li></ul><p><strong>3. PubNub HTTP Long-Polling</strong>:</p><ul><li><p><a href="https://www.pubnub.com/guides/websockets/">WebSocket guide</a>: &#8220;long polling is the best bet for most use cases&#8221;</p></li><li><p><a href="https://www.pubnub.com/docs/general/channels/subscribe">Subscribe documentation</a>: 310-second timeout</p></li><li><p><a href="https://www.pubnub.com/docs/general/presence/presence-events">Presence events</a>: &#8220;~280s server pings&#8221;</p></li><li><p>Verify yourself: Open DevTools, test their demo</p></li></ul><p><strong>4. Ably Architecture</strong>:</p><ul><li><p><a href="https://ably.com/docs/platform-architecture">Platform architecture</a>: Multi-region design</p></li><li><p><a href="https://ably.com/docs/client-lib-development-guide/websocket">WebSocket specification</a>: Protocol implementation</p></li><li><p><a href="https://github.com/ably/ably-js">Open source SDKs</a>: Verify implementation yourself</p></li><li><p><a href="https://ably.com/network">Network map</a>: 11 regions + 700+ edge points</p></li></ul><p><strong>The evidence is public. The data is verifiable. The architectural differences are documented.</strong></p>]]></content:encoded></item><item><title><![CDATA[The 'Impossible' Architecture: How Ably Maintained Zero Impact During the AWS US-East-1 Outage]]></title><description><![CDATA[When PubNub's CEO called our results impossible, he validated exactly what we built]]></description><link>https://blog.mattheworiordan.com/p/the-impossible-architecture-how-ably</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/the-impossible-architecture-how-ably</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Wed, 29 Oct 2025 21:31:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RM1w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last Monday, October 20, <a href="https://blog.pragmaticengineer.com/aws-outage-us-east-1/">AWS US-EAST-1 experienced a major outage lasting over 14 hours</a>. For any infrastructure company running on AWS, this was a real-world stress test of architectural resilience.</p><p>The results were stark:<br>  <strong>Ably</strong>: Operational throughout. Zero customer impact. Zero downtime.<br>  <strong>PubNub</strong>: 10+ hours of degraded service across two incidents.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RM1w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RM1w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 424w, https://substackcdn.com/image/fetch/$s_!RM1w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 848w, https://substackcdn.com/image/fetch/$s_!RM1w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!RM1w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RM1w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg" width="598" height="312.455" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:418,&quot;width&quot;:800,&quot;resizeWidth&quot;:598,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;No alternative text description for this image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="No alternative text description for this image" title="No alternative text description for this image" srcset="https://substackcdn.com/image/fetch/$s_!RM1w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 424w, https://substackcdn.com/image/fetch/$s_!RM1w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 848w, https://substackcdn.com/image/fetch/$s_!RM1w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!RM1w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f969c33-3c84-42b7-bfcd-619c7da4a8ec_800x418.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I expected we&#8217;d share technical post-mortems and move on. What I didn&#8217;t expect was PubNub&#8217;s CEO, Todd Greene, to publicly question our results, <a href="https://www.linkedin.com/feed/update/urn:li:activity:7386439622463029249?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7386439622463029249%2C7386533606527201281%29&amp;dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287386533606527201281%2Curn%3Ali%3Aactivity%3A7386439622463029249%29">suggesting they were &#8220;impossible&#8221;</a> and that we&#8217;d &#8220;<a href="https://www.linkedin.com/feed/update/urn:li:activity:7386439622463029249?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7386439622463029249%2C7386533606527201281%29&amp;replyUrn=urn%3Ali%3Acomment%3A%28activity%3A7386439622463029249%2C7386965384257732608%29&amp;dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287386533606527201281%2Curn%3Ali%3Aactivity%3A7386439622463029249%29&amp;dashReplyUrn=urn%3Ali%3Afsd_comment%3A%287386965384257732608%2Curn%3Ali%3Aactivity%3A7386439622463029249%29">solved that pesky speed-of-light limitation</a>&#8220;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n9r-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n9r-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 424w, https://substackcdn.com/image/fetch/$s_!n9r-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 848w, https://substackcdn.com/image/fetch/$s_!n9r-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 1272w, https://substackcdn.com/image/fetch/$s_!n9r-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n9r-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png" width="481" height="310" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:310,&quot;width&quot;:481,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40636,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177511988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n9r-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 424w, https://substackcdn.com/image/fetch/$s_!n9r-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 848w, https://substackcdn.com/image/fetch/$s_!n9r-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 1272w, https://substackcdn.com/image/fetch/$s_!n9r-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4497c4c-81e8-4487-9324-42d1bb8cbc9f_481x310.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Those comments became the ultimate validation of years of architectural investment.</p><h4><strong>What Todd Called &#8220;Impossible&#8221;</strong></h4><p>Todd&#8217;s comment implied that maintaining operational status during a regional AWS failure defies the laws of physics. Let me explain what he&#8217;s calling &#8220;impossible&#8221; - it&#8217;s actually well-thought-through infrastructure design.</p><p>The core principle: <strong>Regional redundancy</strong>.</p><p>Ably operates TWO datacenters within the US-East region:</p><ul><li><p>AWS us-east-1 (Northern Virginia)</p></li><li><p>AWS us-east-2 (Ohio)</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T7PU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T7PU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 424w, https://substackcdn.com/image/fetch/$s_!T7PU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 848w, https://substackcdn.com/image/fetch/$s_!T7PU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 1272w, https://substackcdn.com/image/fetch/$s_!T7PU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T7PU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png" width="859" height="448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:448,&quot;width&quot;:859,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:401945,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177511988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T7PU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 424w, https://substackcdn.com/image/fetch/$s_!T7PU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 848w, https://substackcdn.com/image/fetch/$s_!T7PU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 1272w, https://substackcdn.com/image/fetch/$s_!T7PU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c07644f-5e9a-4ed1-8880-700d8438a2a7_859x448.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ably&#8217;s data center regional distribution</figcaption></figure></div><p>The network latency between these regions from major East Coast cities:</p><ul><li><p>New York: 5-10ms</p></li><li><p>Boston: 8-12ms</p></li><li><p>Washington DC: 7-10ms</p></li><li><p>Atlanta: 10-12ms</p></li></ul><p>When us-east-1 became unavailable, we failed over to us-east-2. Our monitoring showed a worst-case median latency increase of 12ms (<em>anyone can <a href="https://gist.github.com/mattheworiordan/0fd8f3334b58ac7827afd15506f4ebca">easily verify this is possible and does not require any light speed violations</a> </em>&#129325;<em>).</em></p><p>That&#8217;s basic geography, not bending physics.</p><p>Our blog post on how <a href="https://ably.com/blog/multi-region-resilience-aws-outage">Ably&#8217;s multi-region architecture held up during the US-East AWS outage</a> has the full technical details including performance graphs.</p><h4><strong>What Happened at PubNub</strong></h4><p>According to <a href="https://status.pubnub.com/incidents/585rbxt33bcs">PubNub&#8217;s public status page</a>, their experience was very different:</p><p><a href="https://status.pubnub.com/incidents/585rbxt33bcs">Incident 1: October 20, 07:06-23:48 UTC (16 hours 42 minutes)</a><br><strong>&#8220;Elevated latencies and errors for multiple services in US-west and US East&#8221;</strong></p><p><a href="https://status.pubnub.com/incidents/4vl9wztw0cbn">Incident 2: October 20th, 2025 at 07:06 UTC (2 hours 1 minutes)</a><br><strong>&#8220;Increased latency and errors observed in US-West&#8221;</strong></p><p>Total: Over 16 hours of documented degraded service.</p><p>Their blog post about the incident explained why: &#8220;The physical distance to other regions was going to increase latencies.&#8221;</p><p>What this reveals: PubNub doesn&#8217;t appear to have multi-datacenter redundancy within US-East. When us-east-1 failed, they had to route traffic across the country or globe - hence the multi-hour latency issues.</p><h4><strong>This Isn&#8217;t Infrastructure 101</strong></h4><p>I want to be clear: building truly resilient global infrastructure is hard. This isn&#8217;t &#8220;infrastructure 101&#8221; - it&#8217;s the result of 10 years of deliberate architectural choices and significant investment.</p><p><strong>What we have built at Ably:</strong></p><p>Multi-region architecture with no single points of failure:</p><ul><li><p>Each region operates independently</p></li><li><p>Regions communicate peer-to-peer (no central hub)</p></li><li><p>Failure in one region doesn&#8217;t cascade to others</p></li><li><p>700+ edge locations globally via CloudFront</p></li></ul><p>Connection state recovery:</p><ul><li><p>2-minute window to seamlessly resume after disconnections</p></li><li><p>Messages queued on servers, not just client-side</p></li><li><p>Zero message loss during network interruptions</p></li><li><p>Automatic reconnection without application code</p></li></ul><p>SDK resilience:</p><ul><li><p>Automatic failover to healthy datacenters</p></li><li><p>Multiple fallback hosts tried in sequence</p></li><li><p>Connection state preserved during transitions</p></li><li><p>Transparent to end users</p></li></ul><blockquote><p><em><strong>Ably</strong></em><strong> e</strong><em><strong>ngineering philosophy: &#8220;Do the hard infrastructure work so our customers don&#8217;t have to&#8221;</strong></em></p></blockquote><p>This philosophy and investment is clearly evident in <a href="https://ably.com/four-pillars-of-dependability.">our Four Pillars of Dependability</a>.</p><h4><strong>The Broader Pattern</strong></h4><p>The AWS outage wasn&#8217;t an anomaly. Looking at the last year of public incident data (October 2024 - October 2025):</p><p><strong>Ably</strong> (<a href="https://status.ably.com/">status.ably.com</a>):</p><ul><li><p>5 customer impacting incidents </p></li><li><p>531 minutes of degraded service</p></li></ul><p><strong>PubNub </strong>(<a href="https://status.pubnub.com">status.pubnub.com</a>):</p><ul><li><p>26 customer impacting incidents (4.2x more than Ably)</p></li><li><p>6,045 minutes of degraded service (10.3x more than Ably)</p></li><li><p>Pattern of Presence service failures</p></li></ul><p>Ably is not claiming perfection, but we are demonstrating that architectural choices have real consequences for reliability.</p><p><em>(Source: <a href="https://mattheworiordan.substack.com/p/reliability-by-the-numbers-ably-vs">Reliability By The Numbers: Ably vs Pusher vs PubNub incident analysis</a>)</em></p><h4><strong>Why This Matters to Customers</strong></h4><p>This is exactly why customers migrate from PubNub to Ably.</p><p>To date, our <strong>enterprise customers, who</strong> <strong>migrated from PubNub to Ably</strong> in search of a better service, have generated a whopping <strong>$7.5m of revenue</strong>.<br><br><strong>We&#8217;re not aware of any enterprise customers who&#8217;ve migrated in the opposite direction.</strong></p><p>These customers consistently cite similar reasons: They needed reliability guarantees they could actually depend on.</p><p>One recent enterprise customer (we can&#8217;t name them - PubNub threatened legal action when they tried to publish a case study) reported:</p><ul><li><p>65% reduction in operating costs</p></li><li><p>95% reduction in waiting room issues related to realtime</p></li><li><p>100% elimination of ghost-check-in times</p></li><li><p>99% reduction in app-closing errors</p></li></ul><p>These metrics aren&#8217;t about marketing claims. They&#8217;re about real-world performance under real-world conditions - including infrastructure failures.</p><h4><strong>To Developers: Verify Everything</strong></h4><p>I&#8217;m making bold claims. Don&#8217;t trust me - verify the evidence:</p><p>1. Status Pages</p><ul><li><p>See <a href="https://status.ably.com/">Ably status</a> and <a href="https://status.pubnub.com/incidents/4vl9wztw0cbn">PubNub us-east-1 AWS incident</a></p></li></ul><ul><li><p><a href="https://mattheworiordan.substack.com/p/reliability-by-the-numbers-ably-vs">See raw data and analysis for for 3 years worth of Ably, Pusher and Pubnub incidents</a></p></li></ul><p>2. Run Your Own Latency Test:</p><ul><li><p>Ping from US locations to us-east-1 and us-east-2 and see the latency differences</p></li><li><p><a href="https://gist.github.com/mattheworiordan/0fd8f3334b58ac7827afd15506f4ebca">Here&#8217;s some data and a handy script you can run yourself to reproduce this</a></p></li></ul><p>3. Review Architecture Documentation:</p><ul><li><p>Ably Four Pillars: <a href="https://ably.com/four-pillars-of-dependability">https://ably.com/four-pillars-of-dependability</a></p></li><li><p>Ably platform architecture: <a href="https://ably.com/docs/platform-architecture">https://ably.com/docs/platform-architecture</a></p></li><li><p>PubNub architecture: .. tumble weed .. (I genuinely cannot find this information)</p></li></ul><h4><strong>Transparency Makes Everyone Better</strong></h4><p>The more transparent we are about how we design systems and how they perform under real conditions, the more we can all learn from each other. There&#8217;s plenty of space for multiple strong companies in the realtime infrastructure market.</p><p>The AWS outage provided a rare, public test of every platform&#8217;s architecture. The results are documented on both our status pages.</p><p>Ably maintained operational status. PubNub experienced 10+ hours of degradation. That&#8217;s not impossible. That&#8217;s the difference between architectural choices made years ago.</p><h4><strong>What&#8217;s Coming Next &#128074;<br></strong></h4><p>This incident reminded me that we should talk more about the &#8220;impossible&#8221; things Ably achieves.</p><p>Over the next week, I&#8217;m publishing a series on things our competitors probably think are impossible:</p><p><strong>Friday: Scaling native WebSockets to billions of connections daily</strong></p><ul><li><p>Why we chose the hard path instead of easier alternatives</p></li><li><p>What this enables for customers</p></li><li><p>The engineering investment required</p></li></ul><p><strong>Monday: Guaranteeing message ordering and exactly-once delivery in globally distributed systems</strong></p><ul><li><p>Why most platforms can&#8217;t offer these guarantees</p></li><li><p>How our architecture makes it possible</p></li><li><p>What this means for building reliable applications</p></li></ul><p><strong>Wednesday: Transparent pricing that doesn&#8217;t penalize your most successful customers</strong></p><ul><li><p>Why transaction complexity creates billing surprises</p></li><li><p>How consumption-based pricing aligns with customer success</p></li><li><p>The difference between simple marketing and simple reality</p></li></ul><p>Each post will show what&#8217;s actually possible when you do the hard engineering work.</p><p>See you on Friday!</p><p>Matt<br>Technical co-founder and CEO of <a href="https://ably.com">Ably</a></p>]]></content:encoded></item><item><title><![CDATA[Reliability By The Numbers: Ably vs Pusher vs PubNub incident analysis]]></title><description><![CDATA[A Data-Driven Analysis of Realtime Platform Performance from Public Status Site Data]]></description><link>https://blog.mattheworiordan.com/p/reliability-by-the-numbers-ably-vs</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/reliability-by-the-numbers-ably-vs</guid><pubDate>Wed, 29 Oct 2025 20:57:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!P_fZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After the AWS outage, <a href="https://www.linkedin.com/feed/update/urn:li:activity:7386439622463029249?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7386439622463029249%2C7386533606527201281%29&amp;dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287386533606527201281%2Curn%3Ali%3Aactivity%3A7386439622463029249%29">PubNub&#8217;s CEO posted a comment questioning Ably&#8217;s reliability reporting</a>. Fair enough - extraordinary claims require extraordinary evidence.</p><p>So I pulled the data. All of it. Public. Verifiable. Objective.</p><p>I analysed 24 months of incident data from public status pages across Ably, PubNub, and Pusher - 133 incidents total, which is available in <a href="https://docs.google.com/spreadsheets/d/1KcuB3TAlOE8C61dt0GwNSlqCjqoBWJKZLc3d1FieDw8/edit?usp=sharing">this Google Sheet</a>.</p><p><strong>The uptime vs. experience gap</strong></p><p>When platforms claim &#8220;99.999% uptime,&#8221; they&#8217;re referring to SLA definitions that measure consecutive minutes of complete unavailability, excluding scheduled maintenance, brief errors, and degraded performance.</p><p><strong>SLA uptime &#8800; customer experience.</strong></p><p>This analysis doesn&#8217;t calculate SLA uptime - that&#8217;s not measurable from status pages. Instead, it measures what customers actually experienced: every incident where status pages documented errors, failures, or material latency increases, regardless of SLA implications.</p><p>That&#8217;s the metric that matters. Here&#8217;s what the data shows:</p><h3><strong>Last 12 Months</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!P_fZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!P_fZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 424w, https://substackcdn.com/image/fetch/$s_!P_fZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 848w, https://substackcdn.com/image/fetch/$s_!P_fZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 1272w, https://substackcdn.com/image/fetch/$s_!P_fZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!P_fZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png" width="569" height="333.6127527216174" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:377,&quot;width&quot;:643,&quot;resizeWidth&quot;:569,&quot;bytes&quot;:66255,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177508711?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!P_fZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 424w, https://substackcdn.com/image/fetch/$s_!P_fZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 848w, https://substackcdn.com/image/fetch/$s_!P_fZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 1272w, https://substackcdn.com/image/fetch/$s_!P_fZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb0f6e94-329b-47f4-9313-b735f2e97687_643x377.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Ably</strong> demonstrated the strongest performance with 4 major incidents (avg 90 min duration) and 531 customer degraded minutes over 12 months.</p><p><strong>PubNub</strong> had 5.0x more major incidents (20 vs 4), with an average major incident duration of 136 minutes. Customer degraded minutes totaled 6045 (11.4x more than Ably).</p><p><strong>Pusher</strong> experienced 1.0x more major incidents (4 vs 4), with notably longer average durations at 227 minutes. Customer degraded minutes reached 5132 (9.7x more than Ably).</p><h3><strong>Last 24 Months</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gL85!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gL85!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 424w, https://substackcdn.com/image/fetch/$s_!gL85!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 848w, https://substackcdn.com/image/fetch/$s_!gL85!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 1272w, https://substackcdn.com/image/fetch/$s_!gL85!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gL85!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png" width="647" height="382" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:382,&quot;width&quot;:647,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66354,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177508711?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gL85!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 424w, https://substackcdn.com/image/fetch/$s_!gL85!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 848w, https://substackcdn.com/image/fetch/$s_!gL85!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 1272w, https://substackcdn.com/image/fetch/$s_!gL85!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F141f5f47-25ac-4047-886e-daf1845b04d1_647x382.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Ably</strong> demonstrated the strongest performance with 7 major incidents (avg 180 min duration) and 1711 customer degraded minutes over 24 months.</p><p><strong>PubNub</strong> had 3.7x more major incidents (26 vs 7), with an average major incident duration of 148 minutes. Customer degraded minutes totalled 7903 (4.6x more than Ably).</p><p><strong>Pusher</strong> experienced 2.4x more major incidents (17 vs 7), with notably longer average durations at 314 minutes. Customer degraded minutes reached 9661 (5.6x more than Ably).</p><div><hr></div><h2><strong>Detailed Analysis (24 Months)</strong></h2><p>Over a 24-month period, <strong>102 incidents</strong> were analysed across Ably, Pubnub, Pusher.</p><p><strong>Key Findings (Customer-Impacting Degraded Service):</strong></p><ul><li><p><strong>Ably:</strong> 16 customer impact incidents, 1711 total degraded minutes (28.5 hours)</p></li><li><p><strong>PubNub:</strong> 35 customer impact incidents, 7903 total degraded minutes (131.7 hours)</p></li><li><p><strong>Pusher:</strong> 24 customer impact incidents, 9661 total degraded minutes (161.0 hours)</p></li></ul><p><strong>Major Incident Summary:</strong></p><ul><li><p><strong>Ably:</strong> 7 major incidents, average duration 180 minutes</p></li><li><p><strong>PubNub:</strong> 26 major incidents, average duration 148 minutes</p></li><li><p><strong>Pusher:</strong> 17 major incidents, average duration 314 minutes</p></li></ul><div><hr></div><h2><strong>Overall Statistics</strong></h2><h3><strong>Total Incidents by Platform</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nLq6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nLq6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 424w, https://substackcdn.com/image/fetch/$s_!nLq6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 848w, https://substackcdn.com/image/fetch/$s_!nLq6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 1272w, https://substackcdn.com/image/fetch/$s_!nLq6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nLq6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png" width="774" height="315" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:315,&quot;width&quot;:774,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:49194,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177508711?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nLq6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 424w, https://substackcdn.com/image/fetch/$s_!nLq6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 848w, https://substackcdn.com/image/fetch/$s_!nLq6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 1272w, https://substackcdn.com/image/fetch/$s_!nLq6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F136596a3-91b5-4e37-8cfe-e91397e50062_774x315.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>PubNub shows 74% of incidents classified as major compared to Ably&#8217;s 29%, indicating a higher proportion of severe customer-impacting issues.</em></p><h3><strong>Customer-Impacting Degraded Service Time</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QAxK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QAxK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 424w, https://substackcdn.com/image/fetch/$s_!QAxK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 848w, https://substackcdn.com/image/fetch/$s_!QAxK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 1272w, https://substackcdn.com/image/fetch/$s_!QAxK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QAxK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png" width="775" height="256" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:256,&quot;width&quot;:775,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42986,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177508711?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QAxK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 424w, https://substackcdn.com/image/fetch/$s_!QAxK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 848w, https://substackcdn.com/image/fetch/$s_!QAxK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 1272w, https://substackcdn.com/image/fetch/$s_!QAxK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28b9a9eb-c519-4aa2-93a0-61100f5d8d3a_775x256.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Pusher&#8217;s average incident duration of 314 minutes is significantly longer, contributing to 5.6x more total degraded service time compared to Ably.</em></p><h3><strong>Major Incident Duration Summary</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oyJp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oyJp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 424w, https://substackcdn.com/image/fetch/$s_!oyJp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 848w, https://substackcdn.com/image/fetch/$s_!oyJp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 1272w, https://substackcdn.com/image/fetch/$s_!oyJp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oyJp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png" width="730" height="196" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab820810-3945-4517-a8a0-49086a124a18_730x196.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:196,&quot;width&quot;:730,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31160,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177508711?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oyJp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 424w, https://substackcdn.com/image/fetch/$s_!oyJp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 848w, https://substackcdn.com/image/fetch/$s_!oyJp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 1272w, https://substackcdn.com/image/fetch/$s_!oyJp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab820810-3945-4517-a8a0-49086a124a18_730x196.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>PubNub demonstrates the fastest average resolution time at 148 minutes, indicating more effective incident response and remediation processes.</em></p><div><hr></div><h2><strong>Comparative Analysis</strong></h2><h3><strong>Monthly Averages</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!F8Vg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F8Vg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 424w, https://substackcdn.com/image/fetch/$s_!F8Vg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 848w, https://substackcdn.com/image/fetch/$s_!F8Vg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 1272w, https://substackcdn.com/image/fetch/$s_!F8Vg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!F8Vg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png" width="769" height="224" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:224,&quot;width&quot;:769,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:35162,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://mattheworiordan.substack.com/i/177508711?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!F8Vg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 424w, https://substackcdn.com/image/fetch/$s_!F8Vg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 848w, https://substackcdn.com/image/fetch/$s_!F8Vg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 1272w, https://substackcdn.com/image/fetch/$s_!F8Vg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bbfcf17-2f00-4880-979f-a57ca3c232af_769x224.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>On a monthly basis, PubNub averages 4.6x more degraded service minutes than Ably, representing a consistent pattern of higher customer impact over the analysis period.</em></p><div><hr></div><h2><strong>Methodology</strong></h2><h3><strong>Data Source</strong></h3><ul><li><p><strong>Platform:</strong> Statuspage.io public incident APIs</p></li><li><p><strong>Period:</strong> 24 months (October 2023 - October 2025)</p></li><li><p><strong>Incidents:</strong> 102 incidents analysed (133 total collected)</p></li></ul><h3><strong>Classification</strong></h3><ul><li><p><strong>LLM-Based:</strong> Claude Sonnet analysed incident descriptions, timelines, and component impacts as data classification by vendors was not reliable</p></li><li><p><strong>Categories:</strong> Major, Minor, Control Plane / Non-Customer Impact</p></li><li><p><strong>Customer Impact:</strong> Separate tracking of customer-visible degradation</p></li><li><p><strong>Timestamp Corrections:</strong> LLM corrected inaccurate timestamps by reading natural language in incident messages</p></li></ul><h3><strong>Definitions</strong></h3><p><strong>Incident Severity:</strong></p><ul><li><p><strong>Major:</strong> Service failures, customer-visible errors, or extended periods of material latency increases</p></li><li><p><strong>Minor:</strong> Brief degraded performance, short-duration issues, or transient errors</p></li><li><p><strong>Control Plane / Non-Customer Impact:</strong> Internal/control plane issues OR incidents with no customer impact (dashboards, stats, documentation, billing, or internal issues handled gracefully)</p></li></ul><p><strong>Customer Impact:</strong></p><ul><li><p><strong>Customer-Visible Errors:</strong> ANY errors that customers could see, even if brief</p></li><li><p><strong>Material Latency:</strong> Significant slowdown mentioned in incident for extended periods</p></li><li><p><strong>No Customer Impact:</strong> Control-plane issues, or internal issues handled gracefully (retries, failover) with no visible errors</p></li></ul><p><strong>Key Metrics:</strong></p><ul><li><p><strong>Customer Degraded Service Time:</strong> Total minutes where customers experienced errors OR material latency</p></li><li><p><strong>Non-Degraded Service Availability:</strong> 100% - (customer impact minutes / total minutes in period)</p></li><li><p><strong>Major Incident Duration:</strong> Average length of major incidents, indicating how quickly issues are resolved</p></li></ul><p><em><strong>This report was generated from live data on 2025-10-29</strong></em> <br></p>]]></content:encoded></item><item><title><![CDATA[SaaS Funding Napkin trends from 2016-2022]]></title><description><![CDATA[Christopher Janz, from Point Nine Capital, has been creating the now infamous SaaS napkin since 2016.]]></description><link>https://blog.mattheworiordan.com/p/saas-funding-napkin-trends-from-2016</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/saas-funding-napkin-trends-from-2016</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Thu, 04 Aug 2022 08:01:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Dnxa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><a href="https://medium.com/inside-efounders/meet-christoph-janz-from-point-nine-capital-2e500e8f2c49">Christopher Janz</a>, from <a href="http://www.pointninecap.com/">Point Nine Capital</a>, has been creating the now infamous <a href="https://medium.com/point-nine-news/what-does-it-take-to-raise-capital-in-saas-in-2022-7ebe55c86e3e">SaaS napkin</a> since 2016. In this post I have visualised what&#8217;s changed for founders raising capital over the last 6 years. You can also <a href="https://docs.google.com/spreadsheets/d/1-QCBMwFvCJQWtcC4xKYOslIS0n3O9H1pxSW5jTbMNBk/edit#gid=0">view the raw data</a>.</em></p><h2><strong>Round size</strong></h2><p>The round sizes have unsurprisingly grown significantly, with some tapering off in 2022. Pre-seed rounds in 2016 ranged from $200k to $500k, whereas they now range from $1&#8211;$2m. Series A have grown from $3m to $12m in 2016 to $6m and $18m in 2022 showing no sign of drop off in spite of the macro economic situation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Dnxa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Dnxa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 424w, https://substackcdn.com/image/fetch/$s_!Dnxa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 848w, https://substackcdn.com/image/fetch/$s_!Dnxa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 1272w, https://substackcdn.com/image/fetch/$s_!Dnxa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Dnxa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png" width="616" height="645" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:645,&quot;width&quot;:616,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Dnxa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 424w, https://substackcdn.com/image/fetch/$s_!Dnxa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 848w, https://substackcdn.com/image/fetch/$s_!Dnxa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 1272w, https://substackcdn.com/image/fetch/$s_!Dnxa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef4802b-7475-4ba5-a95b-81735fccd1a4_616x645.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://docs.google.com/spreadsheets/d/1-QCBMwFvCJQWtcC4xKYOslIS0n3O9H1pxSW5jTbMNBk/edit?usp=sharing">Generated from raw data for Seed to Series B from 2016&#8211;2022</a></figcaption></figure></div><h2><strong>Valuation</strong></h2><p>Valuations have materially increased across the board, with some signs this is rebounding this year. Pre-seed valuations in 2022 are up to $12m from $3m in 2016, and Series B valuations are up to $270m last year up from $100m in 2016.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kTmk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kTmk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 424w, https://substackcdn.com/image/fetch/$s_!kTmk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 848w, https://substackcdn.com/image/fetch/$s_!kTmk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 1272w, https://substackcdn.com/image/fetch/$s_!kTmk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kTmk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png" width="630" height="704" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:704,&quot;width&quot;:630,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!kTmk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 424w, https://substackcdn.com/image/fetch/$s_!kTmk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 848w, https://substackcdn.com/image/fetch/$s_!kTmk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 1272w, https://substackcdn.com/image/fetch/$s_!kTmk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b7098f-ed99-43f2-ba6e-b89bf41b0181_630x704.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://docs.google.com/spreadsheets/d/1-QCBMwFvCJQWtcC4xKYOslIS0n3O9H1pxSW5jTbMNBk/edit?usp=sharing">Generated from raw data for Seed to Series B from 2016&#8211;2022</a></figcaption></figure></div><p>Comparing this to public SaaS multiples, it&#8217;s clear that Series B valuations more closely track the markets, whereas Seed and Series A valuations seem to be bump upward regardless of the market.</p><p>Data I would love to see is how each annual cohort performed for investors i.e. what returns did investors get based on which year they invested in and the valuations at the time. Unfortunately I don&#8217;t have access to this data.</p><h2><strong>ARR</strong></h2><p>The ARR expectations for seed companies has not shifted much, up from $0 to $0.6m to now $0 to $1m. Series A has shown significant change with the expectation in 2016 being $1.2m to $3m, in 2021 being $0.5m to $4m, and this year being $0.5m to $2.5m showing that Series A companies can certainly raise with less ARR today. Series B mins have dropped too from $4.2m to $3m.</p><h2><strong>Capital Efficiency</strong></h2><p>2022 is the year where every VC suddenly started talking about capital efficiency in every meeting with their portfolios. It&#8217;s not surprising given access to capital is no longer cheap given the wider economic shift in the markets and the <a href="https://www.ft.com/content/6395df7e-1bab-4ea1-a7ea-afaa71354fa0">&#8220;silent&#8221; VC crash</a>. Predictably this year Christopher Janz added capital efficiency to the SaaS Napkin as a new metric you now need to think about at Series A (3.5x) and Series B (2.5x). If your investors have not asked you about capital efficiency yet, they must be living under a rock. If you don&#8217;t know what it is:</p><blockquote><p><em>The Capital Efficiency Ratio is <strong>the ratio of how much a company has spent growing revenue and how much they&#8217;re receiving in return</strong>. It is the broadest measure of company effectiveness in generating ARR</em></p></blockquote><h2><strong>What next?</strong></h2><p>I honestly don&#8217;t know what&#8217;s coming next, I am not sure anyone really knows either. However, what I can clearly observe is that interest rates continue to climb resulting in downward pressure on equity multiples, and all startup and growth businesses around me are tightening their belts and extending their runways in anticipation of a bumpy fundraising ride ahead. If you&#8217;re looking to fundraise now but have the option to delay, my advice would be to hold off until there is more stability in the market and access to money eases.</p><p>I&#8217;m <a href="https://www.ably.io/about/team">Matthew O&#8217;Riordan and CEO</a> and Co-Founder of <a href="https://www.ably.io/">Ably Realtime</a>. Ably is a Series B developer-first business backed by <a href="https://www.insightpartners.com/">Insight Partners</a>, <a href="https://dawncapital.com/">Dawn Capital</a>, <a href="https://mmc.vc/">MMC Ventures</a> amongst <a href="https://www.crunchbase.com/organization/ably">others</a>, and our customers are using our realtime APIs to power live and collaborative experiences for more than 300m people each month.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JipH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JipH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 424w, https://substackcdn.com/image/fetch/$s_!JipH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 848w, https://substackcdn.com/image/fetch/$s_!JipH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 1272w, https://substackcdn.com/image/fetch/$s_!JipH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JipH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png" width="512" height="263" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92504c2f-7a90-4781-a43c-58f25029c678_512x263.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:263,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!JipH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 424w, https://substackcdn.com/image/fetch/$s_!JipH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 848w, https://substackcdn.com/image/fetch/$s_!JipH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 1272w, https://substackcdn.com/image/fetch/$s_!JipH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92504c2f-7a90-4781-a43c-58f25029c678_512x263.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://ably.com/">Ably</a> is a serverless WebSocket PaaS operating at the edge. There&#8217;s no infrastructure to provision or manage, just an evolving suite of <a href="https://ably.com/download">SDKs</a> and APIs that give you the freedom and flexibility to power live and collaborative experiences with a few lines of code. Our <a href="https://ably.com/four-pillars-of-dependability">mathematically modeled system</a> design provides a <a href="https://ably.com/network">globally-distributed edge network</a> that brings users closer to your app, unique data ordering and delivery guarantees to ensure a seamless end-user experience, a legitimate 99.999% uptime SLA underpinned by fault tolerant infrastructure, and instant elasticity to enable effortless scale.<br><a href="https://ably.com/">Find out more about Ably</a>.</p>]]></content:encoded></item><item><title><![CDATA[Capybara Screenshot 1.0.0]]></title><description><![CDATA[3 years ago, being a newbie to Ruby and Rails, I found the acceptance test workflow tedious, specifically in regards to trying to debugging failing full stack browser tests.]]></description><link>https://blog.mattheworiordan.com/p/capybara-screenshot-100</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/capybara-screenshot-100</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Wed, 30 Apr 2014 22:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3fsF!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eacf3c0-ef5e-4f3b-af97-e63f52160885_226x226.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>3 years ago, being a newbie to Ruby and Rails, I found the acceptance test workflow tedious, specifically in regards to trying to debugging failing full stack browser tests. Inspired by a <a href="https://github.com/mocoso/cucumber-screenshot">gem by Joel Chippindale</a>, I created <a href="https://github.com/mattheworiordan/capybara-screenshot">Capybara Screenshot</a> with the aim of providing automatic screenshots for any testing framework using <a href="https://github.com/jnicklas/capybara">Capybara</a>.</p><p>Today, I am proud to say the <a href="https://github.com/jnicklas/capybara">Capybara Screenshot gem</a> has finally reached a stable version release of 1.0.0, and supports RSpec, Cucumber, Spinach, MiniTest and TestUnit. And impressively, according to RubyGems, it has now had more than 550,000 downloads to date, equivalent to roughly 1% Rails&#8217; downloads.</p><p>If those numbers are at all accurate, and this gem is helping even 1% of the Rails community, then I am a happy man for contributing something back.</p><p>View the <a href="https://github.com/mattheworiordan/capybara-screenshot/blob/master/CHANGELOG.md">changelog for the 1.0.0 release</a>.</p>]]></content:encoded></item><item><title><![CDATA[Part 2: How elastic are Amazon Elastic Load Balancers (ELB)? Very!]]></title><description><![CDATA[For those of you who have not read part 1 of this post, I recommend you take a look at the original ELB post where I briefly described my experience testing ELB to see how elastic it truly is before we roll it out into production.]]></description><link>https://blog.mattheworiordan.com/p/part-2-how-elastic-are-amazon-elastic</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/part-2-how-elastic-are-amazon-elastic</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Sun, 30 Sep 2012 22:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3fsF!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3eacf3c0-ef5e-4f3b-af97-e63f52160885_226x226.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For those of you who have not read part 1 of this post, I recommend you take a look at the <a href="https://mattheworiordan.substack.com/p/how-elastic-are-amazon-elastic-load">original ELB post</a> where I briefly described my experience testing <a href="http://aws.amazon.com/elasticloadbalancing/">ELB</a> to see how elastic it truly is before we roll it out into production. We are building a highly concurrent socket &amp; websocket based system, and we expect upwards of 10k SSL (SSL is the important bit) new connection requests per second. We thought about building our own HAProxy + SSL termination solution, but to be honest the work in building an auto-scaling, resilient, multi-region load balancer is no mean feat, and something we&#8217;d prefer to avoid.</p><p>In order to understand the significance of the expected volume of 10k SSL requests per second, a single Amazon EC2 small instance can terminate approximately 25 2048bit SSL connections per second. If we were to terminate these connections ourselves using small instances, then we&#8217;d need at least 400 small instances running simultaneously with an even spread of traffic through a DNS load balancer to achieve this. Personally, I don&#8217;t like the idea of managing 400 CPUs (equivalent of a small instance) at each of our locations.</p><p>Hence we turned to <a href="http://aws.amazon.com/elasticloadbalancing/">ELB</a> and started running our tests to see if it would scale as needed and deliver. One thing to bear in mind with ELB is that it does not officially support <a href="http://en.wikipedia.org/wiki/WebSocket">WebSockets</a>, so in order to use ELB you have to configure it to balance using TCP sockets on port 80 and 443, which works fine except that the source IP is not available. I am told Amazon are working on a solution, but at present none exists, and it&#8217;s not such a big problem for us anyway.</p><p>With the help of Spencer at Amazon, who was incredibly helpful throughout the entire process (which lasted more than 2 weeks), we managed to get to a point where we knew the tests were accurate, any bottle necks that we found were indeed ELB and not caused by other factors, and we could replicate our tests easily. Spencer set up <a href="http://aws.amazon.com/cloudformation/">CloudFormation</a> templates (awesome stuff) so that we could spin up the servers and the load testing clients in the same configuration each time, and I worked on building a simple WebSocket server, a WebSocket testing client, and a controller app (based on <a href="https://github.com/newsapps/beeswithmachineguns">Bees With Machine Guns</a>) so that we could spin up any number of load testing clients we needed, and start a progressive and realistic attack on the load balancers. On Github you can find my core repositories for the <a href="https://github.com/mattheworiordan/websocket-load-test">WebSocket load testing client and server</a>, and the modified <a href="https://github.com/mattheworiordan/beeswithmachineguns">Bees With Machine Guns</a> that does not rely on SSH connections as I found these to be unreliable when you spin up more than 10 load testing machines (we went up to 80 c1.medium).</p><p>In summary, the results were very encouraging, but certainly not perfect. In my original post I alleged that ELB was flat lining at around 2k requests per second, unfortunately this was wrong, and was caused by me due to the way the testing clients were designed. Once I made the controller more reliable, made the load testing client not wait for connections to close, and replicated more realistic traffic growth, then when I ran the tests myself in my EC2 cloud I easily got to 10k requests per second, and so did Spencer (Amazon) with his tests using CloudFormation and the libraries described above. What we found is that ELB does seem to have <strong>unlimited scaling capabilities</strong>, however it doesn&#8217;t necessarily scale as fast as you want it to all the time. If you look at the graphs below, you will see plenty of dips where we would expect ELB to scale up horizontally to cope with more demand, yet it doesn&#8217;t until some time passess. Eventually ELB does catch up, but it&#8217;s worth bearing in mind that if you get spikes in traffic, latency will increase and potentially some connections may drop as ELB plays catch up.</p><p><strong>My tests using ELB and EC2 showing expected versus actual in terms of new SSL connections per second</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!noGE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!noGE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 424w, https://substackcdn.com/image/fetch/$s_!noGE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 848w, https://substackcdn.com/image/fetch/$s_!noGE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 1272w, https://substackcdn.com/image/fetch/$s_!noGE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!noGE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png" width="500" height="258" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:258,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image" title="image" srcset="https://substackcdn.com/image/fetch/$s_!noGE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 424w, https://substackcdn.com/image/fetch/$s_!noGE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 848w, https://substackcdn.com/image/fetch/$s_!noGE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 1272w, https://substackcdn.com/image/fetch/$s_!noGE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff888f8b1-105e-426f-8888-aaeaf3ec89e3_500x258.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Amazon&#8217;s (Spencer) test on ELB where we expect a smooth bicubic curve</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z-XD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z-XD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 424w, https://substackcdn.com/image/fetch/$s_!Z-XD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 848w, https://substackcdn.com/image/fetch/$s_!Z-XD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 1272w, https://substackcdn.com/image/fetch/$s_!Z-XD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z-XD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png" width="500" height="254" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:254,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image" title="image" srcset="https://substackcdn.com/image/fetch/$s_!Z-XD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 424w, https://substackcdn.com/image/fetch/$s_!Z-XD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 848w, https://substackcdn.com/image/fetch/$s_!Z-XD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 1272w, https://substackcdn.com/image/fetch/$s_!Z-XD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a005db4-fda2-4f14-9de4-d976f6042aaf_500x254.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So to summarise:</p><ul><li><p><a href="http://aws.amazon.com/elasticloadbalancing/">ELB</a> is pretty damn awesome and scales incredibly (pretty much limitlessly it seems)</p></li><li><p><a href="http://aws.amazon.com/elasticloadbalancing/">ELB</a> has its problems and is not perfect. It&#8217;s designed to scale as necessary, but your traffic growth may exceed ELB&#8217;s natural scale-out algorithms meaning you will experience latency or dropped connections for short periods.</p></li><li><p>We&#8217;re going to be using ELB as we believe it&#8217;s the best solution out there by a long stretch (we considered hardware load balancing &amp; SSL termination, we considered Rackspace, GoGrid, and a bunch of others).</p></li><li><p>Amazon have been amazingly helpful throughout this exercise, way beyond what I could have expected.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[How elastic are Amazon Elastic Load Balancers (ELB)? Not very it seems]]></title><description><![CDATA[Update: Since I made this post, Amazon have in fact been in touch and have been extremely helpful looking into this issue and running numerous tests to ensure ELB is performing as it should.]]></description><link>https://blog.mattheworiordan.com/p/how-elastic-are-amazon-elastic-load</link><guid isPermaLink="false">https://blog.mattheworiordan.com/p/how-elastic-are-amazon-elastic-load</guid><dc:creator><![CDATA[Matthew O'Riordan]]></dc:creator><pubDate>Tue, 31 Jul 2012 22:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!N5Jn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Update: Since I made this post, Amazon have in fact been in touch and have been extremely helpful looking into this issue and running numerous tests to ensure ELB is performing as it should. In short, many of the tests in this post are wrong.</p><p>Please go to <a href="https://mattheworiordan.substack.com/p/part-2-how-elastic-are-amazon-elastic">Part 2: How elastic are Amazon Elastic Load Balancers (ELB)? Very.</a></p></blockquote><p>Recently I&#8217;ve been working on a project that will feasibly need to respond to 10,000+ SSL web socket connection requests per second, and I&#8217;ve been racking my brain as to figure out what type of infrastructure I would need to cope with that.</p><p>I did some initial tests and determined that a single CPU instance on EC2 (with 1 EC2 compute power) can cope with a measly 25 SSL handshakes per second. Based on my 10k target, that means I would need 400 CPU instances on EC2 just to deal with handshakes. I soon learn that the certificate key size is paramount, and dropping from the normal 2048 bit key down to 1024 bit improves performance 5 fold, so that now means I only need 80 CPU instances. Still way too many instances, and to be honest, not a piece of architecture I particularly want to look after either as I will need to build a system that can auto-scale on demand.</p><p>So I started experimenting with Amazon&#8217;s Elastic Load Balancers on the premise that they are <strong>elastic</strong>. I ran some quick apache bench tests against an ELB server and unsurprisingly got 25 SSL handshakes per second throughput with a 2048 bit key. So I can deduce that an ELB when it starts out is simply a single CPU instance on EC2. I then tried to run apache bench for 30 minutes to see how ELB scales, but unfortunately quickly discovered that that type of test is quite contrived, and ELB scales out dynamically using DNS. So a single load test client would only ever hit one ELB instance, and as such, ELB may not scale as only one IP is hitting it and even if it did, the client would never be able to benefit from that scaling.</p><p>So I went ahead and built a load testing farm of daemons that distribute their &#8220;attack&#8221; on the ELB from loads of different IP addresses (I spun up 40+ micro instances on EC2), and will cleverly keep querying DNS to see when ELB scales and distribute traffic to the new IP addresses that ELB responds to for its public DNS name.</p><p>And my findings were interesting, and disappointing. It seems that ELB does in fact scale, but for some reason I am hitting a hard limit for some reason or another. Perhaps Amazon have set a hard limit for some reason, perhaps I need to have something enabled on my account, or perhaps ELB is just not as elastic as it&#8217;s claimed to be. I&#8217;ll only find out if Amazon get in touch with me to explain ;)</p><p>Here is a graph demonstrating the attempted requests per second from my load testing daemons that scaled up request from 50 per second in minute one, up to 6,000 requests per second in the 120th minute. As you can see, other than a few more small upward blips, ELB pretty much flattens out at around 2,000 requests per second with a 1024 bit key and ELB spread across 3 zones (and thus 3 instances).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N5Jn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N5Jn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 424w, https://substackcdn.com/image/fetch/$s_!N5Jn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 848w, https://substackcdn.com/image/fetch/$s_!N5Jn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 1272w, https://substackcdn.com/image/fetch/$s_!N5Jn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N5Jn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png" width="500" height="335" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:335,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image" title="image" srcset="https://substackcdn.com/image/fetch/$s_!N5Jn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 424w, https://substackcdn.com/image/fetch/$s_!N5Jn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 848w, https://substackcdn.com/image/fetch/$s_!N5Jn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 1272w, https://substackcdn.com/image/fetch/$s_!N5Jn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f57a132-379b-4b2e-916a-2b55246fe9dc_500x335.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If anyone has any suggestions or feedback on how to make ELB scale as it should, please do get in touch. I&#8217;ve posted my findings into the Amazon forums <a href="https://forums.aws.amazon.com/message.jspa?messageID=282843#282843">here</a> and <a href="https://forums.aws.amazon.com/message.jspa?messageID=321341#321341">here</a>, <s>but I have little hope that Amazon themselves will respond</s> (see below, Amazon did get in touch and have been brilliant!).</p><p>In the mean time, it looks like I&#8217;ll be finding another solution.</p><blockquote><p>Update: Since I made this post, Amazon have in fact been in touch and have been extremely helpful looking into this issue and running numerous tests to ensure ELB is performing as it should. In short, many of the tests in this post are wrong.</p><p>Please go to <a href="https://mattheworiordan.substack.com/p/part-2-how-elastic-are-amazon-elastic">Part 2: How elastic are Amazon Elastic Load Balancers (ELB)? Very.</a></p></blockquote>]]></content:encoded></item></channel></rss>