Live media · benchmark report

Live media measurements, methods and results.

The measured origin, relay and browser paths behind the ForgeSworn media stack. Compare the exact workloads, source versions and raw results before sizing your own deployment.

Watch the licensed broadcast and compare your own native servers, with browser playback, process readings and downloadable results in one place.

Explore the media stackOrigin benchmarksRelay benchmarks and interoperability

Native ARM64 binaries on one M4 Max, 23 October 2026. The server and TURN trials are separate workloads. These are measured resource gains; deployment capacity and operating costs need their own measurements.

A smaller origin for the same viewer workload

Sapflow takes H.264 and AAC over SRT or RTMP, packages Low-Latency HLS and records fragmented MP4. Keeping that job small gives an operator a concrete reason to evaluate it: the 16-worker own HTTP loop used 79% less CPU and 90% less process RSS than MediaMTX in this test.

750 simulated viewers, three runs each. Median server CPU, peak process RSS and per-run playlist p99. CPU is a percentage of one core.
ConfigurationCPUPeak RSSPlaylist p99
MediaMTX 1.21.2167.8%276.7 MiB33.2 ms
Sapflow, default Hyper60.9%250.2 MiB29.3 ms
Sapflow, own loop, 16 workers35.0%26.4 MiB28.0 ms
Sapflow, own loop, 1 worker20.3%25.0 MiB33.7 ms

All twelve trials completed with zero errors across 7,055,374 requests. The 79% CPU and 90% RSS comparison uses the 16-worker own loop; Hyper remains the default and used 64% less CPU than MediaMTX here. One own-loop worker reduced CPU further, with a higher playlist p99 and median part fan-out delay than sixteen.

The HTTP implementation is a useful tuning target in its own right. Against Sapflow on Hyper, the 16-worker own loop cut measured CPU by 43% and peak RSS by 89%. The ingest and packaging paths were shared between those configurations.

Test conditions, source versions and raw results

Generated 720p30 H.264/AAC over RTMP, native ARM64 release binaries, loopback HTTP/1.1, recording off and no TLS. Server, encoder and load generator shared the M4 Max with existing host workloads. Each trial had warm-up, a ten-second viewer ramp and a sixty-second full-load target.

The measured Sapflow development snapshot is 2d20835ef246740ab42ca810df7c51fd43bf9ff6, ahead of the published 0.1.0 crates. These figures don't requalify another source revision. The load generator includes ramp traffic in its counters and percentiles. It fetches overlapping parts and segments and doesn't fetch MediaMTX's separate audio rendition; its byte count isn't unique-media throughput. Peak RSS excludes kernel memory.

Full dated method and ranges · Every scalar run and binary hash

The broadcast path

  1. Encode

    A native app or an existing encoder produces compressed H.264 video and AAC audio.

  2. Publish

    SRT carries media over UDP with recovery. RTMP provides a publishing path for existing tools.

  3. Package

    Sapflow writes HLS parts, segments and playlists, with optional MP4 recording.

  4. Watch

    A player fetches HLS over HTTPS. A reverse proxy supplies TLS and HTTP/2.

The native adapters own the camera, microphone, hardware codecs and sockets. The shared Rust libraries process compressed media. Sapflow doesn't transcode a stream or create an adaptive bitrate ladder.

Why separate libraries?

An application may need a publisher without a server, or a packager without a network runtime. Separating protocol state from sockets lets the same code run under a server event loop or a native platform adapter.

The libraries share a repository. Each has a specific responsibility.
ComponentWhat it suppliesWhen you need it
sapflow-srtRuntime-free SRT listener/receiver and caller/sender state, including optional AES-CTR encryption.A Rust SRT implementation you can drive from your own sockets and clock. Live mode is the supported scope; file transfer, bonding and full libsrt parity aren't promised.
sapflow-rtmpRTMP publishing client and server-side protocol state.Compatible publishing without embedding a C library or the whole media server. It doesn't provide an RTMP playback service.
sapflow-hlsFLV/MPEG-TS ingest, fragmented MP4, LL-HLS parts and playlist rules.Packaging H.264/AAC for HLS playback or reusing media handling in an application.
sapflow-coreShared media and stream types with no network or async runtime.The common vocabulary used by the protocol and packaging libraries.
sapflow-client and sapflow-ffiCompressed-sample validation, bounded queues, session policy and the Swift/Kotlin boundary.Native app development. These interfaces and native packages are still being qualified; they aren't a finished camera SDK.
Sapflow serverSocket adapters, HTTP serving, recording and application callbacks around those libraries.A small origin for the specific SRT/RTMP-to-HLS job.

RelaySwarm shares media. Spry connects peers.

RelaySwarm lets viewers exchange verified HLS media over WebRTC data channels, using application-selected Nostr relays for rendezvous. RelaySwarmKit provides the Swift implementation. The HTTP origin remains the fallback when peers can't provide media in time.

Some peers can't connect directly through their networks. Spry TURN is our small Rust STUN/TURN server for that relay role: UDP and TCP client connections, optional TLS, coturn-compatible shared-secret credentials and bounded resources. It can run separately from the media server.

RelaySwarm accepts ICE server configuration, where an operator can supply Spry or coturn. The relay still needs reachable addresses, credentials and bandwidth. Spry is optional for peer connectivity; ordinary Sapflow SRT/RTMP ingest and HLS playback don't require it.

More UDP and TLS delivery in the measured workloads

The published Spry 0.2.1 M4 Max binaries delivered 16–22% more UDP packets per second and 27–35% more TLS packets per second than the tested coturn configuration. TCP ranged from 1.2% behind to 8.5% ahead. The complete M4 matrix contains 108 runs and 53,075,648 checked forwarded packets, with no observed payload loss, reordering or corruption.

Native ARM64, 128 allocations and 1,200-byte payloads. Medians of three runs per server. The final column spans all six allocation/payload cells per transport.
Client transportSpry packets/scoturn 4.18.0 packets/sSpry difference across six cells
UDP271,644223,168+16.2% to +22.2%
TCP302,240305,790−1.2% to +8.5%
TLS264,697196,161+27.1% to +34.9%

These are configuration-specific delivered rates. Spry's source and 0.2.1 prerelease are public, under MIT, © 2026 TheCryptoDonkey. The full method and all 108 M4 samples identify the source, executables and resource counters.

Platform choice matters. Spry was slower in five of six UDP workloads on the constrained Linux ARM64 VM. At 128 allocations and 1,200-byte payloads it was 15.4% behind coturn over UDP, 46.8% ahead over TCP and 30.2% ahead over TLS. These VM results need a separate trial on an operator's Linux host.

RelaySwarm's desktop HLS composition remains under qualification. An earlier fixture shared one TURN credential across viewers and hit Spry's allocation quota. A corrected Spry 0.2.1 run with separate viewer credentials passed UDP at 81% in-time delivery. TCP and TLS carried verified media without ICE errors but reached 27% and 37.8%, below the unchanged 50% gate. TLS also had no active selected path at the final sample and used an explicit test-certificate bypass. The remaining timing failure has not been isolated to either implementation. HTTP playback and tampering rejection passed. The composition results and fixture correction are pinned to the public main-branch update checked on 24 October 2026 and remain separate from the standalone relay benchmark. The scalar receipt retains the failed gates. Internet NAT and physical-phone acceptance remain open.

The actual KithMoot web client, through ordinary TURN settings

Spry 0.2.1 also passed a separate local browser qualification using the actual KithMoot web application. Two clients exchanged and decoded generated audio/video through forced UDP, TCP and TLS relay paths, with operator-generated short-lived credentials entered through the real Connections settings. No HTTP credential issuer or publisher-operated default was added, and the client made no /turn request. This qualifies the identified web source and executable on one machine; TLS used an explicit test-certificate bypass. Cross-network reachability, public certificate validation and physical GrapheneOS acceptance remain separate gates. Read the accepted path and limits and versioned browser receipt.

What changed, platform limits and all relay samples

Spry reserves packet headroom to avoid a second media-payload copy, uses bounded readiness slots and connected client-facing UDP sockets for authenticated, concrete-IPv4 allocations. Wildcard/IPv6 listeners use the portable path. Version 0.2.1 also caches writable-interest state: the event loop registers write readiness when output blocks and removes it after draining. A separate controlled before/after M4 experiment measured 5.8% higher Spry TCP delivery and 4.4% higher TLS delivery.

The primary M4 matrix covers 1, 16 and 128 allocations, 160- and 1,200-byte payloads and UDP/TCP/TLS, with an eight-packet window per load worker. It uses generic ARM64 release builds without PGO and coturn 4.18.0 with one relay event loop. Each throughput phase completes at least 200,000 round trips over at least two seconds. Existing workloads remained running. These closed-loop medians establish neither maximum WAN capacity nor statistical significance.

Process memory and kernel memory have separate budgets. The connected-UDP path holds an extra client-facing socket per allocation. TCP buffering can cost more process memory than coturn: the controlled 128-allocation experiment measured 12.21 MB versus 11.70 MB RSS over TCP. Linux socket counters include nonzero drops despite successful payload checks, so the results do not establish zero kernel drops.

M4 and Linux methods, results and unsuccessful trials · Release binary and source receipts · Controlled 27-run tuning experiment

The earlier UDP optimisation study remains available: 36 historical samples · three-way experiment · source and binary hashes · checksums. Its pre-v0.2.0 executable and 32-packet window differ from the published 0.2.1 matrix above.

Choose for the job you have

Feature trade-offs. These aren't claims that one implementation wins every workload.
DecisionForgeSworn optionAlternative and reason to choose it
Live media originSapflow keeps the SRT/RTMP, H.264/AAC, HLS and recording scope small.MediaMTX supports a much broader protocol and codec set, including RTSP, WebRTC and Media-over-QUIC, plus operational APIs.
SRT implementationsapflow-srt is Rust with runtime-free protocol state and a narrow live-media profile.libsrt is the established reference with a broader feature set. Sapflow compares against its executables as black boxes. This is not a claim of full compatibility.
RTMP implementationsapflow-rtmp can be embedded in a Rust server or native publishing core.gortmplib fits Go applications; nginx-rtmp-module fits an existing nginx deployment.
HLS packagingsapflow-hls supplies the Rust packager used by Sapflow.gohlslib provides the Go implementation used by MediaMTX. Language, supported tracks and playlist features affect the choice.
Peer-assisted HLSRelaySwarm uses Nostr rendezvous, signed media authorisation and origin fallback. Its protocol and field qualification are still developing.P2P Media Loader is an established player integration using WebTorrent-compatible tracker infrastructure.
STUN/TURN relaySpry is a small public MIT Rust relay with measured UDP gains and bounded resources. Its published 0.2.1 binaries have M4 and Linux measurements; RelaySwarm delivery-time qualification remains open.coturn has a broader deployment and administration feature set, including database integrations and metrics. Existing coturn configurations need an explicit compatibility review before migration.
Native broadcasterSapflow shares compressed-media and protocol logic between Swift and Kotlin adapters.HaishinKit and StreamPack cover native broadcasting in their respective ecosystems. No matched physical-device performance advantage is claimed here.

The detailed comparison names supported features and current gaps. The benchmark record keeps versions, conditions, results and limitations together.

Add storage and transfer when the application needs them

Move a recording

ForgeSworn Link provides a separate transfer protocol. It isn't an ingest protocol or a required Sapflow dependency. Broadcast-time recording transfer needs its own integration and contention measurements.

Store and recover files

Shelter Kit provides content-addressed storage and repair interfaces. Foregather can supply pairing or invitation flows. Neither belongs in a media callback or is required for basic HLS delivery.

What the measurements establish

The origin and relay comparisons establish resource savings in their documented workloads. They provide a reason to trial Sapflow and Spry on an operator's traffic and measure the resulting headroom.

Those results don't establish Linux capacity, internet latency, phone battery life or sustained hardware-codec performance. Server, load generator and encoder sharing a Mac also compete for resources. Read the conditions alongside the numbers before using them to size a deployment.

The native performance contract sets out copying, queueing and physical-device gates. New measurements belong with their exact source and binary versions.

Next measurements: Sapflow's runner now separates steady-state collection from its ramp and balances treatment order. Rerun 1/4/16 workers at 250 and 750 viewers on the current source revisions when the M4 is available. Then exercise TLS, recording and multiple publishers on a separate Linux host, and measure RelaySwarm with Spry across real networks, including origin fallback and relay bandwidth.

Public source, with the actual notices

The linked ForgeSworn source repositories are public and MIT-licensed. Sapflow's licence and Spry's licence name TheCryptoDonkey. Other projects retain their own copyright notices, and dependencies retain theirs. Sapflow's third-party notices list those separately.

Public source and a published package are separate things. The SRT, RTMP, HLS and core crates and server have initial 0.1.0 releases. Native consumer qualification and production readiness remain explicit in the project documentation.