Add Rails Action Cable comparison page#58
Open
irinanazarova wants to merge 10 commits into
Open
Conversation
New /compare/rails-actioncable page comparing four Rails WebSocket adapters on identical hardware: Action Cable (Puma+Redis), Solid Cable (Puma+DB), AsyncCable (Falcon), and AnyCable (out-of-process Go gateway). All four speak the Action Cable API, so channels and Turbo Streams are unchanged. Measured across four rubrics with a sharded load fleet: - Latency: AnyCable fastest at every scale (7ms p50 at 5K) - Jitter delivery: AnyCable 99.9% vs ~78% for the at-most-once in-process trio - Deploy survival: AnyCable 0 dropped vs all-drop for in-process adapters - Capacity: all hold 10K at 100%; pushed to failure, Puma adapters wall ~52K (fd limit), Falcon ~97K (memory), AnyCable held 600K with 0 failures Reuses the compare.scss / compare-spine.scss system and the document skeleton from the nodejs-websocket page. Includes FAQPage + TechArticle JSON-LD.
|
|
Applied feedback from reviews channeling DHH, David Cramer, Matt Biilmann,
Guillermo Rauch, a scaling-Rails-shop CTO, and LLM/answer-engine retrieval:
- Lead the callout with the architectural choice (in-process vs separate
Go gateway) and the undeniable wins (jitter, deploy), not latency; state
the two precise causes (process for deploys/capacity, protocol for delivery)
- Add a "Should you switch?" decision box with triggers + one-line rollback
- Add a "How it was measured" methodology disclosure (box, driver locality,
runtimes, per-cell counts, single-pass honesty, raw-results link)
- De-FUD "What this breaks": acknowledge the refetch-on-reconnect workaround,
drop "nobody can recover"; label the jitter run as a deliberate stress test;
soften deploy "stranded" to "still reconnecting when we stopped watching"
- Present 600K as a floor (ran out of load fleet, not server); drop the
~700K extrapolation
- Note latency is where the four sit closest (7 vs 13 ms barely felt)
- Hero card labels: outcome phrases instead of questions; deploy values
carry the count ("all 5,000"); jitter p99 column made non-numeric (n/a)
- New FAQs: which adapter to choose, what is AnyCable, Action Cable
connection limit, do I need Go, does 99.9% need a client swap
- Sharpen the architecture thesis (subtitle, section heading, figcaption)
- Add keywords + a machine-readable Dataset JSON-LD; mirror new FAQs in
FAQPage JSON-LD
Report how long the in-process adapters stay dropped before reconnecting (~7.5 to 8 s, ~96% recovered) instead of only the reconnect percentage. Reorder the deploy table to Dropped / Down for / Reconnected, redefine the footnote, and add downtime to the Dataset JSON-LD.
New hand-authored /compare landing page that hosts every comparison, reusing the existing compare-hub-* CSS component set (added earlier, previously unused). Hero, then three stack cards (Node.js and Rails live, Laravel/PaaS coming soon), a three-topology landscape map with AnyCable tagged "You are here", and a CTA. Adds CollectionPage + ItemList JSON-LD. Point the footer "Comparisons" link at /compare instead of the Node.js page now that there is a hub.
Add the /compare hub and the new Rails benchmark page to llms.txt and llms-full.txt: a benchmark-backed "when to use AnyCable instead of Action Cable / Solid Cable / AsyncCable" section, a Rails article entry and (in the full file) a complete Rails methodology + results section with latency, jitter, capacity, and deploy tables. Link the hub and the Rails page in both Links sections.
- Capacity: the 1M idle figures were stale (OSS 993,994 / Pro 999,954). Correct to the published compare-page numbers: OSS 821,877 @ 28.3 GB (~34 KB/conn), Pro 822,037 @ 14.8 GB (~18 KB/conn), uWS 1,018,366 @ 5.45 GB. Fixes an internal contradiction where llms.txt disagreed with itself. Recompute Pro efficiency (~1.9x, was 1.7x). - Avalanche: replace the single-scale Socket.io table with the page's scale sweep (5K-25K), adding the uWS data point. - Pricing: Managed is free for early users (up to 2,000 connections), not "$29/month" (no such price on the site). Pro is unlimited instances and connections. - Action Cable "~500 connections" claim corrected to the benchmarked in-process ceiling (~52,000) and reframed around deploy drops and at-most-once. - Customer figures aligned to the site / web sources: CompanyCam $452M raised / $2B valuation (was $30M+), Qualified acquired by Salesforce (was $95M raised), Circle $33M, Fullscript $240M+. Drop Jane's "$100M+ raised" (that figure is revenue/secondary, not capital).
Match the gem's own naming: the README heading and Ruby constant are Async::Cable (the gem package stays async-cable). Update the Rails comparison page (title, hero, tables, prose, FAQ, JSON-LD) and the Rails sections of both llms files.
Surface per-connection idle RAM for all four adapters in the "How far does it scale?" table (~45 KB Action Cable, ~50 KB Solid Cable, ~290 KB Async::Cable, ~47 KB AnyCable), computed as peak RSS / connections held. Flag Falcon's ~290 KB as the outlier that makes it memory-bound. Move the figure out of the prose footnote to avoid duplication.
…ped" "All 5,000 dropped" is a given for any in-process server, so it earned a test we didn't need. Drop that column and lead with the metrics that actually inform: blackout duration (Down for) and the share that reconnects within the window (Recovered, with the residual still-out count). Every in-process adapter still dropped all 5,000; that fact moves to the footnote as context. Reframe the hero card to downtime (7.5-8 s vs 0 s) and update the headline and Dataset JSON-LD to match.
The "Down for" figure is recoveryTimeMs from the avalanche runner, defined as time from redeploy until 95% of clients are back. Say so explicitly in the column header, headline, footnote, hero card, and Dataset JSON-LD instead of the vaguer "blackout before reconnect".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New
/compare/rails-actioncablepage: Action Cable vs Solid Cable vs AsyncCable vs AnyCable, the Rails counterpart to the existing/compare/nodejs-websocketpage.What it compares
Four Rails WebSocket adapters running the same Rails 8.1 app on identical Railway hardware, in one shared-tenant window:
All four speak the Action Cable API, so channels and Turbo Streams are unchanged. The only thing that varies is what runs the WebSockets.
Findings (sharded load fleet)
actioncable-v1-jsonhas no resume; AnyCable'sactioncable-v1-ext-jsonreplays per-stream history)Implementation
compare.scss/compare-spine.scsssystem and the document skeleton from the nodejs-websocket pageBenchmark methodology and raw data live in the separate bench repo (nodejs-websocket-bench).