Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fastlane broadcasts #10

Merged
merged 2 commits into from
Feb 3, 2025
Merged

Fastlane broadcasts #10

merged 2 commits into from
Feb 3, 2025

Conversation

palkan
Copy link
Member

@palkan palkan commented Jan 8, 2025

Context

Action Cable decodes and re-encodes every broadcasted message for every client which is unnecessary in most cases. This PR provides a fastlane_broadcasts configuration option to skip double encoding and transmit broadcast messages as is to clients not using custom stream coders or user-defined callbacks.

This is a continuation of the previous work: rails/rails#26999

Benchmarks

The cost of excess encoding heavily depends on the broadcasting payload size and nature. We consider three examples: a small JSON, a larger JSON, and a Turbo Stream "append" action.

Here are the results:

$ be ruby --yjit  benchmarks/broadcasting.rb

Running benchmark with N=10, M=100, adapter=async, fastlane_broadcasts_enabled=false, worker_pool_size=4

ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +PRISM [aarch64-linux]
Warming up --------------------------------------
small json (19 Bytes)
                        10.000 i/100ms
large json (80.5 KB)     1.000 i/100ms
turbo stream (2.95 KB)
                         1.000 i/100ms
Calculating -------------------------------------
small json (19 Bytes)
                        101.991 (±19.6%) i/s    (9.80 ms/i) -    980.000 in  10.053077s
large json (80.5 KB)      0.557 (± 0.0%) i/s     (1.80 s/i) -      6.000 in  10.786842s
turbo stream (2.95 KB)
                         16.618 (±24.1%) i/s   (60.18 ms/i) -    156.000 in  10.068446s
$ FASTLANE_BROADCASTS=1 be ruby --yjit  benchmarks/broadcasting.rb

Running benchmark with N=10, M=100, adapter=async, fastlane_broadcasts_enabled=true, worker_pool_size=4

ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +PRISM [aarch64-linux]
Warming up --------------------------------------
small json (19 Bytes)
                        38.000 i/100ms
large json (80.5 KB)     1.000 i/100ms
turbo stream (2.95 KB)
                         9.000 i/100ms
Calculating -------------------------------------
small json (19 Bytes)
                        327.354 (±25.0%) i/s    (3.05 ms/i) -      3.116k in  10.076621s
large json (80.5 KB)      3.826 (± 0.0%) i/s  (261.36 ms/i) -     38.000 in  10.019392s
turbo stream (2.95 KB)
                         85.029 (±31.8%) i/s   (11.76 ms/i) -    765.000 in  10.078424s

So, for small JSON payloads the fastlane version is ~3x faster, for larger JSON — ~7x faster, for HTML/Hotwire payloads — ~5x faster.

Here are Vernier profile screenshots:

  • Fastlane implementation:
image
  • Current implementation:
image

Integration benchmarks

These are the results of websocket-bench and k6 benchmarks from actioncable-next-playground:

  • websocket-bench:
Clients Baseline 95p RTT Fastlane 95p RTT AnyCable 95p RTT
200 91ms 31ms 91ms
400 124ms 43ms 85ms
600 172ms 59ms 108ms
800 204ms 80ms 123ms
1000 305ms 111ms 143ms
1200 291ms 133ms 191ms
1400 511ms 149ms 187ms
1600 569ms 172ms 182ms
1800 494ms 253ms 225ms
2000 619ms 327ms 208ms
  • k6 benchmark.js:
Scenario broadcast_duration p(95) rtt p(95)
Baseline 68ms 50ms
Fastlane 21ms 20ms
AnyCable 21ms 18ms

@palkan palkan force-pushed the feat/fastlane-broadcasts branch from df574ba to 7679c8b Compare January 8, 2025 01:05
@palkan palkan force-pushed the feat/fastlane-broadcasts branch from 7679c8b to 10e1a80 Compare January 8, 2025 15:07
@palkan palkan force-pushed the feat/fastlane-broadcasts branch from 10e1a80 to 44db017 Compare February 3, 2025 18:08
Rails 7 fails without it being explicitly loaded
@palkan palkan force-pushed the feat/fastlane-broadcasts branch from c73a9d7 to 0df716b Compare February 3, 2025 19:33
@palkan palkan merged commit 6f2aab5 into main Feb 3, 2025
10 checks passed
@palkan palkan deleted the feat/fastlane-broadcasts branch February 3, 2025 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant