Skip to content

Commit d81a90d

Browse files
kixelatedclaude
andauthored
On a boat blog post (#82)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b39a481 commit d81a90d

5 files changed

Lines changed: 192 additions & 0 deletions

File tree

public/blog/on-a-boat/boat.png

356 KB
Loading

public/blog/on-a-boat/fanout.png

189 KB
Loading

public/blog/on-a-boat/kraken.png

381 KB
Loading
172 KB
Loading

src/pages/blog/on-a-boat.mdx

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
layout: "@/layouts/global.astro"
3+
title: On a Boat
4+
author: kixelated
5+
description: I'm on a boat.
6+
cover: "/blog/on-a-boat/boat.png"
7+
date: 2026-02-26
8+
---
9+
10+
# On a Boat
11+
[Saronic](https://www.saronic.com/) posted a [blog](https://medium.com/saronic-technologies/the-ground-moves-building-on-early-open-source-without-getting-burned-ba2af78beb78) about how they've been using MoQ for years.
12+
Go read it.
13+
14+
I'm stoked because I can *finally* talk about nautical nonsense.
15+
16+
## Bandwidth Constrained
17+
Imagine this:
18+
19+
- You're on a boat, man.
20+
- You're going fast, man.
21+
- You've got 9 cameras and StarLink is expensive, man.
22+
23+
<figure>
24+
![boat](/blog/on-a-boat/boat.png)
25+
<figcaption>[obligatory](https://www.youtube.com/watch?v=R7yfISlGLNU)</figcaption>
26+
</figure>
27+
28+
It's not sustainable to constantly transmit a full HD stream from every camera.
29+
Even if you can afford it, ship happens.
30+
Your bandwidth will fluctuate and camera feeds will drop out.
31+
32+
Existing contribution protocols (ex. WebRTC, SRT, RTSP, RTMP) are push-based.
33+
A publisher, like a security camera on a boat, constantly transmits *everything* to a server.
34+
Not good when you're on a boat.
35+
36+
But **MoQ is pull-based**\*.
37+
We are the ugly duckling of the media publishing world.
38+
39+
\* Well technically, the IETF nerds added an (optional) `PUBLISH` message to [moq-transport](https://datatracker.ietf.org/doc/draft-ietf-moq-transport/), so it can do both.
40+
But I *strongly* discourage you from using it, and here's why:
41+
42+
## LIKE, COMMENT, SUBSCRIBE
43+
But first the basics.
44+
45+
A MoQ broadcast is split into live streams called "tracks".
46+
It's completely up to your application to decide how to split stuff into tracks.
47+
For example, [hang.live](https://hang.live) uses:
48+
- `1080p`
49+
- `360p`
50+
- `audio`
51+
- `captions`
52+
- `chat`
53+
- etc
54+
55+
Every MoQ viewer has to explicitly `SUBSCRIBE` to each track, otherwise it won't be transmitted.
56+
57+
This is fantastic because now tracks are optional.
58+
Window minimized? Codec unsupported? Screen too small? Don't `SUBSCRIBE 1080p`.
59+
60+
What if 100 viewers `SUBSCRIBE 1080p`?
61+
[moq-relay](https://doc.moq.dev/app/relay/) is the champ that merges them into a single *upstream* `SUBSCRIBE 1080p`.
62+
Your boat is safe from the flood and serves *at most* one copy of each track.
63+
64+
What if 100,000 viewers `SUBSCRIBE 1080p`?
65+
Run a [cluster](https://doc.moq.dev/app/relay/cluster) of relays.
66+
Sprinkle them around the world and suddenly you have a global CDN.
67+
68+
It's the exact same concept as HTTP CDNs, but for live streams.
69+
MoQ is being standardized specifically so you can use a [CDN like Cloudflare](/blog/first-cdn) to scale world-wide.
70+
Or you could self-host [moq-relay](https://doc.moq.dev/app/relay/) (like Saronic) and keep everything in your network.
71+
72+
73+
## Enter, Renditions
74+
**Mr Skeptic Strawman** says:
75+
> I have a single viewer, why should I care about mass fanout?
76+
77+
Well **Mr Skeptic Strawman**, let's talk about renditions.
78+
79+
In new reality land, you don't want a *human* viewer.
80+
You instead throw an AI model at that shit.
81+
The AI will subscribe to the 360p stream from every camera and try to detect anomalies.
82+
Like a kraken is attacking or something.
83+
84+
idk I don't sail.
85+
86+
By default, only the 360p stream for each camera is being transmitted.
87+
If AI detects a kraken on the starboard bow, then it subscribes to the 1080p stream.
88+
89+
<figure>
90+
![kraken](/blog/on-a-boat/kraken.png)
91+
<figcaption>Arr, there be a kraken on the starboard bow.</figcaption>
92+
</figure>
93+
94+
But what happens during congestion if we can't transmit everything?
95+
**Answer**: it's your choice buddy.
96+
97+
All MoQ subscriptions contain a priority, so they can cooperate while sharing a connection.
98+
- **Do you want the kraken cam?** Probably, set the priority to 10.
99+
- **Do you want to crash the boat?** Probably not, set the front-facing cameras to 5.
100+
- **Do you want audio?** Idk I don't sail, maybe set it to 15.
101+
102+
The QUIC library will transmit packets based on the specified priorities.
103+
In this example: audio, then the kraken, then front cameras, then anything else.
104+
This is all best-effort, so your sloppy-seconds might get queued/dropped if the bandwidth is too low.
105+
106+
**Something** has to be queued/dropped, but we do our best to make sure the most important stuff gets transmitted.
107+
Hopefully it's the kraken.
108+
109+
110+
## Backfill that Boat
111+
Another MoQ difference is that we don't drop frames, we prioritize/queue.
112+
113+
**Mr Skeptic Strawman** says:
114+
> huh?
115+
116+
So lets say the kraken is consuming our crew, and our available bandwidth.
117+
We get an alert that the kraken is attacking.
118+
119+
A human wants to see that shit in real-time and configures a maximum latency of 100ms.
120+
If a frame takes longer than that, then we skip ahead.
121+
We don't want a spinny boye getting in the way of the action.
122+
123+
But let's say there's also a VOD worker recording the footage for the post-mortem.
124+
It can tolerate higher delays, configuring a maximum latency of 30 seconds.
125+
126+
Normally, a WebRTC publisher would have dropped that frame after 100ms, but MoQ doesn't.
127+
We instead deprioritize it, sending newer frames instead but keeping old frames in RAM.
128+
129+
**We know the kraken will eventually be satiated**.
130+
Once we recover, we might have enough spare bandwidth to backfill the VOD before the 30s deadline.
131+
132+
The end result is a lossy live stream AND a pristine VOD.
133+
Just because one viewer wants real-time latency doesn't mean the rest of the world has to suffer.
134+
135+
Literally huge.
136+
137+
## Bonded Pairs
138+
What if you're near the coast?
139+
Can we use a cellular connection in addition to the satellite connection?
140+
141+
Why of course, rhetorical question.
142+
QUIC supports path migration, seamlessly switching between multiple paths (active-backup).
143+
You can switch from Wifi to cellular to satellite without severing the QUIC connection (unlike TCP).
144+
145+
There's also a [multi-path extension](https://datatracker.ietf.org/doc/draft-ietf-quic-multipath/) that can use multiple paths at the same time (active-active).
146+
If you want to give it a spin, the [iroh](https://iroh.computer/) folks just released their [Quinn fork](https://github.com/n0-computer/noq).
147+
It's gated [behind a feature flag](https://github.com/moq-dev/moq/blob/main/rs/moq-native/Cargo.toml) if you want to try it with MoQ.
148+
149+
<figure>
150+
![bonded pairs](/blog/on-a-boat/multipath.png)
151+
<figcaption>Like kittens, these pairs are bonded.</figcaption>
152+
</figure>
153+
154+
And that's only at the QUIC level.
155+
Another option is to establish multiple MoQ connections, advertising the broadcast as available on all of them.
156+
The viewer will automatically route subscriptions to the "best" connection.
157+
For example, via a P2P connection (via [iroh](https://iroh.computer/)) otherwise via CDN connection.
158+
159+
And remember, MoQ won't transmit a track until there's a `SUBSCRIBE` for it.
160+
You can establish multiple connections, possibly to different CDNs, and nothing will flow.
161+
The moment a viewer (on that CDN?) needs a track, then it will be transmitted.
162+
163+
Push-based protocols can't do this.
164+
**Pull-based is based.**
165+
166+
## The Wake not Taken
167+
You need pretty huge buoys to be an early adopter.
168+
Saronic has been using my [moq.dev](https://github.com/moq-dev/moq) libraries for maybe ~2 years now... even before I was a professional vagrant.
169+
170+
I want to thank them for their patience and support.
171+
They put up with bugs, overzealous renaming, and other shenanigans.
172+
They've got a pretty nice solution now and [are hiring](https://jobs.lever.co/saronic).
173+
174+
And there's a few other cant-be-named companies evaluating MoQ for *security purposes*.
175+
I can't say that was the plan... but it makes perfect sense.
176+
Hit me up if you want to chat about your use-case and how I can help.
177+
Even if I have to sign an NDA.
178+
179+
I'm just happy to see MoQ being used in the wild.
180+
[Dave Gullo](https://github.com/davegullo) earns a shoutout for doing just that with [ooda.video](https://ooda.video/).
181+
He's using the dope [MoQ OBS plugin](/blog/moqbs) we built in [Montevideo](/blog/monte-video) to do all of the kraken detection stuff.
182+
183+
## Conclusion
184+
MoQ is great for boats.
185+
And other vehicles.
186+
And stationary objects.
187+
188+
Want to learn more?
189+
I'm working on [more documentation](https://doc.moq.dev), including other non-boat [use-cases](https://doc.moq.dev/concept/use-case/).
190+
191+
Until next time sailor.
192+
![@kixelated](/blog/avatar.png)

0 commit comments

Comments
 (0)