<?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[AnyCable Broadcasts]]></title><description><![CDATA[News and stories on building realtime functionality in modern apps, with productivity and scalability in mind.]]></description><link>https://blog.anycable.io</link><image><url>https://substackcdn.com/image/fetch/$s_!gEuI!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee4b1ee-eca5-41e8-9d08-d39e95284694_1280x1280.png</url><title>AnyCable Broadcasts</title><link>https://blog.anycable.io</link></image><generator>Substack</generator><lastBuildDate>Mon, 06 Apr 2026 19:35:24 GMT</lastBuildDate><atom:link href="https://blog.anycable.io/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Evil Martians Inc.]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[anycable@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[anycable@substack.com]]></itunes:email><itunes:name><![CDATA[AnyCable]]></itunes:name></itunes:owner><itunes:author><![CDATA[AnyCable]]></itunes:author><googleplay:owner><![CDATA[anycable@substack.com]]></googleplay:owner><googleplay:email><![CDATA[anycable@substack.com]]></googleplay:email><googleplay:author><![CDATA[AnyCable]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Any Cables #33: Durable at Once]]></title><description><![CDATA[January &#8211; February 2026]]></description><link>https://blog.anycable.io/p/any-cables-33-durable-at-once</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-33-durable-at-once</guid><dc:creator><![CDATA[Irina Nazarova]]></dc:creator><pubDate>Tue, 10 Feb 2026 15:05:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SHC1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The word &#8220;durable&#8221; keeps showing up. Durable Streams, DurableAgent, durable sessions. After years of treating realtime as fire-and-forget, the ecosystem is converging on the idea that messages should survive disconnects. Here&#8217;s what happened in January and February.</p><div><hr></div><h2>Highlights</h2><p><strong><a href="https://github.com/anycable/anycable/releases/tag/v1.6.9">AnyCable 1.6.9: Durable Streams support</a> </strong></p><p>The headliner: AnyCable now speaks <a href="https://docs.anycable.io/anycable-go/durable_streams">Durable Streams</a>&#8212;an open HTTP protocol for reliable, resumable data streaming from ElectricSQL.</p><p>We announced the gradual adoption of the protocol in the <a href="https://evilmartians.com/chronicles/anycable-rails-and-the-pitfalls-of-llm-streaming">AnyCable, Rails, and the pitfalls of LLM-streaming</a> post back in December. Well, &#8220;gradual&#8221; happened faster than expected&#8212;with AnyCable v1.6.9, the read side is done. Your clients can now consume AnyCable streams using any Durable Streams-compatible client. You still publish via the AnyCable API (broadcasting), but on the read side, it&#8217;s an open standard. No vendor lock-in, no proprietary protocol required.</p><p>Other highlights from the release:</p><ul><li><p><strong>New REST API</strong> for publishing broadcasts and querying presence from any HTTP client&#8212;no SDK required (<a href="https://docs.anycable.io/anycable-go/api">docs</a>)</p></li><li><p><strong>Pusher Get Channel Users API</strong> to simplify the migration to AnyCable (<a href="https://docs.anycable.io/anycable-go/pusher?id=get-channel-users">docs</a>).</p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/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 AnyCable Broadcasts! Subscribe for free to receive new posts.</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><div><hr></div><h2>News</h2><p><strong><a href="https://www.heroku.com/blog/an-update-on-heroku/"><s>An update on</s> The end of Heroku</a></strong></p><p>Sad (but kinda expected) news: Heroku is turning on maintenance mode (read: &#8220;we&#8217;re gradually sunsetting our operations&#8221;). If you&#8217;re using it and have been expecting to rely on it in the mid- to long-term, you need to start looking for alternatives.</p><p>Today, there are plenty of PaaS platforms offering a <em>Heroku-like experience</em> (I&#8217;m pretty sure we&#8217;ll continue using this term even when Heroku is no more). Self-hosting is also not rocket science anymore; the variety ranges from Kamal to Kubernetes kits.</p><p>We decided to check the distribution of deployment platforms among AnyCable users (based on the anonymized telemetry we collect) and got the following results:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5K_q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5K_q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 424w, https://substackcdn.com/image/fetch/$s_!5K_q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 848w, https://substackcdn.com/image/fetch/$s_!5K_q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 1272w, https://substackcdn.com/image/fetch/$s_!5K_q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5K_q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png" width="1456" height="551" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:551,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105887,&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.anycable.io/i/187464910?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.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_!5K_q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 424w, https://substackcdn.com/image/fetch/$s_!5K_q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 848w, https://substackcdn.com/image/fetch/$s_!5K_q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.png 1272w, https://substackcdn.com/image/fetch/$s_!5K_q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb194c7a6-b195-4c47-b100-062faf05d38b_2004x758.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>Out of the identified platforms (you see the &#8220;None&#8221; at the bottom&#8212;it&#8217;s everything from self-hosted and local runs to k8s clusters), Heroku is 2nd, with ECS/Fargate as the leader. Not suggesting anything, just sharing our data. (But you need help in picking and implementing the escape strategy, <a href="https://evilmartians.com/">Evil Martians</a> are here to help.)</p><p><strong><a href="https://electric-sql.com/blog/2026/01/22/announcing-hosted-durable-streams">Durable Streams on Electric Cloud</a></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_!b-6X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b-6X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!b-6X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!b-6X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!b-6X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b-6X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&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_!b-6X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!b-6X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!b-6X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!b-6X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d4161cf-c2fd-4b1c-91f8-5bb3e4ad7f31_1376x768.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>Since we covered the original <a href="https://blog.anycable.io/p/any-cables-32-2025-is-over">announcement in #32</a>, ElectricSQL shipped fast: from <a href="https://electric-sql.com/blog/2025/12/23/durable-streams-0.1.0">v0.1.0 (NPM) </a> on Dec 23 to the <a href="https://electric-sql.com/blog/2026/01/22/announcing-hosted-durable-streams">hosted cloud along with v0.2.0</a> on Jan 22. The new version also comes with the Idempotent Producer specification&#8212;don&#8217;t even try to publish your message twice! We, Team AnyCable, are glad to be in the company of <a href="https://electric-sql.com/blog/2025/12/23/durable-streams-0.1.0#new-implementations">early adopters</a> of this new, exciting technology. Are you durable streaming yet?</p><p><strong><a href="https://valkey.io/blog/introducing-valkey-9/">Valkey 9.0: innovation, features, and improvements</a></strong></p><p>The announcement is not fresh, but we decided that it deserves more attention. Why? First of all, Valkey has finally caught up on the Redis features released in 7.4 (right after the change in the Redis licensing policy, and thus not available to other cloud providers). For example, the family of Hash field expiration commands (<a href="https://valkey.io/commands/hexpire/">HEXPIRE</a> et al) is now supported, making Valkey compatible with AnyCable Presence implementation.</p><div><hr></div><h1>Videos</h1><p><strong><a href="https://www.rubyevents.org/talks/real-time-collaboration-with-rails-anycable-and-yjs?back_to=%2Fevents%2Fsfruby-2025%2Ftalks%3Fscroll_top%3D741&amp;back_to_title=San+Francisco+Ruby+Conference+2025">Real-time Collaboration with Rails, AnyCable and Yjs (JP Camara @ SF Ruby Conference)</a></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_!SHC1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SHC1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 424w, https://substackcdn.com/image/fetch/$s_!SHC1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 848w, https://substackcdn.com/image/fetch/$s_!SHC1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 1272w, https://substackcdn.com/image/fetch/$s_!SHC1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SHC1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png" width="1456" height="817" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:817,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3991086,&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.anycable.io/i/187464910?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.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_!SHC1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 424w, https://substackcdn.com/image/fetch/$s_!SHC1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 848w, https://substackcdn.com/image/fetch/$s_!SHC1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.png 1272w, https://substackcdn.com/image/fetch/$s_!SHC1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca6f6373-44ea-4bd4-a0ae-1527169731d6_3022x1696.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>All 32 talks from <a href="https://sfruby.com/">SF Ruby Conference 2025</a> are published on <a href="https://www.rubyevents.org/events/sfruby-2025/talks">sfruby.com/talks</a>. Check them all out!</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://intertwingly.net/blog/2026/01/06/Rails-Apps-on-V8-Isolates.html">Rails Apps on V8 Isolates</a></strong></p><p>Can you imagine running a Rails app on V8 (JS runtime) for serverless sake? No need to imagine, Sam Ruby is already bringing this to life. Realtime-wise, check out the <a href="https://www.ruby2js.com/docs/juntos/demos/chat">chat demo</a>: <strong>Action Cable backed by Broadcast Channel</strong> (do you remember we shared the same idea when talked about <a href="https://blog.anycable.io/p/any-cables-monthly-23-its-a-rails">Rails on Wasm in #23</a>).</p><div><hr></div><h2>Releases</h2><p><strong><a href="https://github.com/anycable/anycable/releases/tag/v1.6.9">anycable &#183; 1.6.9</a></strong></p><p>We&#8217;ve already mentioned Durable Streams and REST API additions. Another noticeable addition is a <strong>mTLS support for Redis </strong>(or Valkey). </p><p><strong><a href="https://github.com/anycable/anycable-laravel">anycable-laravel &#183; 0.3.0</a></strong></p><p>We changed the way the server is configured when running the <code>php artisan anycable:server</code> command to use Laravel configuration. (Thanks for <a href="https://github.com/anycable/anycable-laravel/issues/4">the feedback</a> from our AnyCable Laravel early adopters!).</p><p><strong><a href="https://github.com/loro-dev/loro/releaseshttps://github.com/loro-dev/loro">loro &#183; 1.10</a></strong></p><p>Loro is a Y.js alternative built in Rust by an independent team. Loro produces cleaner merges thanks to the <a href="https://arxiv.org/abs/2305.00583">Fugue algorithm</a>. It also keeps full editing history by default&#8212;you get Git-like time travel without bolting on extra storage. Bindings exist for JS/WASM, Swift, Python, and React Native, plus <a href="https://github.com/loro-dev/loro-prosemirror">ProseMirror</a> and <a href="https://github.com/loro-dev/loro-codemirror">CodeMirror</a> integrations.</p><p><strong><a href="https://github.com/centrifugal/centrifugo/releases/tag/v6.6.0">centrifugo &#183; 6.6.0</a></strong></p><p>The release notes are read as a year-end recap: v6, async consumers, server-side publication filtering, WebSocket over HTTP/2, C# SDK, 7k+ installations.</p><p><strong><a href="https://laravel-news.com/everything-new-in-livewire-4">livewire &#183; 4.0.0</a></strong></p><p>Livewire 4 makes building reactive web applications (in PHP) with no JavaScript even simpler: now, you can mix PHP, view templates, styles and JavaScript (&#8220;no&#8221; doesn&#8217;t mean &#8220;never&#8221;) in a single file! (I have strong <a href="https://en.wikipedia.org/wiki/MXML">MXML</a> vibes &#128513;.)</p><div><hr></div><h2>Frame of curiosity: Who&#8217;s next? Pusher? </h2><p>Heroku has become synonymous with the &#8220;git push&#8221; deployment experience. It&#8217;s been the default for Ruby on Rails applications for years. And now what? It&#8217;s over.</p><p><strong>What other PaaS services will repeat the fate of Heroku?</strong> Who pioneered a field, set the standard, and is now struggling to compete in a new world full of other vendors and viable open-source alternatives? The first project that comes to mind is Pusher.</p><p>For years, Pusher has been the default answer to &#8220;how do I add realtime to my app?&#8221; Easy to start, SDKs everywhere, it Just Works&#8482;. While everyone was afraid of self-hosting WebSockets, Pusher offered an easy way out. Don&#8217;t underestimate the power of irrational fear: even though open-source reverse-engineered alternatives have been known for almost as long as Pusher exists, they were barely used outside of local setups and experimental projects (I remember suggesting switching to <a href="https://github.com/edgurgel/poxa">Poxa</a>, an Elixir-driven OSS alternative, back in 2016&#8212;that was a hard sale, we failed).</p><p>Pusher&#8217;s protocol became a de facto standard. Laravel built its entire Broadcasting layer around it. Countless apps speak Pusher protocol without thinking twice. Well, <strong>until the invoice arrives</strong>. Or you need <strong>delivery guarantees.</strong> Or you want your <strong>data on your infrastructure</strong>.</p><p>The demand for real-time features in 2026 is not the same as in 2016 (no, I don&#8217;t want my 2016 back; I live today). The supply has changed too: more PaaS options arrived, popular frameworks got built-in real-time engines (Action Cable in Rails, Reverb in Laravel), new protocols emerged to satisfy new needs (yes, I&#8217;m talking about Durable Streams, again). And Pusher stays basically the same, not from the features they offer but from the way developers use it.</p><p>We&#8217;ve seen many applications using Pusher, many developers unsatisfied with its features and limitations, and managers unsatisfied with the bills. That triggered our decision to support the <a href="http://as%20soon%20as%20we%20released%20Pusher%20compatibility,">Pusher interface in AnyCable</a>. The goal is not to lure the clients but to provide a smooth migration path towards better realtime UX.</p><p>Today, switching your application from Pusher (PaaS) to AnyCable is just a matter of configuration. This is the first phase. After finishing the infrastructure migration, you can gradually migrate to other protocols better suited to your needs: whether it&#8217;s server-sent events, or durable streams, or reliable WebSockets backed by the AnyCable protocol&#8212;the choice is yours and yours only.</p><p>The future of realtime web must be reliable and affordable. Be a part of it and don&#8217;t let the next &#8220;An update on &#8230;&#8221; post take you by surprise.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/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 AnyCable Broadcasts! 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[Any Cables #32: 2025 is over 🎅]]></title><description><![CDATA[December, 2025]]></description><link>https://blog.anycable.io/p/any-cables-32-2025-is-over</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-32-2025-is-over</guid><pubDate>Tue, 23 Dec 2025 19:29:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4iBK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey everyone! This is a last issue of our <s>monthly</s> (well, no longer) newsletter this year, 2026 is just around the corner. <strong>Happy holidays! Let your 2026 be reliable and predictable!</strong></p><p>In this issue, we&#8217;ll cover all interesting stuff happened in the last few months.</p><div><hr></div><h1>News</h1><p><strong><a href="https://github.com/basecamp/fizzy">37signals released Fizzy</a></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_!C1HT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C1HT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 424w, https://substackcdn.com/image/fetch/$s_!C1HT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 848w, https://substackcdn.com/image/fetch/$s_!C1HT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 1272w, https://substackcdn.com/image/fetch/$s_!C1HT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C1HT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png" width="1456" height="627" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:627,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Screenshot of a Fizzy board&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="Screenshot of a Fizzy board" title="Screenshot of a Fizzy board" srcset="https://substackcdn.com/image/fetch/$s_!C1HT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 424w, https://substackcdn.com/image/fetch/$s_!C1HT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 848w, https://substackcdn.com/image/fetch/$s_!C1HT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.png 1272w, https://substackcdn.com/image/fetch/$s_!C1HT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76eea11b-099c-478e-bb92-18a294811ea0_3168x1365.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><a href="https://www.fizzy.do/">Fizzy</a> is a (kinda) open source Kanban-style task manager. All its real-time features are powered by Turbo Streams (and <a href="https://github.com/basecamp/fizzy/blob/main/app/models/board/broadcastable.rb">Page Refreshes</a>). You can use a SaaS version or host it yourself (and, you can modify it: for example, migrate to AnyCable &#128513;).</p><p><strong><a href="https://electric-sql.com/blog/2025/12/09/announcing-durable-streams">Announcing Durable Streams</a></strong></p><p>Team ElectricSQL announced a new HTTP standard proposal&#8212;<a href="https://github.com/durable-streams/durable-streams">Durable Streams</a>.</p><blockquote><p>The core idea: streams are a first-class primitive that get their own URL. Each stream is an addressable, append-only log that clients can read from any position.</p></blockquote><p>We at AnyCable have already started adopting the new spec, so stay tuned for the updates early next year!</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://evilmartians.com/chronicles/anycable-rails-and-the-pitfalls-of-llm-streaming">AnyCable, Rails, and the pitfalls of LLM-streaming</a></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_!4iBK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4iBK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!4iBK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!4iBK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!4iBK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4iBK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png" width="500" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Cover for AnyCable, Rails, and the pitfalls of LLM-streaming&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="Cover for AnyCable, Rails, and the pitfalls of LLM-streaming" title="Cover for AnyCable, Rails, and the pitfalls of LLM-streaming" srcset="https://substackcdn.com/image/fetch/$s_!4iBK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 424w, https://substackcdn.com/image/fetch/$s_!4iBK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 848w, https://substackcdn.com/image/fetch/$s_!4iBK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.png 1272w, https://substackcdn.com/image/fetch/$s_!4iBK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c36f5d5-0784-4abe-a48f-c0584ebeaf65_500x500.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>This post demonstrates UI/UX <em>hallucinations</em> that could happen when streaming LLM responses over not-so-reliable <em>channels</em> (like Action Cable).</p><p><strong><a href="https://island94.org/2025/10/notes-from-building-a-who-is-doing-what-right-now-on-our-website-presence-feature-with-action-cable">Notes from building a &#8220;who is doing what right now on our website?&#8221; presence feature with Action Cable</a></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_!Sa2t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Sa2t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Sa2t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Sa2t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Sa2t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Sa2t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg" width="1456" height="656" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:656,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A screenshot of my application with little presence indicators decorating content&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="A screenshot of my application with little presence indicators decorating content" title="A screenshot of my application with little presence indicators decorating content" srcset="https://substackcdn.com/image/fetch/$s_!Sa2t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Sa2t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Sa2t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Sa2t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F196685ef-29dd-470f-9d57-fed9289d6963_1990x896.jpeg 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>Ben shares the story of building a presence feature in a an Action Cable-backed Rails application. </p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/anycable/releases">anycable &#183; 1.6.7-1.6.8</a></strong></p><p>The recent releases of AnyCable bring more stability, performance, and observability improvements, as well as security fixes. Please, upgrade! &#8252;&#65039;</p><p><strong><a href="https://github.com/anycable/anycable-rails">anycable-rails &#183; 1.6.1</a></strong></p><p>We&#8217;ve upgraded our interactive installer, so it fits new Rails defaults better, and helps you set up AnyCable in a <a href="https://docs.anycable.io/anycable-go/reliable_streams">reliable mode</a> right away.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XhNG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XhNG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 424w, https://substackcdn.com/image/fetch/$s_!XhNG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 848w, https://substackcdn.com/image/fetch/$s_!XhNG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 1272w, https://substackcdn.com/image/fetch/$s_!XhNG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XhNG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png" width="1500" height="694" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f74266d1-8969-417c-ae71-172226538367_1500x694.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:694,&quot;width&quot;:1500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:318237,&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.anycable.io/i/182319664?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1550d669-bbd5-4af1-b747-0cbef0f64e4c_1500x868.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_!XhNG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 424w, https://substackcdn.com/image/fetch/$s_!XhNG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 848w, https://substackcdn.com/image/fetch/$s_!XhNG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.png 1272w, https://substackcdn.com/image/fetch/$s_!XhNG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff74266d1-8969-417c-ae71-172226538367_1500x694.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 class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3ZRJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 424w, https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 848w, https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 1272w, https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png" width="1494" height="683" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:683,&quot;width&quot;:1494,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:417066,&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.anycable.io/i/182319664?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d38489-97f6-46eb-909f-d597e61f1271_1494x866.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_!3ZRJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 424w, https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 848w, https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.png 1272w, https://substackcdn.com/image/fetch/$s_!3ZRJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5db4e1a-a067-4b72-990a-756ba9142d49_1494x683.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><a href="https://github.com/rubys/turbo_cable">turbo_cable</a></strong></p><p>A custom (and minimal) Ruby WebSocket server for Turbo Streams.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #31: Why.js?]]></title><description><![CDATA[September, 2025]]></description><link>https://blog.anycable.io/p/any-cables-monthly-31-whyjs</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-31-whyjs</guid><pubDate>Tue, 07 Oct 2025 19:24:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vF5l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Good news, everyone! We&#8217;re back from our vacation and ready to present all the real-time-ish stuff happened in the last three months. Buckle up!</p><div><hr></div><h1>Highlights</h1><p><strong><a href="https://docs.anycable.io/pro/install?id=anycable-thruster-pro">AnyCable Thruster Pro </a></strong></p><p>As Thruster becomes more popular in the Rails world, so does its <a href="https://github.com/anycable/thruster">AnyCable-d version</a>. It&#8217;s not surprising: running AnyCable for Rails with Thruster is as simple as changing a line in the Gemfile!</p><p>Now, you can also switch to AnyCable Pro with a one more configuration change!</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://evilmartians.com/chronicles/anycable-for-laravel">AnyCable for Laravel: reliable WebSocket infrastructure</a></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_!vF5l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vF5l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 424w, https://substackcdn.com/image/fetch/$s_!vF5l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 848w, https://substackcdn.com/image/fetch/$s_!vF5l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 1272w, https://substackcdn.com/image/fetch/$s_!vF5l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vF5l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png" width="1456" height="662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:662,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:546978,&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.anycable.io/i/175514565?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.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_!vF5l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 424w, https://substackcdn.com/image/fetch/$s_!vF5l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 848w, https://substackcdn.com/image/fetch/$s_!vF5l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.png 1272w, https://substackcdn.com/image/fetch/$s_!vF5l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F089a6b72-3fb6-472b-b3ed-f69c353de8d2_1926x876.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>We continue our work on AnyCable integration for Laravel. This post introduces AnyCable&#8217;s Pusher (and, thus, Reverb) protocol compatibility and a <a href="https://github.com/anycable/anycable-client/tree/master/packages/echo">dedicated Echo adapter</a>. It also includes load testing results and comparisons (no spoilers, go to the post to see the numbers). </p><div><hr></div><h1>Videos</h1><p><strong><a href="https://www.youtube.com/watch?v=AnbWtyB3pcQ">Phoenix LiveView: Mastering Reconnects for a Seamless User Experience</a></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_!wunv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wunv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 424w, https://substackcdn.com/image/fetch/$s_!wunv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 848w, https://substackcdn.com/image/fetch/$s_!wunv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 1272w, https://substackcdn.com/image/fetch/$s_!wunv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wunv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png" width="1456" height="716" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:716,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:351558,&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.anycable.io/i/175514565?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.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_!wunv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 424w, https://substackcdn.com/image/fetch/$s_!wunv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 848w, https://substackcdn.com/image/fetch/$s_!wunv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.png 1272w, https://substackcdn.com/image/fetch/$s_!wunv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe80f5ec-512f-445a-8a5f-c854e3d2e216_1778x874.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>This talk from ElixirConf EU 2025 explores the problem of restoring a connection state (more precisely, a LiveView component&#8217;s state) on reconnect. There are a few techniques presented, most are specific to LiveView, except the very last one (which I liked the most): <strong>Prefer &#8220;I haven&#8217;t figured out&#8221; mindset over &#8220;It&#8217;s a technology limitation&#8221;.</strong></p><p><strong><a href="https://www.youtube.com/watch?v=UftT4YiIla8">Klipshow From Scratch Ep. 4: Real-Time WebSocket Alerts + OBS Integration + AnyCable Architecture</a></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_!KXP3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KXP3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 424w, https://substackcdn.com/image/fetch/$s_!KXP3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 848w, https://substackcdn.com/image/fetch/$s_!KXP3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 1272w, https://substackcdn.com/image/fetch/$s_!KXP3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KXP3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png" width="1456" height="823" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:823,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:820716,&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.anycable.io/i/175514565?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.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_!KXP3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 424w, https://substackcdn.com/image/fetch/$s_!KXP3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 848w, https://substackcdn.com/image/fetch/$s_!KXP3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.png 1272w, https://substackcdn.com/image/fetch/$s_!KXP3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44bcee4-4eca-4e1d-a94a-cc17a039dcf6_2032x1148.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>In this YouTube series, Johny builds a production Rails/React application (Klipshow, a Twitch monetization platform) in real time and thoroughly explains everything he does. This show is a good collection of how-to-s for a variety of modern Ruby on Rails tools (Turbo, AnyCable, SolidQueue, etc.). Subscribe!</p><h1>Podcasts</h1><p><strong><a href="https://onrails.buzzsprout.com/2462975/episodes/17653501-ryan-stawarz-austin-story-inside-doximity-s-15-year-rails-monolith">OnRails: Inside Doximity&#8217;s 15-Year Rails Monolith</a></strong></p><blockquote><p>Throughout the episode, they share pragmatic insights into debugging at scale, managing one-off data migrations, and determining when a service should live inside or outside the monolith. They also reflect on their use of tools like <a href="https://github.com/Shopify/packwerk">Packwerk</a>, <a href="https://anycable.io/">AnyCable</a>, and <a href="https://github.com/departurerb/departure">Departure</a>, and how a culture of trust, documentation, and lightweight planning helps Doximity move fast without breaking things.</p></blockquote><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/anycable/releases">anycable &#183; 1.6.6</a></strong></p><p>We&#8217;ve released a few patch version of AnyCable during the summer with some tiny but helpful features. Check out the <a href="https://github.com/anycable/anycable/blob/main/CHANGELOG.md">change log</a>!</p><p><strong><a href="https://github.com/basecamp/once-campfire">once-campfire</a></strong></p><p>Campfire, a simple group chat app built at Basecamp, that was previously commercially available via the <a href="https://once.com/">Once model</a> is now open sourced! Feel free to play with it, modify and share your mods with the world! (That&#8217;s what we&#8217;re going to do soon &#128521;)</p><div><hr></div><h1><strong>Frame of curiosity: y-j-s</strong></h1><p>In just about a month, we&#8217;re holding the very first <strong><a href="https://sfruby.com/">SF Ruby Conference</a></strong>. Apart from various AI-related talks, there is one hidden gem (from this newsletter point of view)&#8212;a talk by JP Camara on <strong><a href="https://sfruby.com/schedule/#realtime-collaboration-rails">Real-time collaboration with Rails, AnyCable and Yjs</a></strong>. I don&#8217;t know (yet) what it&#8217;s gonna be about, but I have some thoughts on the subject I&#8217;d like to share.</p><blockquote><p>SF Ruby Conference is happening on <strong>November 19-20, 2025</strong>. Grab a ticket here: <em><strong><a href="https://luma.com/sfrubyconf2025?coupon=ANYCABLE">https://luma.com/sfrubyconf2025?coupon=ANYCABLE</a></strong></em> ($50 off!).</p></blockquote><p>So, what is Y.js, and why should you care? <a href="https://yjs.dev/">Y.js</a> is a CRDT (Conflict-free Replicated Data Type) library that solves the distributed state synchronization problem. In practical terms: it lets you build collaborative features where multiple users can edit the same data simultaneously, and all changes merge automatically without conflicts. Think Google Docs, but for any kind of shared state&#8212;collaborative whiteboards, forms, design tools, or even project management boards. If your users need to work together on something in real-time, Y.js handles the hard math so you don&#8217;t have to.</p><p>The Rails community has flirted with Y.js before. If you have been following us for a while, you should remember the <a href="https://github.com/y-crdt/yrb-actioncable">yrb-actioncable</a> project. However, we haven&#8217;t seen a lot of people building with it (probably, because it&#8217;s incompatible with AnyCable, and we mostly work with it).</p><p>But here&#8217;s the exciting part: recently, a <a href="https://github.com/skyterra/y-crdt">Go port of Y.js</a> has been released. Wait, Go? Yes! This changes everything. We can move all the CRDT complexity to AnyCable and expose a simple, clean API to bring collaborative features to any Rails (or PHP, or...) application. No more worrying about Ruby&#8217;s performance characteristics for handling high-frequency CRDT updates. No more binary protocol gymnastics in your application code. Just a straightforward API that lets you add &#8220;Google Docs-like&#8221; collaboration to your app!</p><p>That&#8217;s something we&#8217;ve been keeping in mind for a long time, and it seems it&#8217;s getting closer to reality. Sounds exciting to you? Let&#8217;s chat in San Francisco in November!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #30: Kamal, benchmarks, and ⛱️]]></title><description><![CDATA[June, 2025]]></description><link>https://blog.anycable.io/p/any-cables-monthly-30-kamal-benchmarks</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-30-kamal-benchmarks</guid><pubDate>Tue, 08 Jul 2025 23:00:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nLhM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>All the June we&#8217;ve been busy with the preparations for the final <a href="https://railsconf.org/">RailsConf</a> (that starts today; come say &#8220;Hi!&#8221;), so this issue is a bit short on updates (and <em>frames</em>). We&#8217;ve also decided to take some rest and spend the rest of summer newsletter-free &#127958;&#65039;. See you again this fall!</p><div><hr></div><h1>Highlights</h1><p><strong><a href="https://docs.anycable.io/deployment/kamal">AnyCable meets Kamal </a></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_!nLhM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nLhM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 424w, https://substackcdn.com/image/fetch/$s_!nLhM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 848w, https://substackcdn.com/image/fetch/$s_!nLhM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 1272w, https://substackcdn.com/image/fetch/$s_!nLhM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nLhM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png" width="720" height="439.61538461538464" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:889,&quot;width&quot;:1456,&quot;resizeWidth&quot;:720,&quot;bytes&quot;:137600,&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.anycable.io/i/167226900?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.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_!nLhM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 424w, https://substackcdn.com/image/fetch/$s_!nLhM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 848w, https://substackcdn.com/image/fetch/$s_!nLhM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.png 1272w, https://substackcdn.com/image/fetch/$s_!nLhM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71241b4c-52e4-410f-b6c2-f897e8afddd1_1560x952.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>You asked, we listened. Our documentation now includes a detailed guide on <a href="https://docs.anycable.io/deployment/kamal">deploying AnyCable with Kamal</a>. It covers various possible setups depending on the number of machines and required configuration.</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://dev.to/alex_aslam/anycable-vs-action-cable-a-benchmark-war-4c3f">AnyCable vs. Action Cable: A Benchmark War</a></strong></p><div class="pullquote"><p><strong>Our Rails app&#8217;s real-time features were crumbling under 10K users&#8212;until we switched WebSocket stacks. Here&#8217;s what exploded, what improved, and what caught fire.</strong></p></div><p>The post by Alex Aslam shares a lot of insights and numbers from battle-testing Action Cable vs. AnyCable. I especially like the &#8220;Failure Recovery&#8221; test&#8212;something people rarely pay attention to:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_qeu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_qeu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 424w, https://substackcdn.com/image/fetch/$s_!_qeu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 848w, https://substackcdn.com/image/fetch/$s_!_qeu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 1272w, https://substackcdn.com/image/fetch/$s_!_qeu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_qeu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png" width="1456" height="639" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:639,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105095,&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.anycable.io/i/167226900?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.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_!_qeu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 424w, https://substackcdn.com/image/fetch/$s_!_qeu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 848w, https://substackcdn.com/image/fetch/$s_!_qeu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.png 1272w, https://substackcdn.com/image/fetch/$s_!_qeu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f10bd3d-f809-4121-94e3-147b5bef9f15_1472x646.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><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/websocket-bench">websocket-bench &#183; 0.4.0</a></strong></p><p>We&#8217;ve updated our benchmarking tool to support Pusher-compatible servers (such as Soketi or Laravel Reverb). Stay tuned for some Laravel AnyCable benchmarks!</p><div><hr></div><h1><strong>Frame of the future: SF Ruby</strong></h1><p>We run the new <a href="https://sfruby.com">San Francisco Ruby Conference</a> on November 19-20, and because&#8212;we know!&#8212;you are building amazing things, we&#8217;d love you to <a href="https://cfp.sfruby.com/">send us a talk proposal</a>, or <a href="https://cfp.sfruby.com/startups">demo your Ruby startup</a> at the conference. CFP for talks closes this <strong>Sunday, July 13, EOD.</strong> Join this new and exciting Ruby conference!</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Building bridges: announcing AnyCable for Laravel]]></title><description><![CDATA[github.com/anycable/anycable-laravel]]></description><link>https://blog.anycable.io/p/building-bridges-announcing-anycable</link><guid isPermaLink="false">https://blog.anycable.io/p/building-bridges-announcing-anycable</guid><dc:creator><![CDATA[Irina Nazarova]]></dc:creator><pubDate>Fri, 06 Jun 2025 00:01:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!QomX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Hey Laravel Community!</strong> &#127775;</p><p>We&#8217;re thrilled to introduce <strong>AnyCable for Laravel</strong>&#8212;a production-proven real-time server now available in preview. Think of it as a friendly handshake from the Rails ecosystem, returning the love after Inertia.js made its way from Laravel to Rails. Let&#8217;s keep building bridges! </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QomX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QomX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 424w, https://substackcdn.com/image/fetch/$s_!QomX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 848w, https://substackcdn.com/image/fetch/$s_!QomX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 1272w, https://substackcdn.com/image/fetch/$s_!QomX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QomX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png" width="278" height="252.96862210095497" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:667,&quot;width&quot;:733,&quot;resizeWidth&quot;:278,&quot;bytes&quot;:42199,&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.anycable.io/i/165303396?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.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_!QomX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 424w, https://substackcdn.com/image/fetch/$s_!QomX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 848w, https://substackcdn.com/image/fetch/$s_!QomX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.png 1272w, https://substackcdn.com/image/fetch/$s_!QomX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f6d3b3f-69f2-4dc9-b0bd-512c889487f5_733x667.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">AnyCable for Laravel</figcaption></figure></div><p>AnyCable brings <strong>7+ years of Rails-scale reliability</strong> to Laravel, designed to <em>complement</em> the tools you already love and act as a <em>natural add-on</em> for Laravel apps, not a <em>foreign component</em>. In other words, it&#8217;s a new Laravel Broadcasting backend in addition to Reverb, Pusher, and others. Your backend real-time logic (events, etc.) stays the same. Your client-side logic (Echo) can remain the same.</p><p>Our first Laravel-aware release includes the <a href="https://github.com/anycable/anycable-laravel">broadcast adapter library</a> and limited Pusher protocol support (for now)&#8212;just enough to get started with AnyCable.</p><p>We plan to bring better Reverb compatibility and port AnyCable-specific features in future releases. But first, we&#8217;d love to hear from the community!</p><p><strong>Ask questions, raise concerns, request features&#8212;your feedback will help shape what comes next.</strong></p><p>I know that the first question is going to be &#8220;why&#8221;. Why use AnyCable when we have Reverb, Pusher, Soketi, and so on? So, let me try to answer it right away.<br><br><strong>1. Reliability and Developer Experience for Real-Time Features</strong></p><p>AnyCable is built to make WebSockets truly reliable&#8212;going far beyond basic connectivity. With features like <strong>reliable streams</strong> and <strong>resumable sessions</strong>, AnyCable ensures your users never miss a message, even if their connection drops for a moment, whether they&#8217;re riding the subway or just dealing with everyday WiFi hiccups. As a result, your users get a smooth and dependable real-time experience.</p><p>Other key reliability features include:</p><ul><li><p><strong>At-least-once delivery:</strong> Delivery of messages is guaranteed, and when the client-side handles potential duplicates, we achieve exactly-once. </p></li><li><p><strong>Automatic state restoration:</strong> Upon reconnection, clients automatically catch up on missed messages and resume their session without re-authentication or re-subscribing to channels.</p></li><li><p><strong>Fallback transports:</strong> Beyond WebSockets, AnyCable supports Server-Sent Events and long-polling, so your real-time features work everywhere.</p></li></ul><p><strong>2. Scalability and Performance</strong></p><p>AnyCable is written in Go, giving your Laravel app a high-performance WebSocket server that takes the load off your core PHP processes. This unlocks greater scalability for real-time workloads, letting your main app focus on business logic while AnyCable handles thousands of concurrent connections with low latency.</p><ul><li><p><strong>Effortless horizontal scaling:</strong> Seamlessly scale with Redis or NATS or use embedded NATS for clustering&#8212;no extra infrastructure headaches.</p></li><li><p><strong>Optimized resource usage:</strong> Go&#8217;s efficiency means less RAM and CPU per connection, making it cost-effective as your app grows.</p></li><li><p><strong>Observability and tooling:</strong> The AnyCable ecosystem includes everything from Grafana dashboards for real-time monitoring to a k6 plugin for load testing, so you can confidently operate and scale your real-time features.</p></li></ul><p>Importantly, we haven't benchmarked AnyCable against Reverb or Soketi yet. Stay tuned!<br><strong><br>3. Open Source and Always Will Be</strong></p><p>AnyCable is open source and here to stay&#8212;feel free to screenshot that for posterity. The core is free, and always will be. For teams with massive scale, there&#8217;s a commercial version with extra features, but you only pay if you need it. There&#8217;s also a <strong>free managed offering</strong> (<a href="https://plus.anycable.io">plus.anycable.io</a>) that already supports Laravel!</p><p>Built by Evil Martians, a team focused on developer tools, AnyCable is designed to fit naturally into your Laravel workflow. For example, you can launch the server locally with a single Artisan command:</p><p><code>php artisan anycable:server</code></p><p>No manual installs or downloads&#8212;just Laravel simplicity.</p><div><hr></div><p>In short: AnyCable brings production-grade reliability, performance, and developer experience to Laravel&#8217;s real-time features, while being open and flexible for teams of any size.</p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #29: Laravel Cable]]></title><description><![CDATA[June, 2025]]></description><link>https://blog.anycable.io/p/any-cables-monthly-29-laravel-cable</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-29-laravel-cable</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Wed, 04 Jun 2025 21:54:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OKlW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It&#8217;s summer time &#9728;&#65039; (or winter time for &#128579; folks), and we&#8217;re almost halfway through this year. How is it going so far? What are the <em>vibes</em>? More and more, we tend to delegate work&#8212;especially coding&#8212;to LLM agents, but this newsletter is still <em>handcrafted</em> (is 'vibe-writing' a thing?). Or maybe it&#8217;s not, and I&#8217;m just a not-so-stupid AI playing the imitation game with you. You decide.. </p><div><hr></div><h1>Highlights</h1><p><strong><a href="https://docs.anycable.io/guides/laravel">AnyCable meets Laravel!</a></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_!OKlW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OKlW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 424w, https://substackcdn.com/image/fetch/$s_!OKlW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 848w, https://substackcdn.com/image/fetch/$s_!OKlW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 1272w, https://substackcdn.com/image/fetch/$s_!OKlW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OKlW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png" width="1456" height="646" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:646,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144743,&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.anycable.io/i/165216594?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.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_!OKlW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 424w, https://substackcdn.com/image/fetch/$s_!OKlW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 848w, https://substackcdn.com/image/fetch/$s_!OKlW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.png 1272w, https://substackcdn.com/image/fetch/$s_!OKlW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa064908b-dcf3-4619-b7cb-830917b3a43e_1591x706.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>AnyCable opens up a new frontier: we&#8217;ve started working on bringing better real-time capabilities to <a href="http://laravel.com">Laravel</a> users. Laravel is a <em>cousin-framework </em>to Ruby on Rails; it&#8217;s based on the same ideas and ideals. Even though the frameworks now evolve independently, we believe there is still room for sharing (or cross-pollination). AnyCable worked out great for Rails&#8212;why can&#8217;t it be useful to Rails&#8217; distant relative?</p><p>Today, we&#8217;re taking the first step towards <em>Laravel</em> Cable: meet the <a href="https://github.com/anycable/anycable-laravel">AnyCable broadcasting adapter</a> for Laravel. We&#8217;ve also added limited Pusher protocol support to the AnyCable server&#8212;just enough to get started with AnyCable as a Laravel Reverb drop-in replacement..</p><blockquote><p>Laravel-ready AnyCable is already available on <a href="https://plus.anycable.io">AnyCable+</a> managed service for early access. Give it a try!</p></blockquote><p>AnyCable Laravel is still in its early days, and we&#8217;d be happy hear your feedback and suggestions on how to move forward with it.</p><div><hr></div><h1>News</h1><p><strong><a href="https://sfruby.com/">SF Ruby Conference</a> &#127745;</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_!-vKG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-vKG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 424w, https://substackcdn.com/image/fetch/$s_!-vKG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 848w, https://substackcdn.com/image/fetch/$s_!-vKG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 1272w, https://substackcdn.com/image/fetch/$s_!-vKG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-vKG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png" width="1456" height="838" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:838,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:936965,&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.anycable.io/i/165216594?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.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_!-vKG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 424w, https://substackcdn.com/image/fetch/$s_!-vKG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 848w, https://substackcdn.com/image/fetch/$s_!-vKG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.png 1272w, https://substackcdn.com/image/fetch/$s_!-vKG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19b10b23-2a0a-4e8d-858b-25dc2f8683a5_1754x1010.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>Brought to you by the same people behind AnyCable, <a href="https://sfruby.com/">SF Ruby Conference</a> is a premier Ruby event focused on startups (at all stages, from idea to IPO), open-source and AI tools, and other Silicon Valley-relevant topics. Come join us in San Francisco this November!</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://centrifugal.dev/blog/2025/04/28/websocket-real-time-leaderboard#adding-fossil-delta-compression">Building a real-time WebSocket leaderboard with Centrifugo and Redis</a></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_!YX2J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YX2J!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YX2J!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YX2J!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YX2J!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YX2J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg" width="1456" height="366" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:366,&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_!YX2J!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YX2J!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YX2J!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YX2J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82d3f566-9404-4896-8899-39c35e9313a5_3016x758.jpeg 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>Our friends from Centrifugo recently released a new feature&#8212;<a href="https://centrifugal.dev/docs/server/delta_compression">delta compression in channels</a>. The blog post demonstrates this by building a real-time leaderboard.</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/anycable/releases/tag/v1.6.2">anycable &#183; 1.6.2</a></strong></p><p>This release brings the initial Pusher protocol support we&#8217;ve already mentioned, as well as some minor features that we&#8217;ll cover in future issues. Stay tuned!</p><p><strong><a href="https://github.com/anycable/anycable-laravel">anycable-laravel &#183; 0.1.0</a></strong></p><p>Meet our very first PHP package! We&#8217;ve started with a Laravel-specific library, but designed it so the core AnyCable logic (broadcasting, stream signing) can be easily extracted in the future (currently, it lives in a single <code>AnyCable\Laravel\Client</code> class). Work with PHP but not Laravel and want to give AnyCable a try? Let us know and we&#8217;ll extract the core into our second PHP package &#128513;.</p><div><hr></div><h1><strong>Frame of curiosity: vibe-deeping</strong></h1><p>In <a href="https://blog.anycable.io/p/any-cables-monthly-28-of-past-and">the previous issue</a>, we mentioned a new AI service&#8212;<a href="https://deepwiki.com/">DeepWiki</a>. It takes a GitHub repo and turns it into a documentation website. The resulting documentation is heavily code-centered and, thus, looks more like a service or repair manual, not a user guide. However, this property is beneficial to those trying to figure out <strong>how things work</strong>, rather than just <strong>how to use them</strong>&#8211;like me &#128578;.</p><p>In combination with the built-in chat-to-ask capabilities, DeepWiki becomes a great learning tool for curious engineers.</p><p>Here are a few examples of questions I&#8217;ve asked recently (so you can guess what I&#8217;m working on in my not-so-spare time &#129323;):</p><ul><li><p><a href="https://deepwiki.com/search/how-does-js-agent-connect-to-t_58195808-58c2-4803-8f8c-5a39dbb20667">How does JS agent&#8230;</a></p></li><li><p><a href="https://deepwiki.com/search/how-to-add-new-files-to-the-fi_8d675ced-5f06-4877-b1e1-72b075e26efe">How to add new files to the FileTree&#8230;</a></p></li><li><p><a href="https://deepwiki.com/search/which-pusher-protocol-features_34061578-672d-4330-9453-f9542411453e">Which Pusher protocol features&#8230;</a></p></li><li><p><a href="https://deepwiki.com/search/how-cache-channels-work-do-the_0fd76d97-ce12-43f9-ade8-533987a69da9">How cache channels work&#8230;</a></p></li></ul><p>Got an idea? Give it a try and don&#8217;t hesitate to share your insights!</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #28: of past and presence]]></title><description><![CDATA[April-May, 2025]]></description><link>https://blog.anycable.io/p/any-cables-monthly-28-of-past-and</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-28-of-past-and</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 06 May 2025 15:39:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qdy8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a yet-another bi-monthly issue of Any Cables Monthly. Sorry, April, but our delivery guarantee is at-most once (a month) &#128513;</p><div><hr></div><h1>Highlights</h1><p><strong><a href="https://docs.anycable.io/release_notes?id=_160">AnyCable v1.6 is out!</a></strong></p><p>The long-awaited AnyCable release with presence tracking support is available everywhere: you can quickly spin up a <em>cable </em>at <a href="https://plus.anycable.io/">plus.anycable.io</a>, download an <a href="https://github.com/anycable/anycable">OSS version</a> or <a href="https://anycable.io/">go Pro</a> w/ presence tracking for clusters support.</p><p>Now, when this big release is out, you may ask&#8212;what&#8217;s next? Our primary focus for the rest of the year is, first, to incrementally enhance presence-related features (WebHooks, HTTP API, etc.) and, secondly, to bring more ready-made components for building real-time applications (e.g., UI kit and stuff). Speaking of components&#8230;</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://evilmartians.com/chronicles/simple-declarative-presence-for-hotwire-apps-with-anycable">Simple Declarative Presence for Hotwire apps with AnyCable</a></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_!qdy8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qdy8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 424w, https://substackcdn.com/image/fetch/$s_!qdy8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 848w, https://substackcdn.com/image/fetch/$s_!qdy8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 1272w, https://substackcdn.com/image/fetch/$s_!qdy8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qdy8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png" width="1456" height="861" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:861,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:824115,&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.anycable.io/i/162926143?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.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_!qdy8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 424w, https://substackcdn.com/image/fetch/$s_!qdy8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 848w, https://substackcdn.com/image/fetch/$s_!qdy8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.png 1272w, https://substackcdn.com/image/fetch/$s_!qdy8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3171f532-da53-4069-99b8-d34cccbb1038_2374x1404.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>Learn more about our Hotwire Presence component that can help you add presence tracking features by just using HTML!</p><p><strong><a href="https://labs.clio.com/improving-websocket-performance-at-clio-b4c284a79ef9">Improving WebSocket performance at Clio</a></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_!xe-v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xe-v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 424w, https://substackcdn.com/image/fetch/$s_!xe-v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 848w, https://substackcdn.com/image/fetch/$s_!xe-v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 1272w, https://substackcdn.com/image/fetch/$s_!xe-v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xe-v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png" width="1456" height="580" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:580,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:543841,&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.anycable.io/i/162926143?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.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_!xe-v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 424w, https://substackcdn.com/image/fetch/$s_!xe-v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 848w, https://substackcdn.com/image/fetch/$s_!xe-v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.png 1272w, https://substackcdn.com/image/fetch/$s_!xe-v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f1b9a51-25cc-4dc7-87f2-1152725b901d_1838x732.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>The <a href="https://labs.clio.com/">Clio</a> team shared the story of improving the performance of their real-time features (powered by AnyCable):</p><blockquote><p>What could be done to improve WebSocket performance? We identified <strong>three</strong> solutions:</p><ul><li><p>Decrease the number of WebSocket messages sent from the frontend to the backend</p></li><li><p>Scale AnyCable&#8217;s servers</p></li><li><p>Make Clio&#8217;s code process WebSocket messages faster.</p></li></ul></blockquote><div><hr></div><h1>News</h1><p><strong><a href="https://terminalwire.com/articles/agpl-license">Terminalwire is open source</a></strong></p><p><a href="https://terminalwire.com/">Terminalwire</a> allows you to easily create a CLI interface for your web application (a &#8220;<em>thin client&#8221;</em>&#8212;a term from the past) fully defined on the server (commands, options, etc.). It&#8217;s like Hotwire but for CLIs. Under the hood, the command-line tool uses a WebSocket connection and a custom protocol to execute commands. The source code can be used as an example of <a href="https://github.com/terminalwire/ruby/blob/main/gem/terminalwire-client/lib/terminalwire/client.rb">using async-websocket</a> to create WebSocket clients in Ruby.</p><div><hr></div><h1><strong>Releases &#129302;</strong></h1><p><strong><a href="https://deepwiki.com/anycable/anycable">deepwiki.com/anycable/anycable</a></strong></p><p>Say hello to our new documentation website! This is joke, of course; our new documentation website will be much better. Still, such AI-generated source-to-documentation resources could be useful in learning more about the internals of the project you want to hack with. Don&#8217;t hesitate to give it a try!</p><div><hr></div><h1><strong>Frame of history: Comet</strong></h1><p>Yesterday, we (Team AnyCable) visited the <a href="https://computerhistory.org/">Computer History Museum</a> in Mountain View, CA. It was a great time-traveling experience and a demonstration of how quickly the industry evolved over the last (half-)century (and how small the first iPhone was compared to modern models, even my beloved mini). And it also felt a bit strange; another visitor nailed it, saying: &#8220;How strange it is to see the things you actively used in the past now being a part of a history museum collection?&#8221;</p><p>We don&#8217;t have a museum of real-time web yet, even a digital one, but there are definitely good candidates to add to its collection. And the first thing that came to my mind with regards this idea is <strong><a href="https://en.wikipedia.org/wiki/Comet_(programming)">Comet</a></strong>, an umbrella term for push-style/streaming HTTP communication used in the late 90s and early 00s. It was usually contrasted with a request-response-ish <strong>Ajax</strong>, a super-hot technology back in the day that is still very much alive today (though since the decline of <code>$.ajax</code> and the rise of <code>fetch,</code> we barely use this legacy term).</p><p>As an exhibit to represent Comet in our mythical Real-Time Web Museum, I would pick <a href="https://infrequently.org/2006/03/comet-low-latency-data-for-the-browser/">the original blog post by Alex Russel</a> that introduced the term. I leave you the opportunity to read the blog from the past in its entirety yourself. Here I just want to pull out some quotes and add a few remarks.</p><div><hr></div><blockquote><p>&#8230;Lacking a better term, I've taken to calling this style of event-driven, server-push data streaming "Comet". It doesn't stand for anything, and I'm not sure that it should.</p></blockquote><p>I don&#8217;t know if it&#8217;s a coincidence or not, but in the context of Ajax, Comet had a clear (<em>clean</em>?) meaning&#8212;both names have been used by popular cleansers since mid-20th century:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B_9h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B_9h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 424w, https://substackcdn.com/image/fetch/$s_!B_9h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 848w, https://substackcdn.com/image/fetch/$s_!B_9h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 1272w, https://substackcdn.com/image/fetch/$s_!B_9h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B_9h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png" width="1186" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1186,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:931744,&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.anycable.io/i/162926143?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.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_!B_9h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 424w, https://substackcdn.com/image/fetch/$s_!B_9h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 848w, https://substackcdn.com/image/fetch/$s_!B_9h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.png 1272w, https://substackcdn.com/image/fetch/$s_!B_9h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97b62720-7ad8-4c57-b1b4-59e9c1f3b9dd_1186x720.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">Ajax vs Comet</figcaption></figure></div><blockquote><p><strong>Common terminology</strong> acts not only as a shortcut in discussions between technical folks, but also as a bridge for those who may not be able to give a technical rundown of exactly how it works&#8230; We have a hard problem for which solutions are available (and have been for some time) but no way to communicate about them. <strong>Terminology is again the missing link</strong>.</p></blockquote><p>We all know that naming things is hard; but this post goes further and discusses the problem of <strong>having no good name</strong> for a common set of problems or solutions.</p><p>The term &#8220;Comet&#8221; hasn&#8217;t become The Term. Today, we use the word &#8220;real-time&#8221; to describe asynchronous/bi-directional/low-latency communication, and most of the times we use a particular transport name along with it (WebSockets, SSE, WebRTC). We still can&#8217;t separate the concept (<em>realtime-ness</em>) from technology.</p><p>P.S. Can you count the number of times the term &#8220;real-time&#8221; used in the Comet blog post? </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #27: Hot Presence ⚡️]]></title><description><![CDATA[March, 2025]]></description><link>https://blog.anycable.io/p/any-cables-monthly-27-hot-presence</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-27-hot-presence</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Wed, 05 Mar 2025 02:57:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!h8Ex!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Spring is in the air (and, I hope, not in your Gemfile). Nature awakens, as does the world of tech: CFPs are blooming, and conferences are being scheduled. We'll reap the benefits of these transformations later. For now, let's take a quick look back at the last winter days.</p><div><hr></div><h1>Videos</h1><p><strong><a href="https://evilmartians.com/events/presence-aint-perfect-sf-ruby">Presence ain&#8217;t perfect</a></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_!h8Ex!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h8Ex!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 424w, https://substackcdn.com/image/fetch/$s_!h8Ex!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 848w, https://substackcdn.com/image/fetch/$s_!h8Ex!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!h8Ex!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h8Ex!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png" width="1456" height="649" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:649,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1554442,&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.anycable.io/i/158386415?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.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_!h8Ex!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 424w, https://substackcdn.com/image/fetch/$s_!h8Ex!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 848w, https://substackcdn.com/image/fetch/$s_!h8Ex!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!h8Ex!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb8e65e9-f0dd-49bd-80a0-b8f4c0c74177_3012x1342.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>This is the video from latest <a href="https://lu.ma/sfruby">SF Ruby Meetup</a> in which we presented the brand new <strong>AnyCable Presence</strong> primitive along with its Hotwire component&#8212;the <code>&lt;turbo-cable-presence-source&gt;</code> element. We&#8217;re close to the final release of the feature, documentation and more!</p><h1>Posts</h1><p><strong><a href="https://stanko.io/adversarial-web-services-Vjfkr3DF9LfG">Adversarial Web Services</a></strong></p><p>This post gives an alternative meaning to the "AWS" acronym, going into details regarding the pitfalls of using AWS. The part about <strong>API Gateway WebSockets limitations and the cost calculations</strong> is of most interest to us:</p><blockquote><p>If you have 50k clients you'll pay AWS 200&#8364; every month just to keep them connected to a WebSocket 24/7. For comparison, a 60&#8364; EC2 instance can handle more clients than that with no limitations.</p></blockquote><div><hr></div><h1>News</h1><p><strong><a href="https://hatchbox.relationkit.io/articles/12-does-hatchbox-support-anycable">Hatchbox upgraded AnyCable support</a></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_!Q8D-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q8D-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 424w, https://substackcdn.com/image/fetch/$s_!Q8D-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 848w, https://substackcdn.com/image/fetch/$s_!Q8D-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 1272w, https://substackcdn.com/image/fetch/$s_!Q8D-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q8D-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png" width="1176" height="644" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:644,&quot;width&quot;:1176,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:113738,&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.anycable.io/i/158386415?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.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_!Q8D-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 424w, https://substackcdn.com/image/fetch/$s_!Q8D-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 848w, https://substackcdn.com/image/fetch/$s_!Q8D-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.png 1272w, https://substackcdn.com/image/fetch/$s_!Q8D-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd44357cf-ae78-429f-a49a-1256c5cf6d97_1176x644.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>Now running AnyCable on Hatchbox is as simple as adding a line of configuration!</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/anycable-client/releases/tag/v1.1.0">@anycable/core &#183; 1.1.0</a></strong></p><p>This release brings many improvements around using authentication tokens. For example, you can now specify the token as a WebSocket sub-protocol (to not expose it in query params and, potentially, server-side logs). Note: this feature requires the latest <a href="https://github.com/anycable/anycable/releases/tag/v1.6.0-rc.4">RC of AnyCable 1.6</a>.</p><p><strong><a href="https://github.com/anycable/anycable-client/tree/master/packages/turbo-stream">@anycable/turbo-stream &#183; 0.8.0</a></strong></p><p>This release brings experimental <code>&lt;turbo-cable-presence-source&gt;</code> element that powers AnyCable Presence features to Hotwire. It&#8217;s still early days of this integration, so we&#8217;d love to hear your feedback! You can see it in action in this <a href="https://github.com/anycable/anycasts_demo/pull/17">demo application</a>.</p><div><hr></div><h1><strong>Frame of curiosity: don&#8217;t slow your roll</strong></h1><p>Have you ever heard of a <em>slow client</em> problem? This happens when a socket cannot read data as fast as it's written into it. The causes vary from poor network to malicious actors. Yes, slow clients could be used to perform DDoS attacks. It's hard to distinguish a <em>good</em> client with low bandwidth from a <em>bad</em> client configured to read slowly intentionally.<br><br>Okay, how exactly can slow clients harm your system? <a href="https://www.ateijelo.com/blog/2016/08/19/slow-client-problem">This article</a> in La Nueva Escuela blog provides a good illustration (and explanation) on how slow clients affect systems of different types&#8212;with <strong>blocking and non-blocking write operations</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_!kFJ9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kFJ9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 424w, https://substackcdn.com/image/fetch/$s_!kFJ9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 848w, https://substackcdn.com/image/fetch/$s_!kFJ9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 1272w, https://substackcdn.com/image/fetch/$s_!kFJ9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kFJ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png" width="640" height="450" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:640,&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_!kFJ9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 424w, https://substackcdn.com/image/fetch/$s_!kFJ9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 848w, https://substackcdn.com/image/fetch/$s_!kFJ9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.png 1272w, https://substackcdn.com/image/fetch/$s_!kFJ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb1b901d-f853-4e2d-8309-b7fb265c5c4e_640x450.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>Basically, there are two possible outcomes (if you don&#8217;t guard yourself from the problem): either your whole <strong>application periodically stalls</strong> for a noticeable amount of time, or you <strong>memory usage grows</strong> significantly (<a href="https://github.com/CrowCpp/Crow/issues/760">example issue</a>). The former happens when writes are blocking and the latter is a result of buffering data before performing the actual write into a socket.<br><br>For example, in Node.js I/O writes are non-blocking and in Go they&#8217;re blocking (by default). In Ruby, I/O objects have both <code>#write</code> and <code>#write_nonblock</code> methods (though the latter may raise an exception if the underlying buffer is full).</p><p>How does this affect real-time applications and WebSockets in particular? And how can we prevent the potential consequences of serving slow clients?</p><p>Recently, one of AnyCable users, <a href="https://github.com/thorsteinson">Caleb Thorsteinson</a>, shared his investigation regarding increased broadcast latency when there are slow clients and a high broadcast rate. AnyCable server is written in Go, so writing messages to clients is a blocking operation; however, there is a <strong>buffer and a write timeout</strong> in place: that's how we protect the pub/sub component of the server from becoming unresponsive when trying to serve slow connections. Still, under some circumstances, that wasn't enough.</p><p>Caleb shared a minimal reproduction setup involving a few scripts to create subscribers, perform broadcasts at a given rate and a <a href="https://github.com/Shopify/toxiproxy">Toxiproxy</a> configuration. Toxiproxy is an indispensable assistant in all kind of <em>non-ideal network</em> test scenarios.<br><br>With the help of the load test (more precisely, its <a href="https://github.com/anycable/slow-client-tests">upgraded version</a>), we were able to measure the effect of slow clients on such WebSocket servers as Action Cable (w/ Puma), AnyCable, and Centrifugo.</p><p>Action Cable uses <a href="https://github.com/rails/rails/blob/cf6ff17e9a3c6c1139040b519a341f55f0be16cf/actioncable/lib/action_cable/connection/stream_event_loop.rb#L97">I/O polling</a> to detect when the socket is writeable, and there is a buffer to store pending messages. There is no buffer size limit nor timeouts. Hence, when there is a slow client, the Action Cable server memory usage grows as we continue broadcasting messages. In our tests, the memory grew from <strong>380 MiB to 450 MiB</strong> with just a single slow client in 10 minutes (and 20 messages per second sent). Without slow clients, the increase was just ~10 MiB.</p><p>In the case of AnyCable, we were able to reproduce the original issue&#8212;a server's pub/sub loop is blocked when writing to a slow client until the timeout triggers and we forcefully close the connection. In theory, that should have been enough; in practice, our default timeout value was too high&#8212;10s. So, some broadcasts could get stuck for 10 seconds&#8212;not good. We also used a Go channel as an application-level buffer for outgoing messages; this is a typical approach for Go applications, but it doesn't take into account payload sizes. We fixed this by switching to a queue as a buffer and adding pending data size tracking: whenever a client exceeds a limit, we mark it as slow and disconnect. Thus, <strong>writes are non-blocking now, and the potential memory increase per connection is capped</strong>. The queue idea was borrowed from Centrifugo, which we tested and confirmed that it handles slow clients well.</p><p>The change will ship in AnyCable v1.6 (and is already available in the <a href="https://github.com/anycable/anycable/releases/tag/v1.6.0-rc.5">latest release candidate</a>).</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #26 ❄️ ping pong]]></title><description><![CDATA[February, 2025]]></description><link>https://blog.anycable.io/p/any-cables-monthly-26-ping-pong</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-26-ping-pong</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 04 Feb 2025 21:29:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today I ate a snowflake&#8230; oh, wait a sec, this is not Twitter :) This is our monthly newsletter about the world of realtime web development. </p><p>If you happen to be around San Francisco next week, come say &#8220;hi!&#8221; to us at the <a href="https://lu.ma/sfruby">SF Ruby Meetup</a> where Team AnyCable will be hanging out (and giving talks). Or you can join the <a href="https://www.youtube.com/live/M25fETp83jQ">live stream</a> &#127909;!</p><div><hr></div><h1>Posts</h1><p><strong><a href="https://www.inferable.ai/blog/posts/postgres-nodejs-longpolling.mdx">Back to Basics: Why We Chose Long Polling Over WebSockets</a></strong></p><p>This story of favoring long-polling over other transports in 2025 is an interesting read. Just check out the analogy:</p><blockquote><p><strong>Short polling</strong> is like a train that departs strictly according to a timetable&#8212;it leaves the station at fixed intervals regardless of whether there are passengers or not.</p><p><strong>WebSockets</strong>, on the other hand, are like having a dedicated train line always ready to transport passengers.</p><p><strong>Long polling</strong>? It's like a train that waits at the station until at least one passenger boards before departing.</p></blockquote><p>(Although I would say that WebSockets are more like taxis; there is no overhead for pulling a whole train just for the sake of a single passenger.) </p><p><strong><a href="https://stanko.io/monitoring-actioncable-GdeaeHfIU4Yk">Monitoring Action Cable</a></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_!RWeR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RWeR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 424w, https://substackcdn.com/image/fetch/$s_!RWeR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 848w, https://substackcdn.com/image/fetch/$s_!RWeR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 1272w, https://substackcdn.com/image/fetch/$s_!RWeR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RWeR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png" width="1024" height="300" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:300,&quot;width&quot;:1024,&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_!RWeR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 424w, https://substackcdn.com/image/fetch/$s_!RWeR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 848w, https://substackcdn.com/image/fetch/$s_!RWeR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.png 1272w, https://substackcdn.com/image/fetch/$s_!RWeR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F106fc59b-3b31-4473-a921-317c5d0b4ea5_1024x300.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>Learn how to make Rails Action Cable instrumentation-friendly and expose metrics to Prometheus (using the <a href="https://github.com/yabeda-rb">Yabeda framework</a>).</p><p><strong><a href="https://jonsully.net/blog/twilio-openai-realtime-rails">Guide to Twilio + OpenAI Realtime on Rails (Without AnyCable)</a></strong></p><p>One more blog post about stitching Twilio Media Streams and OpenAI Realtime together; this time, in pure Ruby (as you might guess from the title). We shared our AnyCable-ed version <a href="https://blog.anycable.io/p/any-cables-monthly-24-anycable-speaking">a couple of issues ago</a>.</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/actioncable-next">actioncable-next &#183; 0.2.0</a></strong></p><p>A new release of the future Action Cable brings various performance improvements. The most significant one is <strong>fastlane broadcasts</strong> support (or less JSON encoding/decoding). See more in <a href="https://github.com/anycable/actioncable-next/pull/10">this PR</a>. And here are some benchmarks:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n5Q8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n5Q8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 424w, https://substackcdn.com/image/fetch/$s_!n5Q8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 848w, https://substackcdn.com/image/fetch/$s_!n5Q8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 1272w, https://substackcdn.com/image/fetch/$s_!n5Q8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n5Q8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png" width="1456" height="752" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:752,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:128560,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n5Q8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 424w, https://substackcdn.com/image/fetch/$s_!n5Q8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 848w, https://substackcdn.com/image/fetch/$s_!n5Q8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.png 1272w, https://substackcdn.com/image/fetch/$s_!n5Q8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bf0a0fb-837d-42f0-8dfc-738706b664fd_1668x862.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><a href="https://github.com/anycable/anycable-rails/releases/tag/v1.6.0.rc.1">anycable-rails &#183; 1.6.0.rc.1</a></strong></p><p>This release brings AnyCable presence (which we&#8217;ve <a href="https://blog.anycable.io/p/any-cables-monthly-2025">announced the last time</a>) to Action Cable channels:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UNjc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UNjc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 424w, https://substackcdn.com/image/fetch/$s_!UNjc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 848w, https://substackcdn.com/image/fetch/$s_!UNjc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 1272w, https://substackcdn.com/image/fetch/$s_!UNjc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UNjc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png" width="1456" height="530" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:107556,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UNjc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 424w, https://substackcdn.com/image/fetch/$s_!UNjc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 848w, https://substackcdn.com/image/fetch/$s_!UNjc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.png 1272w, https://substackcdn.com/image/fetch/$s_!UNjc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ccc50f1-81da-4899-8865-bb7cf677a3d0_1560x568.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><a href="https://centrifugal.dev/blog/2025/01/16/centrifugo-v6-released">centrifugo &#183; 6.0</a></strong></p><p>A new chapter in the life of our friends from Centrifugo.</p><div><hr></div><h1><strong>Frame of curiosity: ping pong &#127955;</strong></h1><p>Persistent network connections (like WebSockets) require a mechanism to inform each communication end (say, <em>client </em>and <em>server</em>) whenever the other one unexpectedly goes out of sight, to distinguish silence from disrupted connectivity. This discovery can be implemented at a different level (or <em>layer</em>). For example, TCP protocol supports sending tiny keep-alive packets to detect network failures (as we explain in <a href="https://docs.anycable.io/anycable-go/os_tuning?id=tcp-keepalive">our documentation</a>).</p><p>Usually, higher-level protocols (<em><a href="https://en.wikipedia.org/wiki/OSI_model">Application Layer</a></em>) implement their own <em>heartbeats</em>. The primary reasons are <strong>better control over heartbeat logic</strong> (e.g., intervals, etc.) and <strong>proxy/firewall handling</strong> (as some intermediate nodes might skip keep-alive packets).</p><p>Both WebSockets and HTTP/2 come with their own heartbeats: PING/PONG messages. Yet almost all realtime protocols/frameworks implement their own keepalive logic! We can see &#8220;ping&#8221;-&#8221;pong&#8221; (or &#8220;ok&#8221;-&#8221;ko&#8221;) messages passing through every WebSocket connection. Why so? Primarily because <strong>pings and pongs are </strong><em><strong>hidden </strong></em><strong>from client-side</strong> (browser) code: you can&#8217;t initiate them, you can&#8217;t listen to the corresponding events, you don&#8217;t even know if the server uses them or not (more info <a href="https://github.com/whatwg/html/issues/4353">here</a>).</p><p>So, we add ping-pong-like features to our realtime protocols.</p><p>Let&#8217;s consider Action Cable, for example. The server sends a &#8220;ping&#8221; message to every connected clients every 3 seconds. The client uses this pings to detect if the <strong>server is still alive and operational</strong> (i.e., it not only checks connectivity but verifies that the server can do its job). Here&#8217;s an important difference from lower-level heartbeats: the network could be up, while the server (in this case, a Ruby application) experiences performance issues&#8212;it&#8217;s better for clients to know about that and try to re-connect to a different node*.</p><p>In many cases, &#8220;ping&#8221; messages (when accompanied by &#8220;pong&#8221;-s) are used to <strong>measure the latency</strong> between the peers (see the Action Cable metrics article linked above). That&#8217;s another reason for having them.</p><p>Thus, protocol-level heartbeats are justified. However, at scale, the number of transmitted messages could be enormous. For example, with 10k Action Cable clients, the server sends <strong>~3k messages per second</strong>.**</p><p>From the client-perspective, receiving and sending pings is also not free, especially, for mobile devices: you can <strong>easily drain power</strong> by constantly <em>asking </em>a mobile app to process pings. (That&#8217;s why we made it possible to configure ping interval on <a href="https://docs.anycable.io/anycable-go/configuration?id=per-client-settings">per-client basis in AnyCable</a>.)</p><p>Know your pings!</p><p>* Ping in Action Cable are only goes in one direction, from server to clients; unfortunately, that doesn&#8217;t prevent all the possible networking problems. See <a href="https://github.com/rails/rails/issues/45112">this PR</a> for discussion.</p><p> ** The calculations are borrowed from <a href="https://github.com/anycable/actioncable-next/issues/6">this issue</a>.</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #(20)25 🎄]]></title><description><![CDATA[December, 2024]]></description><link>https://blog.anycable.io/p/any-cables-monthly-2025</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-2025</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 31 Dec 2024 17:35:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!20Rx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Happy New Year everyone! Let&#8217;s quickly check what we&#8217;ve ended up the year with, and what to expect from 2025.</p><div><hr></div><h1><strong>Highlights</strong></h1><p><strong><a href="https://docs.anycable.io/edge/anycable-go/presence">AnyCable Presence is coming!</a></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_!20Rx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!20Rx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 424w, https://substackcdn.com/image/fetch/$s_!20Rx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 848w, https://substackcdn.com/image/fetch/$s_!20Rx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 1272w, https://substackcdn.com/image/fetch/$s_!20Rx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!20Rx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png" width="1456" height="842" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:842,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:212387,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!20Rx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 424w, https://substackcdn.com/image/fetch/$s_!20Rx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 848w, https://substackcdn.com/image/fetch/$s_!20Rx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.png 1272w, https://substackcdn.com/image/fetch/$s_!20Rx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d5feff8-b928-467d-af9f-b28b14f9c473_1560x902.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>A long-awaited feature is coming to AnyCable&#8212;<strong>presence tracking</strong>. We&#8217;ve just released the first release candidate for the upcoming 1.6 version with presence tracking capabilities. You can check this feature out via our <a href="https://stackblitz.com/edit/anycable-pubsub">Stackblitz demo</a> or by creating a new server on <a href="https://plus.anycable.io/">AnyCable+</a> (yes, the feature is already available there).</p><p>As you can see from the docs, presence tracking is quite a complex feature consisting of multiple components. We&#8217;re going to incrementally release them over the next months. Stay tuned!</p><div><hr></div><h1>News</h1><p><strong><a href="https://supabase.com/blog/edge-functions-background-tasks-websockets">Supabase Edge WebSockets</a></strong></p><p>Supabase announced WebSockets support for Edge functions. Although it opens some new possibilities (the primary use case OpenAI Realtime which we discussed in <a href="https://blog.anycable.io/p/any-cables-monthly-24-anycable-speaking">the previous issue</a>), the <a href="https://supabase.com/docs/guides/functions/limits">duration limits</a> must be taken into account (making a client re-connect and re-initialize every few minutes may not work for your application). (Have Supabase invented <em>WebSockets Long Polling</em> &#129300;?)</p><div><hr></div><h1>Talks</h1><p><strong><a href="https://www.youtube.com/watch?v=WqYExpMWIUU">Streaming over the web with modern Ruby</a></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_!ASiE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ASiE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 424w, https://substackcdn.com/image/fetch/$s_!ASiE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 848w, https://substackcdn.com/image/fetch/$s_!ASiE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!ASiE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ASiE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png" width="1456" height="818" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:818,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1688512,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ASiE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 424w, https://substackcdn.com/image/fetch/$s_!ASiE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 848w, https://substackcdn.com/image/fetch/$s_!ASiE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!ASiE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad97b7a-bd31-4218-ba1a-e55050a979e6_2484x1396.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>Shannon Skipper provided a great overview of realtime transports in his recent RubyConf talk: WebSockets (not dead at all), WebTransport (not-so-close future), SSE, HTTP chunking.</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://phoenixframework.org/blog/phoenix-liveview-1.0-released">LiveView &#183; 1.0</a></strong></p><p>Congratulations to the Phoenix team and Chris McCord for reaching this milestone!</p><p><strong><a href="https://github.com/cinemast/anycable-go-client">anycable-go-client</a></strong></p><p>Want to connect to AnyCable or Action Cable server from another backend application? Here is an open-source Go library for that!</p><p><strong><a href="https://github.com/socketry/async-cable">async-cable</a></strong></p><p>This library aims to provide better Action Cable experience for Async Ruby / Falcon users. It relies on the <a href="https://github.com/anycable/actioncable-next">Action Cable Next</a> project which we mentioned a few times this year.</p><p><strong><a href="http://- https://github.com/anycable/twilio-ai-js-demo">twilio-ai-js-demo</a></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_!HGvv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HGvv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 424w, https://substackcdn.com/image/fetch/$s_!HGvv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 848w, https://substackcdn.com/image/fetch/$s_!HGvv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 1272w, https://substackcdn.com/image/fetch/$s_!HGvv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HGvv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png" width="1456" height="801" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:801,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1253762,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HGvv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 424w, https://substackcdn.com/image/fetch/$s_!HGvv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 848w, https://substackcdn.com/image/fetch/$s_!HGvv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.png 1272w, https://substackcdn.com/image/fetch/$s_!HGvv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae2781b3-dfe7-44eb-8585-d81f3d633518_2998x1650.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>Recently, <a href="https://youtu.be/wqqFjFlgvSQ?si=rZNfD-9vZ5lrs85f&amp;t=6350">Irina presented</a> the Next.js version of our <a href="https://github.com/anycable/twilio-ai-demo">Rails Twilio OpenAI Realtime demo</a>. It demonstrates how AnyCable-based realtime server can stay language and framework-agnostic and work with any backend! </p><div><hr></div><h1><strong>Frame of remembrance: Noah Gibbs</strong></h1><p>The end of the year brought us sad news: a prominent member of Ruby and Rails communities, the author of an amazing <a href="https://rebuilding-rails.com/">&#8220;Rebuilding Rails&#8221;</a> book and many more, <a href="https://codefol.io/about">Noah Gibbs</a> has passed away (<a href="https://www.reddit.com/r/ruby/comments/1hmynb3/noah_gibbs_codefolio_has_passed_away/">/r/ruby</a>).</p><p>Let me share you one story (related to our newsletter&#8217;s primary topic).<br><br>I first met Noah at SouthEastRuby conference in 2018 where we were both speaking. We&#8217;ve likely seen each other before at larger conferences but had no real opportunity to chat; the regional conferences are much better for finding new friends in the community.</p><p>Over three days, we had a few thoughtful conversations, technical and not, but one topic stayed with us for quite some time after the event&#8212;Action Cable. I still smile when I recall how right during the conference Noah sent me a link to a secret gist titled <strong>action_cable_weird_shit.txt</strong>. It contained a dozen questions and notes on the library sometimes surprising or unclear behavior, and we walked through it trying to fill the gaps.</p><p>As a result, Noah wrote a great article called <a href="https://engineering.appfolio.com/appfolio-engineering/2018/8/6/does-actioncable-smell-like-rails">&#8220;Does ActionCable Smell Like Rails?&#8220;</a>. This article is a reflection of a seasoned developer, the framework expert, on the evolution of Rails. Something bothered Noah (&#8220;A Rails API is often carefully polished&#8230; ActionCable isn't there yet&#8221;), and he tried to find the answer for himself and share his findings with the community&#8212;I believe the latter was more important to him than the former. That was Noah. That&#8217;s what we all will miss &#10084;&#65039;.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Xk1c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Xk1c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Xk1c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Xk1c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Xk1c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Xk1c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg" width="1000" height="750" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:750,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;SouthEastRuby speakers&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="SouthEastRuby speakers" title="SouthEastRuby speakers" srcset="https://substackcdn.com/image/fetch/$s_!Xk1c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Xk1c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Xk1c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Xk1c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e8efe29-b64e-4d60-a3c2-975036145181_1000x750.jpeg 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 class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #24: AnyCable speaking!]]></title><description><![CDATA[October-November, 2024]]></description><link>https://blog.anycable.io/p/any-cables-monthly-24-anycable-speaking</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-24-anycable-speaking</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 12 Nov 2024 20:55:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!z4H_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>With all the fall conferences, we can hardly keep pace with time and publish the updates as soon as yet another month ends. So, this issue covers October and &#189; of November, and the last issue of the year is scheduled for somewhere around Christmas and New Year. Relax and enjoy the magical season &#9924;&#65039;!</p><div><hr></div><h1><strong>Highlights</strong></h1><p><strong><a href="https://evilmartians.com/chronicles/anycable-speaking-needing-help-with-a-twilio-openai-connection">Hey, AnyCable speaking! Needing help with a Twilio-OpenAI connection?</a></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_!z4H_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!z4H_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 424w, https://substackcdn.com/image/fetch/$s_!z4H_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 848w, https://substackcdn.com/image/fetch/$s_!z4H_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 1272w, https://substackcdn.com/image/fetch/$s_!z4H_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!z4H_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png" width="1456" height="545" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:545,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:81389,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!z4H_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 424w, https://substackcdn.com/image/fetch/$s_!z4H_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 848w, https://substackcdn.com/image/fetch/$s_!z4H_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.png 1272w, https://substackcdn.com/image/fetch/$s_!z4H_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F016092fa-c7bc-4197-87f5-8147961ee21a_1978x740.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>AnyCable meets Twilio <a href="https://blog.anycable.io/p/anycable-off-rails-connecting-twilio-hanami">again</a>! This time, we demonstrate how to build conversational voice assistants using <strong>OpenAI Realtime</strong>, Twilio Media Streams, and AnyCable as a middleman between all this machinery and your backend application. Check it out!</p><div><hr></div><h1>Talks</h1><p><strong><a href="https://evilmartians.com/events/evolution-of-real-time-and-anycable-rocky-mountain">Evolution of real-time and AnyCable Pro</a> (Rocky Mountain Ruby 2024)</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_!Q5l-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q5l-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 424w, https://substackcdn.com/image/fetch/$s_!Q5l-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 848w, https://substackcdn.com/image/fetch/$s_!Q5l-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 1272w, https://substackcdn.com/image/fetch/$s_!Q5l-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q5l-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png" width="1456" height="813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:721653,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q5l-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 424w, https://substackcdn.com/image/fetch/$s_!Q5l-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 848w, https://substackcdn.com/image/fetch/$s_!Q5l-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.png 1272w, https://substackcdn.com/image/fetch/$s_!Q5l-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58f48c65-2a9c-42ca-b6a2-e45c22b863f8_2202x1230.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><a href="https://speakerdeck.com/ryosk7/30mo-ren-gali-yong-surutiyatutowofirebase-realtime-databasekaraactioncableheyi-xing-surufang-fa">How to migrate a chat service used by 300,000 people from Firebase Realtime Database to Action Cable</a> (Kaigi on Rails 2024)</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_!tbjS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tbjS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tbjS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tbjS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tbjS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tbjS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&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_!tbjS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tbjS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tbjS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tbjS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b1a997d-cf58-4a4b-abab-d9cb6e6a2bfc_1500x844.jpeg 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>The slides are in Japanese, though it might be a bit tricky to understanding; but just the title and the diagram above should at least make you curious &#128578;.</p><div><hr></div><h1>Podcasts</h1><p><strong><a href="https://www.remoteruby.com/2260490/episodes/15976066-solid-cable-with-nick-pezza">Remoty Ruby: Solid Cable with Nick Pezza</a></strong></p><p>The conversations goes into the deeps of Action Cable implementation, <a href="https://evilmartians.com/chronicles/connection-avalanche-safety-tips-and-prepping-for-realtime-applications">thundering herd problem</a> for WebSockets, and <a href="https://evilmartians.com/chronicles/real-time-stress-anycable-k6-websockets-and-yabeda">benchmarking</a> WebSockets.</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://x.com/any_cable/status/1844135493556109314">anycable-go &#183; 1.5.4</a></strong></p><p>This <a href="https://github.com/anycable/anycable-go/releases/tag/v1.5.4">tiny release</a> introduces one long-awaited feature: TOML configuration for the server. Given the huge number of configuration parameters and static natures of the most of them, having a file-based config is definitely a DX improvement. It&#8217;s especially useful for local development: just drop a file and don&#8217;t teach the team which options to provide and how to keep them in sync. As a bonus, <a href="https://github.com/anycable/anycable-rails">anycable-rails</a> now generates <code>anycable.toml</code> for you during the setup.</p><div><hr></div><h1><strong>Frame of curiosity: </strong>Durable Objects and the consistency conundrum</h1><p>Recently, I've been at a tech conference where a developer asked: "Should we use Durable Objects to build collaborative UX?" This led me down a fascinating rabbit hole of distributed systems trade-offs that I'd like to share with you.</p><p><a href="https://developers.cloudflare.com/durable-objects/">Durable Objects</a> make an intriguing promise: globally consistent, single-threaded objects distributed across Cloudflare's edge network. Like having a tiny, dedicated server for each piece of state. Sounds perfect for real-time applications, right? Well, it depends.</p><p>Consider collaborative editing. With Durable Objects, every user action is processed strictly in order by a single object, which eliminates potential edit collisions. However, this comes with two significant trade-offs:</p><p>First, when users are geographically distributed, latency will depend on how close each person is to the physical location of the object. Cloudflare picks this location. As a result, if you are further away from the rest of your team, your UI can be sluggish and unresponsive, while everyone else&#8217;s experience is perfect.</p><p>Second, during network hiccups, Cloudflare might need to recreate your object elsewhere to maintain consistency. Your application freezes rather than risks inconsistency. Classic CAP theorem: choosing consistency over availability.</p><p>There's an old distributed system saying: "You can't not have distributed state, you can only choose how to distribute it." Durable Objects chooses strong consistency over availability&#8212;often not ideal for real-time collaboration. Sometimes, being "eventually right" beats being "immediately frozen."</p><p>What's your take? Have you faced similar architectural decisions? Share your thoughts&#8212;respond to this email, or leave a comment on substack. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #23: it's a Rails, Rails World!]]></title><description><![CDATA[September, 2024]]></description><link>https://blog.anycable.io/p/any-cables-monthly-23-its-a-rails</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-23-its-a-rails</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Wed, 02 Oct 2024 03:59:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!89Qr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey there! We&#8217;re just back from the <a href="https://rubyonrails.org/world/">Rails World conference</a> in Toronto and ready to share some news with you (not only from the world of Rails, of course).</p><div><hr></div><h1><strong>News</strong></h1><p><strong><a href="https://rubyonrails.org/2024/9/27/rails-8-beta1-no-paas-required">Rails 8 (beta) is out!</a></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_!89Qr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!89Qr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 424w, https://substackcdn.com/image/fetch/$s_!89Qr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 848w, https://substackcdn.com/image/fetch/$s_!89Qr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 1272w, https://substackcdn.com/image/fetch/$s_!89Qr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!89Qr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1350163,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!89Qr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 424w, https://substackcdn.com/image/fetch/$s_!89Qr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 848w, https://substackcdn.com/image/fetch/$s_!89Qr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.png 1272w, https://substackcdn.com/image/fetch/$s_!89Qr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8727219-bcf4-4ac6-99dd-d3da225852ee_2620x1424.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>Another major milestone for Rails is just around the corner. The new version&#8217;s slogan is &#8220;No PaaS required&#8221;: the framework provides all you need to deploy applications on any machine in minutes without any additional infrastructure dependencies. One of the missing pieces in Rails 7 was a Redis requirement for Action Cable. Now, we have <a href="https://github.com/rails/solid_cable">Solid Cable</a>, which uses a database as a pub/sub backend. <em>See Releases below for more Rails 8 related updates.</em></p><p><strong><a href="https://platform.openai.com/docs/guides/realtime/overview">OpenAI Realtime API</a></strong></p><p>OpenAI just introduced a new API&#8212;the Realtime API (<em>beta</em>) that allows you to communicate with LLMs via text and <strong>audio</strong> over WebSockets!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iG8N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iG8N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 424w, https://substackcdn.com/image/fetch/$s_!iG8N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 848w, https://substackcdn.com/image/fetch/$s_!iG8N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 1272w, https://substackcdn.com/image/fetch/$s_!iG8N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iG8N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png" width="1360" height="1126" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1126,&quot;width&quot;:1360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:219928,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iG8N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 424w, https://substackcdn.com/image/fetch/$s_!iG8N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 848w, https://substackcdn.com/image/fetch/$s_!iG8N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.png 1272w, https://substackcdn.com/image/fetch/$s_!iG8N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89dbe4bc-1a29-4851-bc2c-cb61e1c8d0bd_1360x1126.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>Which amazing new feature are you going to build with it?</p><h1>Events</h1><p><strong><a href="https://evilmartians.com/events/evolution-of-real-time-and-anycable-pro-euruko">Evolution of real-time and AnyCable Pro</a> (EuRuKo 2024)</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_!AUf2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AUf2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 424w, https://substackcdn.com/image/fetch/$s_!AUf2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 848w, https://substackcdn.com/image/fetch/$s_!AUf2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 1272w, https://substackcdn.com/image/fetch/$s_!AUf2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AUf2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png" width="1456" height="824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:824,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1735753,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AUf2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 424w, https://substackcdn.com/image/fetch/$s_!AUf2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 848w, https://substackcdn.com/image/fetch/$s_!AUf2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.png 1272w, https://substackcdn.com/image/fetch/$s_!AUf2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9031288-937c-48e9-aaa8-c4ac61ef8dd4_2924x1654.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>Take a quick look back (and forward) and see how the world of realtime web evolved over the past 10 years from the perspective of Team AnyCable. </p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/actioncable-next">actioncable-next</a></strong></p><p>The work on the new Action Cable architecture (see <a href="https://blog.anycable.io/p/any-cables-monthly-17">issue #17</a>) is almost done. What&#8217;s left is to do some field tests before we can merge this work into Rails. For that, we&#8217;ve extracted the functionality into a standalone gem, <a href="https://github.com/anycable/actioncable-next">actioncable-next</a>, that you can install into your existing Rails (7+) application to give it a try. See also the <a href="https://github.com/anycable/action-cable-next-playground">actioncable-next-playground</a> showcasing some example use cases for the new architecture.</p><p><strong><a href="https://github.com/anycable/graphql-anycable">graphql-anycable &#183; 1.3.0</a></strong></p><p>GraphQL AnyCable no longer requires using Redis pub/sub adapter for AnyCable. You can use any AnyCable broadcasting adapter in your application and configure Redis to store subscriptions separately!</p><div><hr></div><h1><strong>Frame of curiosity: Weird realtime transport: BroadcastChannel</strong></h1><p><a href="https://evilmartians.com/events/rails-on-wasm-sf-ruby-meetup">Earlier this year</a>, we&#8217;ve started exploring the possibility of leveraging WebAssembly powers for Rails applications. Yes, Rails in the browser! That might sound&#8230; strange?.. but consider it a research project that could bring results far beyond the goals we try achieve today.</p><p>It might not be clear from the first sight, what running a web application within the boundaries of the browser may have in common with realtime technologies. But the thing is: even if you have just a single instance of the application running for a single client, your application UX might still rely on live update functionality. </p><p>We cannot run a true WebSocket server in the browser; long-lived, streaming connections (e.g., SSE) to <em>wasmified</em> applications are also hardly possible. All we have is the browser, or a bit broader, a JavaScript runtime.</p><p>The good thing about full-featured realtime frameworks (like Action Cable or AnyCable) compared to pure transport-level libraries (hey, Socket.io) is that the actual real-time logic at both server and client ends <strong>do not depend on the actual transport implementation</strong>. Hence, all we need is to find a new transport that would fit the constraints.</p><p>One of the in-browser transports we successfully implemented is the <a href="https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel">BroadcastChannel</a>-driven one. If you want to learn more, check out our <a href="https://writebook-on-wasm.fly.dev/5/ruby-on-rails-on-webassembly/64/action-cable-on-wasm">Rails on Wasm handbook</a>.</p><p>Keep it weird &#128123;</p><p></p><p> </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #22: UI kit preview]]></title><description><![CDATA[July, 2024: UI Kit, preparing for connection avalanches, and the question of per-room vs per-user subscriptions]]></description><link>https://blog.anycable.io/p/any-cables-monthly-22-ui-kit-preview</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-22-ui-kit-preview</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 06 Aug 2024 18:03:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!B3Q2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The time of vacations, berry-picking and sun-burning, music and sports festivals (<em>aka </em>summer) is coming to an end. Soon, we&#8217;ll be back to full power mode and start working hard to meet this year&#8217;s goals. At AnyCable, we have two goals for 2024: 1) release the <em>Presence</em> feature, and 2) publish our new documentation website. Both are in progress, so stay tuned! Now, let&#8217;s take a look at what happened in July.</p><div><hr></div><h1><strong>Posts</strong></h1><p><strong><a href="https://evilmartians.com/chronicles/connection-avalanche-safety-tips-and-prepping-for-realtime-applications">Connection avalanche safety tips and prepping for real-time applications</a></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_!B3Q2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B3Q2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 424w, https://substackcdn.com/image/fetch/$s_!B3Q2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 848w, https://substackcdn.com/image/fetch/$s_!B3Q2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 1272w, https://substackcdn.com/image/fetch/$s_!B3Q2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B3Q2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png" width="1456" height="915" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:915,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:894831,&quot;alt&quot;:&quot;&quot;,&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;: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_!B3Q2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 424w, https://substackcdn.com/image/fetch/$s_!B3Q2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 848w, https://substackcdn.com/image/fetch/$s_!B3Q2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.png 1272w, https://substackcdn.com/image/fetch/$s_!B3Q2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81646ffa-69e3-46fb-9faa-ad1afc36e8e1_2168x1362.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><em>Connection avalanche</em> is a kind of thundering herd situation specific to real-time applications. This post gives an overview of possible prevention and mitigation measures. Even if you don&#8217;t expect high loads any time soon, it&#8217;s better to be aware of potential issues that may occur as you grow.</p><div><hr></div><h1><strong>News</strong></h1><p><strong><a href="https://www.figma.com/community/file/1402643723211987375">AnyCable collaboration UI kit</a></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_!RepZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RepZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 424w, https://substackcdn.com/image/fetch/$s_!RepZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 848w, https://substackcdn.com/image/fetch/$s_!RepZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 1272w, https://substackcdn.com/image/fetch/$s_!RepZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RepZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic" width="1000" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:61371,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&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_!RepZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 424w, https://substackcdn.com/image/fetch/$s_!RepZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 848w, https://substackcdn.com/image/fetch/$s_!RepZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 1272w, https://substackcdn.com/image/fetch/$s_!RepZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dcdf8c4-f9fd-40e7-8892-9568d95e37c7_1000x600.heic 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>We&#8217;ve been dreaming of providing some kind of real-time kit for AnyCable users for a while, and finally, the work has started: we&#8217;re happy to (pre-)announce our ready-made <strong>real-time components</strong>. The UI/UX part is mostly solved, and we&#8217;re ready to start working on the actual implementation. What do you think? Share your thoughts/suggestions on this initiative&#8211;respond to this email, or leave a comment on substack.</p><div><hr></div><h1>Events</h1><p><strong><a href="https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-hotwire-and-rails-era-at-reddotrubyconf-2024-singapore">Developer Tooling For The Modern Hotwire &amp; Rails Era</a></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_!j1BR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j1BR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 424w, https://substackcdn.com/image/fetch/$s_!j1BR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 848w, https://substackcdn.com/image/fetch/$s_!j1BR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 1272w, https://substackcdn.com/image/fetch/$s_!j1BR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j1BR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png" width="1456" height="807" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:807,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2504822,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!j1BR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 424w, https://substackcdn.com/image/fetch/$s_!j1BR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 848w, https://substackcdn.com/image/fetch/$s_!j1BR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.png 1272w, https://substackcdn.com/image/fetch/$s_!j1BR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08cea3e5-ae2a-47b8-83fc-7472f3ba12bf_3002x1664.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>Marco Roth travels across the world and shares his vision of the future of Hotwired Rails. Check the slides (videos are coming later) and see how much effort Marco puts into improving developer experience (DX) for engineers working on Hotwire applications&#8212;this is what the future development looks like, with DX as the top priority for engineers.</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/anycable-pubsub-nextjs">anycable-pubsub-nextjs</a></strong></p><p>We made the source code of our <a href="https://stackblitz.com/edit/anycable-pubsub">Stackblitz-hosted AnyCable Next.js example</a> available on GitHub. Feel free to hack around with it on your machine!</p><p><strong><a href="https://github.com/anycable/anycable-client">@anycable/core &#183; 0.9.1</a></strong></p><p>This tiny release brings one new useful feature: the ability to react to history-related events (e.g., `history_not_found`), so you can implement application-specific fallbacks. Check out <a href="https://github.com/anycable/anycable-client/pull/43">this PR</a> to learn more.</p><div><hr></div><h1><strong>Frame of curiosity: per-room vs per-user subscriptions</strong></h1><p>Recently, I had a discussion with one of the AnyCable Pro clients on their real-time application design. They build a chat-like application with <em>users</em> and <em>conversations</em>, and they started to question the design of the underlying real-time functionality (receiving conversation updates): &#8220;Are we modeling the real-time communication correctly?&#8221;, &#8220;Will it scale?&#8221;. I believe engineers must question themselves and re-visit their prior decisions regularly&#8212;that&#8217;s one of the keys to staying afloat. But we&#8217;re not here to talk software engineering philosophy stuff; let&#8217;s go back to the technical problem under consideration.</p><p>So, let&#8217;s assume we have <em>users</em> and <em>rooms</em> in our chatty application. Rooms can be public with many members or direct messaging rooms with just two communication ends. Here is, for example, our <a href="https://github.com/anycable/anycasts_demo/">AnyCasts demo</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_!6Dt3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6Dt3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 424w, https://substackcdn.com/image/fetch/$s_!6Dt3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 848w, https://substackcdn.com/image/fetch/$s_!6Dt3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 1272w, https://substackcdn.com/image/fetch/$s_!6Dt3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6Dt3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png" width="1456" height="973" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:973,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:116750,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6Dt3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 424w, https://substackcdn.com/image/fetch/$s_!6Dt3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 848w, https://substackcdn.com/image/fetch/$s_!6Dt3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.png 1272w, https://substackcdn.com/image/fetch/$s_!6Dt3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8bc861e-2be0-4eef-8c76-4e7657ba2831_1802x1204.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 typical approach in modeling real-time communication in chat rooms is to have a <em>RoomChannel</em> (we&#8217;re going to use Rails Action Cable as an example):</p><p><code>class RoomChannel &lt; ApplicationCable::Channel</code></p><p><code>  def subscribed</code></p><p><code>    room = current_user.rooms.find_by(params[:room_id])</code></p><p><code>    reject unless room</code></p><p><code>    stream_from room</code></p><p><code>  end</code></p><p><code>end</code></p><p>And then, when we want to deliver a new message, we broadcast it to the room:</p><p><code>class Room &lt; ApplicationRecord</code></p><p><code>  after_create_commit do</code></p><p><code>    RoomChannel.broadcast_to room, serialize(self)</code></p><p><code>  end</code></p><p><code>end</code></p><p>This is an example of <strong>per-room</strong> pub/sub model: for each chat room, we have a dedicated <em>stream</em>, and users subscribe to the relevant room streams to receive live updates.</p><p>This is a very efficient model in terms of broadcasting since it fully leverages pub/sub capabilities: we don&#8217;t care about actual subscribers when we deliver updates, all we know is the stream name. However, from the client-to-server communication point of view, it has some drawbacks.</p><p>Imagine we have a Chats screen where we list all the user&#8217;s conversations. In order to show new messages on the list, we should subscribe to all conversation streams! And there could be dozens and even hundreds of them. Surely, the WebSocket connection is still the one, but performing &#8220;subscribe&#8221; requests is not free (especially, in the example above when we reach out to the database to verify access).</p><p>Even if we don&#8217;t show updates on the Chats screen, browsing conversations may feel laggy, because we need to subscribe every time we open a chat screen (and unsubscribe afterward).</p><p>So, after facing such challenges, many decide to look at the kinda opposite strategy&#8212;<strong>per-user </strong>streams.</p><p>When using <strong>per-user </strong>streams, you only have a single stream per user but perform as many broadcasts as the room members number for every message created:</p><p>class UserChannel &lt; ApplicationCable::Channel</p><p>  def subscribed = stream_from current_user</p><p>end</p><p></p><p><code>class Room &lt; ApplicationRecord</code></p><p><code>  after_create_commit do</code></p><p><code>    room.members.each do</code></p><p><code>      UserChannel.broadcast_to(_1, serialize(self))</code></p><p><code>    end</code></p><p><code>  end</code></p><p><code>end</code></p><p>This approach drastically simplifies the client side of the communication: just a single data stream to consume updates from. You subscribe once, and it&#8217;s always on, you just need to route messages to the corresponding <em>stores</em>.</p><p>Well, the server could be not so happy with this change: now it has to perform O(N) broadcasts every time a message is created/updated, where N is the number of room members.  In other words, we ditched the pub/sub idea completely. (With AnyCable&#8217;s <a href="https://docs.anycable.io/ruby/broadcast_adapters?id=batching">batch broadcasts</a>, we can reduce the overhead, but still&#8230;)</p><p>As in many software problems, a combination of multiple techniques works better than each one independently. Instead of choosing either per-room or per-user approach, think of using both. For example, for DM conversations, using per-user approach makes sense: the number of DM dialogues can be huge but the number of members in each is very limited (so, the broadcasting overhead is negligible). For crowded public channels, it&#8217;s better to stick with pub/sub, i.e., per-room subscriptions.</p><p>Thank you for reading. See you next time!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #21]]></title><description><![CDATA[June, 2024: AnyCable module for Caddy to embed AnyCable into your application server. Mocking WebSockets. To self-host or not to?]]></description><link>https://blog.anycable.io/p/any-cables-monthly-21</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-21</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 02 Jul 2024 17:54:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!v6iy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Year 2024 just passed its equator (it&#8217;s 182 days &#8216;till 2025!)&#8212;have you noticed that? Well, now you know. In other news&#8230;</p><div><hr></div><h1><strong>News</strong></h1><p><strong><a href="https://awesome-selfhosted.net/#anycable">AnyCable is on awesome-selfhosted!</a></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_!v6iy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v6iy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 424w, https://substackcdn.com/image/fetch/$s_!v6iy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 848w, https://substackcdn.com/image/fetch/$s_!v6iy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 1272w, https://substackcdn.com/image/fetch/$s_!v6iy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v6iy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png" width="1456" height="647" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:647,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:233505,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v6iy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 424w, https://substackcdn.com/image/fetch/$s_!v6iy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 848w, https://substackcdn.com/image/fetch/$s_!v6iy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.png 1272w, https://substackcdn.com/image/fetch/$s_!v6iy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F180cafa7-98a6-48ea-8ae6-354a69bf8550_1976x878.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><div><hr></div><h1><strong>Videos</strong></h1><p><strong><a href="https://www.epicweb.dev/talks/mocking-websockets-with-msw">Mocking WebSockets with MSW</a></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_!DLix!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DLix!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 424w, https://substackcdn.com/image/fetch/$s_!DLix!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 848w, https://substackcdn.com/image/fetch/$s_!DLix!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 1272w, https://substackcdn.com/image/fetch/$s_!DLix!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DLix!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic" width="1456" height="1135" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1135,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:86957,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&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="" srcset="https://substackcdn.com/image/fetch/$s_!DLix!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 424w, https://substackcdn.com/image/fetch/$s_!DLix!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 848w, https://substackcdn.com/image/fetch/$s_!DLix!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 1272w, https://substackcdn.com/image/fetch/$s_!DLix!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca764cb-1e28-4e7b-b3e1-3889db6ce7f1_1468x1144.heic 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><a href="https://mswjs.io">Mock Service Worker</a> is a popular tool to fake APIs for JavaScript applications. Since the next version (available <a href="https://github.com/mswjs/msw/discussions/2010">in beta</a>), it supports mocking WebSockets, too! So, you can mock your WebSocket server in integration tests instead of running it (which is especially problematic with PaaS-es).</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/caddy-anycable">caddy-anycable </a>&#127881;</strong></p><p>Say hello to the official AnyCable module for <a href="https://caddyserver.com">Caddy</a>! Now you can embed AnyCable into your application server and reduce the number of infrastructure components. (Read more about Caddy in our <a href="https://blog.anycable.io/p/any-cables-monthly-20">previous issue</a>).</p><p><strong><a href="https://github.com/anycable/anycable-rails">anycable-rails &#183; 1.5.2</a></strong></p><p>AnyCable Rails now automatically detects Devise and activates the Warden middleware for RPC requests (so your authentication must work without any additional configuration).</p><p><strong><a href="https://github.com/anycable/anycable">anycable &#183; 1.5.1</a></strong></p><p>This release introduces Rack 3.1 compatibility.</p><h1><strong>Frame of curiosity: be your self-hosted</strong></h1><p>Have you ever wondered how many third-party infrastructure* services your application depends on? Okay, don&#8217;t start counting now (it could take time), bear with me for a minute. (*<em>By &#8220;infrastructure&#8220; we mean those not responsible for your application business logic.)</em></p><p>In the old days of bare metal servers and HTML 4.0 web applications, we hardly had any third parties involved in the process of deploying and maintaining our code. Cannot believe this? Let&#8217;s compare my very first production setup (circa 2010) with what we typically have nowadays (in the&nbsp;<em>old vs. new&nbsp;</em>format):</p><ul><li><p>SVN/FTP vs. Git (hence, we didn't even use GitHub)</p></li><li><p><code>make test &amp;&amp; cap deploy</code>&nbsp;vs. CI/CD</p></li><li><p><code>sendmail</code>&nbsp;vs. Mandrill/SES/Resend/etc&nbsp;</p></li><li><p><code>tail error.log | grep</code>&nbsp;vs. Honeybadger/Sentry</p></li><li><p>Monit / cron + curl vs. monitoring/uptime services</p></li><li><p>Erlang/OPT vs. Pusher/Ably (yeah, we were early WebSockets adopters)</p></li></ul><p>No, I&#8217;m not going to say that the grass was greener&#8212;there was no grass, that was a scorched desert. And it turned out to be very fertile soil&#8212;today we rely on many services while operating our applications. Sometimes they go down (and we&#8212;for another cup of coffee/tea); the more services you have, the more likely you&#8217;re affected by their&nbsp;<em>health</em>&nbsp;&#8212; a&nbsp;<em>micro-(third-party)-services</em>&nbsp;problem. (And I&#8217;m not even talking about $.)</p><p>Thus, although SaaS solutions proved to be helpful, even essential for web applications engineering and operations, it never hurts to consider self-hosted alternatives. Today, self-hosting is very different from 10-15 years ago; it&#8217;s not about dealing with tons of scripts and configuration tuning or writing custom code; usually, it&#8217;s just about running a single command to spin up a server and configuring it via a web UI&#8212;not more complicated than providing your billing information to a third party. The benefits are still the same: cost, privacy, and customizability.</p><p>For example, we at AnyCable self-host uptime monitoring via&nbsp;<a href="https://dev.to/palkan_tula/diy-multi-regional-uptime-monitoring-with-flyio-and-uptime-kuma-5c53">Uptime Kuma</a>&nbsp;and are considering switching to a self-hosted telemetry solution. What about you? (Check out&nbsp;<a href="https://awesome-selfhosted.net/">awesome-selfhosted</a>&nbsp;for some inspiration.)</p><div class="poll-embed" data-attrs="{&quot;id&quot;:189716}" data-component-name="PollToDOM"></div><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #20]]></title><description><![CDATA[April-May, 2024 AnyCable/Thruster]]></description><link>https://blog.anycable.io/p/any-cables-monthly-20</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-20</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 04 Jun 2024 20:23:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vAfN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey everyone! Looks like we&#8217;re turning into a bi-monthly newsletter &#128513; Luckily, the spring conference season is over and we have no excuses (and no alarms&#128680;) to continue keeping radio silence.</p><div><hr></div><h1><strong>Posts</strong></h1><p><strong><a href="https://centrifugal.dev/blog/2024/05/30/real-time-data-compression-experiments">Experimenting with real-time data compression by simulating a football match events</a></strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vAfN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vAfN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 424w, https://substackcdn.com/image/fetch/$s_!vAfN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 848w, https://substackcdn.com/image/fetch/$s_!vAfN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 1272w, https://substackcdn.com/image/fetch/$s_!vAfN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vAfN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png" width="1456" height="328" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87d43b46-57bb-4426-a245-800395e657c3_4002x902.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:328,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;delta frames&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="delta frames" title="delta frames" srcset="https://substackcdn.com/image/fetch/$s_!vAfN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 424w, https://substackcdn.com/image/fetch/$s_!vAfN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 848w, https://substackcdn.com/image/fetch/$s_!vAfN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 1272w, https://substackcdn.com/image/fetch/$s_!vAfN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d43b46-57bb-4426-a245-800395e657c3_4002x902.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>Our friends from Centrifugo recently released the <strong>delta compression</strong> feature for WebSocket clients, which they explore in this post using a football (or <em>soccer</em>) game live translation as an example use case. Great post and a very good example given that <a href="https://www.uefa.com/euro2024/">Euro 2024</a> is just around the corner (<em>Forza Italia &#127470;&#127481;!)</em></p><p>(If you want to dig deeper into the delta compression topic, check out our <a href="https://blog.anycable.io/p/any-cables-monthly-15">Issue #15</a>, where we talked about the diffing problem for real-time streams in the context of LiveView and Turbo Streams).</p><p><strong><a href="https://blog.anycable.io/p/livevoice-shares-how-they-use-anycable">LiveVoice shares how they use AnyCable</a></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_!WdFw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WdFw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 424w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 848w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WdFw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png" width="1456" height="1016" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1016,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:107184,&quot;alt&quot;:&quot;&quot;,&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;: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_!WdFw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 424w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 848w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.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>Read the story by Sebastian Poell, AnyCable user and <a href="https://livevoice.io">LiveVoice</a> co-founder, on how they use AnyCable to power real-time interpretation for guided tours. What I like most about this case study is that it&#8217;s full of technical details and real-time tips (i.e., not a marketing BS).</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/anycable/thruster">anycable/thruster &#183; 0.1.x</a></strong></p><p><a href="https://github.com/basecamp/thruster">Thruster</a> and AnyCable walk into a bar&#8230; Yes, this is a mix of two to make you run one process less! Check out <a href="https://github.com/anycable/anycable_rails_demo/pull/35">this demo PR</a> (also including a freshly released <a href="https://github.com/evilmartians/capybara-thruster">capybara-thruster</a> to speed-up your system tests).</p><p><strong><a href="https://github.com/anycable/anycable-client/blob/master/packages/turbo-stream/CHANGELOG.md#070">@anycable/turbo-stream &#183; 0.7.0 </a></strong></p><p>This release introduces a new configuration option&#8212;<code>delayedUnsubscribe</code>. This setting aims to solve a common problem (or <em>peculiarity</em>): avoid instant subscribe-unsubscribe commands in case the new page HTML contains the same <code>&lt;turbo-stream-source&gt;</code> elements (so our server does not process useless commands and our clients do not miss messages in-between).</p><p><strong><a href="https://github.com/anycable/anycable-client/blob/master/packages/turbo-stream/CHANGELOG.md#070https://github.com/anycable/anycable-client">@anycable/core &#183; 0.9.0 </a></strong></p><p>This release fixes a bunch of TypeScript inconsistencies.</p><p><strong><a href="https://github.com/anycable/thrusterhttps://github.com/anycable/anycable-go/releases/tag/v1.5.2">anycable-go &#183; 1.5.1-1.5.2 </a></strong></p><p>These tiny releases makes Server-Sent Events via AnyCable as powerful as WebSockets by porting all the missing features (signed streams, history offset, etc.). We also added <em>raw </em>mode for SSE clients to receive only data messages ignoring all protocol events.</p><h1><strong>Frame of curiosity: to thrust or not to thrust?</strong></h1><p><s>Thruster is going to be a part of Rails 8 distribution</s>. Well, <a href="https://github.com/rails/rails/pull/51793#issuecomment-2111321664">not a anymore</a> (and I&#8217;m glad we didn&#8217;t publish this issue a month ago &#128513;). Nevertheless, it is still worth discussing this potential change in the way we serve our Rails applications locally and in production.</p><p><a href="https://github.com/basecamp/thruster">Thruster</a> is a standalone proxy server which aims to stand in front of your <code>bin/rails s </code>and do some routine work: serve static assets, terminate SSL, etc. The concept of having a non-Ruby web server is not new to Rails (remember Passenger?), so why do we cycle back to it again? Because, it&#8217;s 2024, and not using HTTP/2+ and manually generating SSL certificates (when deploying on <em>bare metal</em>) is too old school even for Rails developers. DX (Developer eXperience) is what engineers care about today (if you don&#8217;t&#8212;please, start right now). And Thruster <em>aimed</em> to provide a decent one (<a href="https://x.com/dhh/status/1781053369693393245">&#8220;Heroku-like&#8221;</a>) for one-person Rails installations. &#8220;Aimed&#8221;, because it seems that <strong>Kamal 2 Proxy</strong> is going to replace it for production deployments. We&#8217;ll see <a href="https://rubyonrails.org/world/2024/speakers/kevin-mcconnell">this September</a>.</p><p>In any case, Rails 8 will have an official reverse proxy, whether you need or not (<code>--skip-kamal</code>). Of course, there are alternatives starting from good old Nginx (or its <a href="https://unit.nginx.org">Unit version</a>) and continuing with <a href="https://caddyserver.com">Caddy</a>, a modern and extensible application server. Let&#8217;s pay a bit more attention to the latter one.</p><p>As I said, Caddy is <strong>modern</strong>: supports HTTP/2 (and HTTP/3, if you wondered) and it manages SSL certificates with a matter of a configuration change (even for <code>localhost</code>). What&#8217;s more important, it has a pluggable architecture, and you can <strong>extend it via modules</strong>. There are some built-in modules (mostly typical reverse proxy features, such as redirect rules, etc.) and plenty of custom extensions (GeoIP decoding, caching, and many more). And of course, you can write your own!</p><p>Of course, the cherry on the top is the fact that Caddy has been running tons of applications for years. It&#8217;s a robust piece of software, so why can&#8217;t Rails developers benefit from using it like some PHP devs do via <a href="https://frankenphp.dev">FrankenPHP</a>? Why can&#8217;t we extrapolate the success of using Caddy for Rails applications deployment from <a href="https://hatchbox.io/announcements/17">Hatchbox</a> to everywhere else, including our local environments?</p><p>These questions have been bothering me since the very introduction of Thruster. Surely, greenfield Rails apps would benefit from Thruster/Kamal Proxy right away; it&#8217;s simple and it works (though it will take quite a bit of time to stabilize and mature); we can even extend it like we did with <a href="https://github.com/anycable/thruster">AnyCable Thruster</a>; but we&#8217;ll inevitably hit its limits; and I&#8217;m afraid sooner than later.</p><p>That&#8217;s why <em>we</em> (some mysterious &#8220;we&#8221; for now) started an R&amp;D project on building a smart reverse proxy for Rails applications on top of Caddy, covering use cases not only observed <em>once</em> but by many diverse applications and teams. And we want to make useful, Rails-friendly extensions for HTTP available out of the box: AnyCable, imgproxy, Wafris, etc.</p><p>If you like this idea, please share your suggestions on what might be nice to have in such a Rails-oriented application server.</p>]]></content:encoded></item><item><title><![CDATA[LiveVoice shares how they use AnyCable]]></title><description><![CDATA[Simultaneous interpretation and guided tours powered by AnyCable Pro]]></description><link>https://blog.anycable.io/p/livevoice-shares-how-they-use-anycable</link><guid isPermaLink="false">https://blog.anycable.io/p/livevoice-shares-how-they-use-anycable</guid><dc:creator><![CDATA[AnyCable]]></dc:creator><pubDate>Thu, 11 Apr 2024 18:24:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!WdFw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In early 2024, the co-founder of <a href="https://livevoice.io/en">LiveVoice.io</a>, Sebastian Poell, reached out with some feedback for AnyCable:</p><blockquote><p>LiveVoice&nbsp;is completely running on AnyCable - and it really rocks ;) I have to say, seeing the CPUs on an AWS c6g.2xlarge instance at only 6% utilization for 10K listeners is pretty crazy (in a very positive way) ^^ Aside from performance, using AnyCable fixed every issue we ever had with ActionCable (broken connection detection, race conditions, ...).</p></blockquote><p>We got excited and asked Sebastian for a few more details about the use case. But could we have imagined that Sebastian would write not just some sentences, but a full story of LiveVoice and the role of AnyCable in it?!<br><br>Without further ado, Sebastian&#8217;s story:</p><h2>About us</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WdFw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WdFw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 424w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 848w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WdFw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png" width="1456" height="1016" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1016,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:107184,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WdFw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 424w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 848w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!WdFw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa03af784-b166-41f2-882e-c3db6b715bd2_1720x1200.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><a href="https://livevoice.io/">LiveVoice</a> is an ultra-low-latency audio streaming SaaS platform, used mostly for simultaneous interpretation, guided tours, silent stages and audio description. What we do is basically transmitting audio and video from one point of the Earth to another with as little delay as possible (~0.2s), coupled with a friendly UI and tons of other features.</p><p>With LiveVoice, you can set up events and channels and invite your speakers and your audience. The speakers and the audience can then use our mobile apps or the website to simply join the event and speak / listen to your channels. You can imagine it a bit like Skype or Zoom, but instead of many people talking to each other, only one person speaks and thousands of people listen to them.</p><h2>Our setup</h2><p>Not only do we have to transmit audio/video data very fast to a lot of people, we also have to do a ton of signaling. For example, if a speaker presses the "mute" button, we need to inform the whole audience to display the muted state. Ok, that is simple. But what about allowing one speaker to switch between different channels? Or allowing a speaker to take over a stream from another active speaker? How do we handle connection losses and reconnects? When it comes to live events, being reliable in those scenarios becomes more challenging quickly.</p><p>Our backend is built with Rails and we "grew up" using Action Cable. For listeners and speakers, we provide a web interface as well as native apps for Android and iOS. Regarding the apps, building them natively turned out to be the only viable option for us. Hence, we had to build our own native Action/AnyCable libraries in <strong>Kotlin</strong> and <strong>Swift</strong>. Right now, there are about 20 inbound message types and 35 outbound message types. To always guarantee compatibility with old clients, we introduced versioning for cable channels (and messages) on the server.</p><h2>Challenge 1: Broken Connection Detection</h2><p>Whenever a speaker loses the network connection, we have to inform the audience and the other speakers that the speaker went offline as fast as possible. Just think of a guided tour in a city, where people walk around, having an unstable internet connection. For us, the (almost) instant, server-side detection of those broken connections is of utmost priority.</p><p>Since Rails does not support this kind of server-side broken connection detection as of now (although there are promising <a href="https://github.com/rails/rails/pull/50039">PRs</a>), a couple of years ago, we introduced our own version of a "pong". Every time a client received a "ping" from the server it responded with a "pong" back to the server. We also implemented a timeout using periodic timers and patched Rails to accept a "pong" format, similar to "ping". Using this workaround, we could set speakers who timed-out to offline within a couple of seconds.</p><p>As we wanted to migrate from ActionCable to AnyCable, we tried out different approaches to migrate or circumvent that pong feature, but got stuck. <a href="https://evilmartians.com">Evil Martians</a> to the rescue! We reached out and you (editor&#8217;s note: Martians) implemented that <a href="https://docs.anycable.io/misc/action_cable_protocol?id=new-command-pong-">pong feature</a> directly into AnyCable server. Exactly what we needed; even better because terminating the command in Go without the need of RPC is super performant.</p><p>Since we were already using the <a href="https://github.com/anycable/anycable-client">AnyCable JS client library</a> before even migrating our backend to AnyCable, we did not even had to implement the client side "pong" responses in the web client, we just had to enable them.</p><h2>Challenge 2: Tidy up!</h2><p>I think, one very common pitfall when using <em>cables</em> is that code often looks like it should happen synchronously, but in fact happens asynchronously. For example:</p><pre><code>stream_from("my_stream")
ActionCable.server.broadcast("my_stream", { hello: :world })
stop_stream_from("my_stream")</code></pre><p>Does the client receive the message? Well, it&#8217;s random, depending on when the broadcast is done (note that the behaviour of Action Cable and AnyCable regarding when streams are subscribed differ). Take another example:</p><pre><code>ActionCable.server.broadcast("my_stream", { hello: :world_1 })
ActionCable.server.broadcast("my_stream", { hello: :world_2 })</code></pre><p>Both messages will be received by the clients without the guarantee of any particular order. AnyCable helps us here by allowing us to <a href="https://docs.anycable.io/edge/ruby/broadcast_adapters?id=batching">send broadcasts in batches</a> making sure broadcasted messages are always sent in order, which increases reliability and reduces the need for workarounds.</p><p>Also, we occasionally found ourselves in the situation that the current user who performed an action needed to get another response from the server than all the other clients. For example, when a speaker switches the channel, we need to send a lot of information to this speaker but all other speakers should only get a very brief message that a switch happened. AnyCable's <a href="https://docs.anycable.io/rails/getting_started?id=broadcast-to-others">broadcast-to-other feature</a> came in super handy here. Now we can send different responses to the current user and to all other users:</p><pre><code>ActionCable.server.broadcast("my_stream", { type: :another_speaker_switched }, to_others: true)
transmit({ type: :special_response_for_current_speaker })</code></pre><p>This allowed us to tidy up our responses, send fewer messages in general (which is also easier to debug and to test) and simplified our client-side code bases.</p><h2>Challenge 3: Performance</h2><p>When running a streaming service, load testing is one important part of what lets us sleep well at night. Thus, we implemented our own CLI load-testing tool, based on our iOS client libraries (in Swift). This is especially useful, because with our own libraries, we can test realistic-behaving LiveVoice clients without the need to implement them in tools like <a href="https://k6.io">k6</a> or Selenium. Our simulated listeners join an event, press start/stop once in a while and are streaming real audio. When testing AnyCable, we found that 10K listeners only consumed approx. 6% of the server&#8217;s CPU &#8212;which was pretty much unheard-of for us &#128513;</p><blockquote><p>Stack: AWS c6g.2xlarge instance (ARM64), Debian 12, Ruby 3.3 + YJIT, AnyCable 1.4 (via HTTP RPC, pongs enabled), Jemalloc 5.3, Rails 7.1, Puma 6.4, Redis 7, Nginx 1.22. Note, that this server does not handle the actual audio/video streaming or the database, but handles all the web traffic and API requests, as well as all websocket connections.</p></blockquote><h2>Outlook</h2><p>We are super happy with migrating to AnyCable and we'll definitely continue to dive into all the features (and there are a lot!). Especially relevant to our use case are features like <a href="https://docs.anycable.io/anycable-go/binary_formats">optimized messaging formats</a> or <a href="https://docs.anycable.io/anycable-go/reliable_streams?id=redis">multi-regional scaling</a>. An exciting future ahead &#129761; and cheers to you, Evil Martians!</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/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 AnyCable Broadcasts! Subscribe for free to receive new posts and support our 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[Any Cables Monthly #19]]></title><description><![CDATA[March, 2024: AnyCable v1.5 introduces simplified streams and whispers]]></description><link>https://blog.anycable.io/p/any-cables-monthly-19</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-19</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 02 Apr 2024 22:39:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ieCE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Did you miss us? We decided to take a break in February, but this means more cool stuff for this issue. Buckle up!</p><div><hr></div><h1><strong>Highlights</strong></h1><p><strong><a href="https://docs.anycable.io/release_notes?id=_150">AnyCable v1.5 is out!</a> Grab yours <a href="https://anycable.io">here.</a></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_!ieCE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ieCE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 424w, https://substackcdn.com/image/fetch/$s_!ieCE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 848w, https://substackcdn.com/image/fetch/$s_!ieCE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 1272w, https://substackcdn.com/image/fetch/$s_!ieCE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ieCE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png" width="1456" height="1052" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1052,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:971450,&quot;alt&quot;:&quot;AnyCable v1.5 communication diagram with signed streams and whispering&quot;,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="AnyCable v1.5 communication diagram with signed streams and whispering" title="AnyCable v1.5 communication diagram with signed streams and whispering" srcset="https://substackcdn.com/image/fetch/$s_!ieCE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 424w, https://substackcdn.com/image/fetch/$s_!ieCE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 848w, https://substackcdn.com/image/fetch/$s_!ieCE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.png 1272w, https://substackcdn.com/image/fetch/$s_!ieCE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85da9cd6-80af-4e11-9419-8218aaf1d346_1456x1052.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>We are glad to announce our new release&#8212;<strong>AnyCable v1.5</strong>, which adds a <strong>simplified</strong> <strong>standalone pub/sub mode</strong>: no RPC, Socket.IO style. Other updates include whispering (broadcasts that do not touch backend) which is super useful for <strong>typing indicators</strong>, <strong>cursors</strong> and similar features.</p><p>Check out the <a href="https://docs.anycable.io/release_notes?id=_150">release notes</a> for more information or take a look at a couple of new demos:</p><ul><li><p>Minimal messaging Next.js app demonstrating <strong>public streams</strong> (<a href="http://stackblitz.com/edit/anycable-pubsub">Stackblitz</a>)</p></li><li><p>Using <strong>signed streams</strong> and <strong>whispering</strong> for type indicators in our To-do/chat Rails app (<a href="https://github.com/anycable/anycable_rails_demo/pull/34">GitHub PR</a>)</p></li></ul><p>P.S. We recently announced AnyCable v1.5 at the SF Bay Area Ruby Meetup, check out <a href="https://www.youtube.com/watch?v=9-PWz9nbrT8&amp;t=1714s">the video</a> (and don&#8217;t miss other talks from the meetup).</p><p>P.P.S. <a href="http://plus.anycable.io">AnyCable+</a> now runs on v1.5, so you can take the new simplified abstractions for a spin with just a few clicks. </p><div><hr></div><h1><strong>News</strong></h1><p><strong><a href="https://reverb.laravel.com">Laravel 11 brings Reverb</a></strong></p><p>Laravel got its own official WebSocket server. The benchmarks look pretty cool, but let&#8217;s wait while we figure out the <a href="https://github.com/orgs/anycable/discussions/226">AnyCable story for Laravel</a>.</p><div><hr></div><h1>Talks</h1><p><strong><a href="https://evilmartians.com/events/seven-deadly-rails-anti-patterns-sin-city-ruby-2024">Seven deadly Rails anti-patterns</a> </strong>at SinCityRuby (or, the reason we didn&#8217;t publish our previous Monthly).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2Qhc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2Qhc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 424w, https://substackcdn.com/image/fetch/$s_!2Qhc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 848w, https://substackcdn.com/image/fetch/$s_!2Qhc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 1272w, https://substackcdn.com/image/fetch/$s_!2Qhc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2Qhc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png" width="1456" height="1002" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1002,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2579786,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2Qhc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 424w, https://substackcdn.com/image/fetch/$s_!2Qhc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 848w, https://substackcdn.com/image/fetch/$s_!2Qhc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.png 1272w, https://substackcdn.com/image/fetch/$s_!2Qhc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624a27a5-4270-49eb-b8ae-43adbf6f55c2_2512x1728.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>One of the <em>sins</em> mentioned in the talk is page refreshes (Turbo 8 feature). Wonder how it could be both good and evil? Check out the slide (sorry, no video was recorded).</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/hotwired/turbo-rails/releases/tag/v2.0.0-beta.1https://github.com/hotwired/turbo/releases/tag/v8.0.0">turbo &#183; 8.0.x</a></strong></p><p>Turbo 8 is conquering the Rails world! Morphing, refreshes, view transitions, insta clicks. How do you like it? </p><div><hr></div><h1><strong>Frame of curiosity: AnyCable Broadcasts</strong></h1><p>No, this is not a new feature announcement &#128513; &#8220;AnyCable Broadcasts&#8221; is the name of our blog on Substack (this one). We decided to go all-in with Substack and use it for articles, case studies, screencasts, short notes, and this newsletter&#8212;a shared home for all AnyCable and realtime-related content we produce.</p><p>So, expect more <s>emails</s> <em>broadcasts</em> from AnyCable appearing in your inbox soon. Here is a teaser of our first Customer Column post arriving next week:</p><div class="pullquote"><p> I have to say, seeing the CPUs on an AWS c6g.2xlarge instance at only 6% utilization for 10K listeners is pretty crazy (in a very positive way)</p></div><p>For now, let us share the Top-5 broadcasts we transmitted over the years and just re-transmitted to Substack:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;cdf767fa-d1bf-4a74-a0b9-6bd9de98b52c&quot;,&quot;caption&quot;:&quot;Originally published on Martian Chronicles WebSockets has been around for years, but its popularity isn&#8217;t showing any signs of fading. They still power most of the real-time web, primarily because they&#8217;re supported by 98% of browsers in use today (Opera Mini users, we miss you). However, browsers, mobile applications, and other&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;AnyCable off Rails: connecting Twilio streams with Hanami&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:122916213,&quot;name&quot;:&quot;AnyCable&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbd26f82-c5da-4c57-9d22-568218a5cbd2_260x260.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-03-21T07:00:00.000Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d48c113-c31f-4623-8e1a-ce155ec2d405_1978x740.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://anycable.substack.com/p/anycable-off-rails-connecting-twilio&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:143180569,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;AnyCable Broadcasts&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee4b1ee-eca5-41e8-9d08-d39e95284694_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;6c55c747-4118-41e4-b6e1-dfd84b56a54c&quot;,&quot;caption&quot;:&quot;In this episode, we explore the recently released embedded NATS support in AnyCable-Go and see how it can be used to simplify building multi-regional Rails/AnyCable applications on Fly.io.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Flying multi-regionally with NATS&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:122916213,&quot;name&quot;:&quot;AnyCable&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbd26f82-c5da-4c57-9d22-568218a5cbd2_260x260.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-03-24T07:00:00.000Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/youtube/w_728,c_limit/TUHL5jb9jBo&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://anycable.substack.com/p/flying-multi-regionally-with-nats&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:143180537,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;AnyCable Broadcasts&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee4b1ee-eca5-41e8-9d08-d39e95284694_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;d4c5ab4f-a950-45ef-b56c-d3caffb1e141&quot;,&quot;caption&quot;:&quot;This episode is a recording of the AnyCable Meetup dedicated to v1.4 release. We talked a bit about AnyCable history, demonstrated new features, such as Reliable Streams and Long polling support, and also revealed our plans for the future.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;AnyCable v1.4: reliable real-time for all: Ruby, Rails, Hotwire and beyond&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:122916213,&quot;name&quot;:&quot;AnyCable&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbd26f82-c5da-4c57-9d22-568218a5cbd2_260x260.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-07-25T19:00:00.000Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/youtube/w_728,c_limit/4n1SxfK0Uqg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://anycable.substack.com/p/anycable-v14-reliable-real-time-for&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:143180065,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;AnyCable Broadcasts&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee4b1ee-eca5-41e8-9d08-d39e95284694_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;17041e22-800b-40c8-9290-01276143b5e4&quot;,&quot;caption&quot;:&quot;This episode is a spin-off to the RailsConf 2022 talk \&quot;The pitfalls of realtime-ification\&quot; and is dedicated to a particular pitfall&#8212;consistency. We're going to demonstrate how to make Turbo Streams reliable and make a switch from the \&quot;at-most once\&quot; to the \&quot;exactly-once\&quot; delivery guarantee.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Turbo Streams vs. consistency&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:122916213,&quot;name&quot;:&quot;AnyCable&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbd26f82-c5da-4c57-9d22-568218a5cbd2_260x260.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2022-07-19T07:00:00.000Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/youtube/w_728,c_limit/dG8kUy2IVhU&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://anycable.substack.com/p/turbo-streams-vs-consistency&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:143180473,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;AnyCable Broadcasts&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee4b1ee-eca5-41e8-9d08-d39e95284694_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;584f7bfb-3b45-4ef0-aefe-c1a65f9da863&quot;,&quot;caption&quot;:&quot;Introducing multi-tenancy to a web application usually comes at a price: we need to (re&#8211;)design a database schema, ensure all kinds of \&quot;requests\&quot; are bound to the right tenants, and so on. Luckily, for Rails applications, we have battle-tested tools to make developers' lives easier. However, all of them focus on classic Rails&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Multi-tenancy vs. Cables: Introducing Action Cable command callbacks&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:122916213,&quot;name&quot;:&quot;AnyCable&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbd26f82-c5da-4c57-9d22-568218a5cbd2_260x260.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2022-07-05T07:00:00.000Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aedcc91b-690d-46d4-a605-5a3056e6fccb_2020x1132.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://anycable.substack.com/p/multi-tenancy-vs-cables-introducing&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:143180393,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;AnyCable Broadcasts&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee4b1ee-eca5-41e8-9d08-d39e95284694_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>Please, tell us what you think about our AnyCable Broadcasts idea and what would you like to receive through this <em>channel</em>!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/p/any-cables-monthly-19/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/p/any-cables-monthly-19/comments"><span>Leave a comment</span></a></p><p>And here&#8217;s how to subscribe:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.anycable.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.anycable.io/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly 18+]]></title><description><![CDATA[February, 2024: Managed AnyCable plus.anycable.io]]></description><link>https://blog.anycable.io/p/any-cables-monthly-18</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-18</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Wed, 07 Feb 2024 01:06:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7Bnq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#8220;<a href="https://once.com">Once</a> upon a real-time&#8230;&#8221;&#8212;that could be an interesting beginning for an IT fairy tale full of heroes and villains, magic and <em>stience</em>. But&#8230; We&#8217;re a <strong>news</strong>letter, so let&#8217;s keep on sharing news! </p><div><hr></div><h1><strong>Highlights</strong></h1><p><strong><a href="https://plus.anycable.io">AnyCable+ is here!</a></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_!7Bnq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Bnq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 424w, https://substackcdn.com/image/fetch/$s_!7Bnq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 848w, https://substackcdn.com/image/fetch/$s_!7Bnq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 1272w, https://substackcdn.com/image/fetch/$s_!7Bnq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Bnq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png" width="1456" height="1008" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1008,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:836948,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Bnq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 424w, https://substackcdn.com/image/fetch/$s_!7Bnq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 848w, https://substackcdn.com/image/fetch/$s_!7Bnq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.png 1272w, https://substackcdn.com/image/fetch/$s_!7Bnq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60728020-32b2-4f1e-99bd-24c5142eba5f_1958x1356.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>We are introducing <strong><a href="http://plus.anycable.io">AnyCable+</a></strong>, a Software-as-a-<strong>Quick</strong>-Service product (yes, <em>SaaQS</em>) that helps you to get started with reliable real-time features with just a few clicks. (No worries! AnyCable remains open-source in its core, so we expect you to run it on premise as soon as you hit higher loads; but while you&#8217;re working hard on reaching this goal, we&#8217;d like you to worry less about managing a real-time server.)</p><p><strong>Free for early users. </strong>We hope you'll try it out and share your feedback (you can always reply to this email to reach us).</p><p><strong><a href="https://once.com/campfire">ONCE Campfire is publicly available &#128293;</a></strong></p><p>The first ONCE project has been released and it&#8217;s a real-time chat application, Campfire. The ONCE model implies a one-time payment and on-premise installation. But what&#8217;s more important for our newsletter, you get access to the codebase and are free to learn from it or modify it to fit your needs.</p><p>For example, you can try replacing Campfire&#8217;s Action Cable with AnyCable and see if it boosts the performance (spoiler: it does). Just like <a href="https://x.com/palkan_tula/status/1753149601312600142?s=20">I did</a> &#128578;.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UJxw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UJxw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UJxw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UJxw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UJxw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UJxw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg" width="1400" height="770" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:770,&quot;width&quot;:1400,&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;: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="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!UJxw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UJxw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UJxw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UJxw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9aae4b6-afef-4257-8fd0-1aa13727390f_1400x770.jpeg 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">Campfire + AnyCable+ = &#128170;</figcaption></figure></div><div><hr></div><h1><strong>News</strong></h1><p><strong><a href="https://github.com/rails/rails/pull/50979">Action Cable adapterization</a></strong></p><p>A huge initiative on bringing Action Cable to the next level has just kicked off with <a href="https://github.com/rails/rails/pull/50979">this pull request</a>. The initial PR is mostly code reorganization (<em>housekeeping</em>) but the number of possibilities it opens is amazing. You can learn more from the <a href="https://docs.google.com/document/d/1oGf86NAzQL9sDw6rTfUNSe3mzzg7wX64sc34D-_3EDI/edit#heading=h.d3db1fd03ano">document</a>. </p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/hotwired/turbo-rails/releases/tag/v2.0.0-beta.1https://github.com/hotwired/turbo/releases/tag/v8.0.0-rc.3">turbo &#183; 8.0.0-rc.3</a></strong></p><p>Turbo 8 reached its third release candidate and the final release is just around the corner. We&#8217;ve talked a lot about its features in the <a href="https://anycable.substack.com/p/any-cables-monthly-14">previous issues</a>, so we&#8217;re not going to repeat ourselves. Remember: <strong>morph responsibly!</strong></p><p><strong><a href="https://vercel.com/templates/next.js/anycable">AnyCable real-time starter kit</a></strong></p><p>We launched the official Vercel template to deploy a Next.js application powered by AnyCable. Combine it with AnyCable+, and you have a full-featured real-time application in minutes for free!</p><div><hr></div><h1><strong>Frame of curiosity: channels vs. streams</strong></h1><p>One of the distinguishing features of Action Cable (and AnyCable) is encapsulation of real-time interactions into <em>channels</em>. The actual pub/sub is <em>hidden</em> from the client. Let me demonstrate what I mean by comparing two Rails chat implementations: one using Action Cable and another one using Pusher (well, it&#8217;s still popular &#129335;&#8205;&#9794;&#65039;).</p><p>Here is the Action Cable version (showing only the relevant parts):</p><pre><code># A Stimulus controller used to subscribe to updates
export default class extends Controller {
  connect() {
    const channel = "ChatChannel";
    const id = this.data.get("id");

    this.channel = cable.subscriptions.create(
      { channel, id },
      {
        received: (data) =&gt; {
          this.handleMessage(data);
        },
      }
    );
  }

  handleMessage(msg) { ... }
}

# A server-side channel
class ChatChannel &lt; ApplicationCable::Channel
  def subscribed
    room = user.chat_rooms.find_by(id: params[:id])
    return reject unless room
    stream_for room
  end
end

# An example of publishing an event
class MessagesController &lt; ApplicationController
  def create
    message = @room.messages.create!(message_params)
    ChatChannel.broadcast_to(@room, message.as_json)
  end
end</code></pre><p>And here is the same functionality backed by Pusher:</p><pre><code><code>export default class extends Controller {
  connect() {
    const id = this.data.get("id");

    this.channel = pusher.subscribe(`chat:${id}`);
    this.channel.bind("message", this.handleMessage.bind(this));
  }

  handleMessage(msg) { ... }
}

class MessagesController &lt; ApplicationController
  def create
    message = @room.messages.create!(message_params)
    pusher.trigger("chat:#{@room.id}", "message", message.as_json)
  end
end</code></code></pre><p>The Pusher version is more concise and, frankly speaking, easier to digest: it&#8217;s clear what happens at both ends of this <em>feature.</em> We manage pub/sub channel directly, i.e., <strong>we subscribe to the same string identifier as we use to publish updates</strong>. There is nothing in between.</p><p>This communication design is used by most real-time frameworks. Why is Action Cable designed differently? I don&#8217;t know (I&#8217;m not the author), but I can see some benefits in using channels, especially in Ruby on Rails. They&#8217;re all hidden in the differences.</p><p>In Action Cable, we <strong>have to define a channel class</strong> that acts as a middleman between a client and a server. What may seem like an unnecessary boilerplate is actually a great way to <strong>organize logic around the communication channel</strong>. If you go beyond a demo application, you quickly realize that you need to deal with security (authentication, authorization) and maintainability concerns.</p><p>Let&#8217;s consider stream authorization. How would you implement it with a channel-less pub/sub? For example, Pusher <em>asks</em> a subscription permission from your application over HTTP. And then you need to write something like this:</p><pre><code><code>class PusherAuthController &lt; ApplicationController
  before_action :authenticate_user!

  def auth
    channel_name = params[:channel_name]
    if current_user_has_access?(channel_name)
      response = Pusher.authenticate(params[:channel_name], params[:socket_id])
      render json: response
    else
      render json: { error: 'Unauthorized' }, status: :unauthorized
    end
  end

  private

  def current_user_has_access?(channel_name)
    case channel_name
    in /chat:(?&lt;id&gt;\d+)/ if $~ in {id:}
      ChatRoom.find(id).members.where(id: current_user.id).exists?
    in /some_other_channel/
      # ...
    end
  end
end</code></code></pre><p>Oops! That&#8217;s a lot of code (we had a single line for that in our channel class). Furthermore, imagine having a dozen of different streams with their specific authorization logic. You&#8217;ll probably end up with a custom abstraction to keep pub/sub authorization code maintainable. Maybe, even <em>channels</em> &#128578; (That&#8217;s how Laravel Echo and Elixir Phoenix work, for example).</p><p>Pub/sub encapsulation also makes it dead simple to <strong>subscribe a client to multiple data streams</strong> within the same subscription without even letting the client know about this. Here is an example:</p><pre><code><code>class ChatChannel &lt; ApplicationCable::Channel
  def subscribed
    room = user.chat_rooms.find_by(id: params[:id])
    return reject unless room
    stream_for room

    # Additional stream for moderator updates
    stream_for([room, :moderators]) if room.moderator?(user)
  end
end</code></code></pre><p>Note that we <strong>don&#8217;t use string stream identifiers</strong> but pass Rails models instead. This is truly Rails way of dealing with the naming and consistency problems! Don&#8217;t argue which delimiter to use, &#8220;:&#8221; or &#8220;/&#8221;, just use what Rails suggests! That reduces the conceptual complexity of your codebase.</p><p>The last but not the least reason to choose channels over <em>bare</em> pub/sub is their <strong>RPC capabilities</strong>. With channels, handling client messages is straightforward; you have the channel and connection context and scope; and you have a file in your codebase where to put the logic!</p><p>So, encapsulation rocks. But what about Hotwire? Doesn&#8217;t it call into question everything I said above? Yes, it does. Hotwire demonstrates how to take another step further away from implementation towards abstractions. No more channels, no more JS. Now we have <strong>a pub/sub wrapped into Action Cable channels</strong>!</p><p>Still, even with Hotwire, if you want to implement a more sophisticated real-time logic, you can go with custom Action Cable channels (see examples <a href="https://evilmartians.com/events/the-pitfalls-of-realtime-ification">in this talk</a>). But that&#8217;s rarely needed. Authorization is covered by <strong>signed streams</strong>, no need for multiple streams and RPC.</p><p>That makes me think that having a generic <em>secure</em> pub/sub over Action Cable similar to Hotwire would be a nice addition to the framework. What do you think?</p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #17]]></title><description><![CDATA[January, 2024: Action Cable server adapterization]]></description><link>https://blog.anycable.io/p/any-cables-monthly-17</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-17</guid><dc:creator><![CDATA[Vova Dem]]></dc:creator><pubDate>Tue, 02 Jan 2024 13:14:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V_Wm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to 2024 &#129395; ! In this special holiday-riddle edition, we share just the names of some real-time initiatives started in late 2023 to be revealed in 2024. For now, we invite you to become fortune tellers and come up with your foresights! (Feel free to share them with us)</p><div><hr></div><h1><strong>Frames of future &#9203;</strong></h1><h3>AnyCable+</h3><p>Recently, a <a href="https://gemfile.directory/gemfiles/7a8af9c7-a3f8-467e-9a98-c27908bf1a55">Gemfile of the new AnyCable project</a> &#8220;leaked&#8221; online. The codename is &#8220;AnyCable+&#8221;, and it&#8217;s clearly a Rails app. But what is it for? Although we are eager to share everything with you right now, let us intrigue you a bit longer.</p><h3>Action Cable server adapterization project</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V_Wm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V_Wm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 424w, https://substackcdn.com/image/fetch/$s_!V_Wm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 848w, https://substackcdn.com/image/fetch/$s_!V_Wm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 1272w, https://substackcdn.com/image/fetch/$s_!V_Wm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V_Wm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic" width="1456" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/708dedbd-75b9-42b5-ad91-5dbca86cc546.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:160210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&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_!V_Wm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 424w, https://substackcdn.com/image/fetch/$s_!V_Wm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 848w, https://substackcdn.com/image/fetch/$s_!V_Wm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 1272w, https://substackcdn.com/image/fetch/$s_!V_Wm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F708dedbd-75b9-42b5-ad91-5dbca86cc546.heic 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>Together with Samuel Williams (who <a href="https://twitter.com/ioquatix/status/1734520142586130883">shared this diagram on Twitter</a>), we started working on Action Cable improvements that would make it much easier to use different server implementations (e.g., Async) and even paradigms (like AnyCable) with Rails Action Cable. </p><h3>Laravel Reverb</h3><p>It looks like Laravel&#8217;s real-time component, Echo, will soon have an upgrade. The project named <a href="https://laravel-news.com/laravel-reverb">&#8220;Laravel Reverb&#8221; is expected to be released soon</a>. What the next-gen real-time for PHP will look like?</p><h3>SolidCable</h3><p>Haven&#8217;t heard about it? Me neither. But who knows what DHH has up his sleeve. (Btw, check out his <a href="https://evilmartians.com/events/dev-propulsion-labs-episode-9-david-heinemeier-hansson-dhh-basecamp-hey-ruby-on-rails-creator">latest interview for our Dev Propulsion Labs</a>).</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Any Cables Monthly #16]]></title><description><![CDATA[December, 2023: Advent of real-time code &#128467;&#65039; &#127877;]]></description><link>https://blog.anycable.io/p/any-cables-monthly-16</link><guid isPermaLink="false">https://blog.anycable.io/p/any-cables-monthly-16</guid><pubDate>Tue, 05 Dec 2023 15:21:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0Gml!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The winter holiday season is approaching &#127876;. Let&#8217;s enjoy one of the latest bits of information on real-time technologies from 2023 and prepare for 2024!</p><div><hr></div><h1><strong>News</strong></h1><p><strong>Action Cable features in development</strong></p><p>At the end of the year, the number of feature PRs to Action Cable spiked (compared to previous years, which were pretty quiet). Noticeable contributions (yet-to-be-merged) include&nbsp;<a href="https://github.com/rails/rails/pull/50039">pong support</a>&nbsp;(to improve half-open connections detection) and&nbsp;<a href="https://github.com/rails/rails/pull/49903">broadcast payload compression</a>&nbsp;for the PostgreSQL adapter (to overcome the 8kb limit).</p><p>More PRs are to come in 2024 from Honestly Yours regarding different server implementation support (such as Async). Stay tuned!</p><div><hr></div><h1><strong>Posts</strong></h1><p><strong><a href="https://quic.video/blog/replacing-webrtc/">Replacing WebRTC. The long path to use&nbsp;</a></strong><em><strong><a href="https://quic.video/blog/replacing-webrtc/">something else</a></strong></em><strong><a href="https://quic.video/blog/replacing-webrtc/">&nbsp;for real-time media.</a></strong></p><p>The article provides an excellent overview of new web technologies to bring next-gen real-time streaming experience and capabilities to browsers, including&nbsp;<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API">WebCodecs</a>&nbsp;and&nbsp;<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API">WebTransport</a>. Check it out to learn how we will write real-time applications (not only media-related) in a couple of years.</p><p><strong><a href="https://fly.io/ruby-dispatch/turbo-8-in-8-minutes/">Turbo 8 in 8 minutes</a></strong></p><p>We&#8217;ve been talking about Turbo 8 for a while. Now, when the first beta&nbsp;<a href="https://github.com/hotwired/turbo/releases/tag/v8.0.0-beta1">has been released</a>, you can try it yourself. And Brad&#8217;s post is a great starting point.&nbsp;</p><div><hr></div><h1><strong>Releases</strong></h1><p><strong><a href="https://github.com/hotwired/turbo-rails/releases/tag/v2.0.0-beta.1">turbo-rails &#183; 2.0.0-beta.1</a></strong></p><p>A companion update for Turbo 8 beta.1 bringing page refreshes support to Rails. (Think twice before adding&nbsp;broadcasts_refreshes&nbsp;to your model: it publishes an update on every change, which you might not want).</p><div><hr></div><h1><strong>Frame of curiosity: Advent of real-time code &#128467;&#65039; &#127877;</strong></h1><p>Every December, millions worldwide participate in advent-calendar-driven challenges in anticipation of Christmas (or just for fun). Modern challenges vary from eating chocolate to collecting Lego figures, drinking coffee and tea, and solving programming puzzles. Let&#8217;s focus on the latter ones.</p><p><a href="https://adventofcode.com/">Advent of Code</a>&nbsp;is the most prevalent challenge among software engineers (it has already started, but it&#8217;s never too late to join). However, there are many other coding challenges for you out there. For example, we have&nbsp;<a href="https://kddnewton.com/2023/11/30/advent-of-prism-part-0.html?ref=dailydev">Advent of Prism</a>&nbsp;(a new Ruby parser) in Ruby world.</p><p>I asked myself what a version of Advent of Code focused on the real-time web looks like and started sketching possible challenges. I&#8217;m unsure if I will ever make it live (maybe next year?), so I&#8217;d like to share some of my favorites with you.</p><h3><strong>Day 1. tail + cURL = real-time logs</strong></h3><p>You want to share your production server logs in real-time with another developer who has access to a headless Unix machine with only the essential CLI tools. You have access to a production machine and can write a program in the language of your choice. Write a program that accepts a stream of logs via standard input (Unix pipes) and exposes them over HTTP to the outside world so that you can consume them via cURL:</p><p>tail -f production.log | ./my-server</p><p>curl -N "http://my-server-ip/logs"</p><h3><strong>Day 2. Rock, Paper, Scissors, Lizard, Spock</strong></h3><p>Implement a terminal, HTTP-driven&nbsp;<a href="https://www.wikihow.com/Play-Rock-Paper-Scissors-Lizard-Spock">Rock, Paper, Scissors, Lizard, Spock</a>&nbsp;game. Players issue HTTP requests with the same game ID and their choice to the real-time game server, and as soon as both players send their requests, the server responds to both with the result:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Gml!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Gml!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0Gml!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0Gml!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0Gml!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Gml!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg" width="1456" height="650" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:650,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A screenshot of a computer screen\n\nDescription automatically generated&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="A screenshot of a computer screen

Description automatically generated" title="A screenshot of a computer screen

Description automatically generated" srcset="https://substackcdn.com/image/fetch/$s_!0Gml!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0Gml!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0Gml!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0Gml!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa494b382-985a-4a4a-9dab-81ab7c40f589_1456x650.jpeg 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>Keep in mind that there could be multiple concurrent games.</p><h3><strong>Day 3. ABC duel</strong></h3><p>Let&#8217;s build a 2-player real-time game called &#8220;ABC Duel&#8221;. Players open a page and press &#8220;Start&#8221;, as soon as both players enter the room (there could be multiple rooms), the server starts showing letter sequences on the screen. The first player to type the sequence correctly wins the round. There are 9 rounds in total.</p><p>Use WebSockets for client-server communication (in both directions) to minimize the latency.</p><p>...</p><h3><strong>Day 10. Dance in sync</strong></h3><p>Build a collaborative music listening application prototype. One user is a DJ (can pause/resume/seek audio), and others are listeners. Audio is synchronized for everyone&#8230;</p><p><em>&#8230; and so on.</em></p><p><strong>P.S.</strong>&nbsp;Please let me know if you would like to take part in such a challenge next year and share your ideas!</p><p></p>]]></content:encoded></item></channel></rss>