GPU streaming platform (Parsec-category) — cloud gaming + remote GPU workstation
Proposta de arquitetura para um componente Koder na categoria do Parsec: acesso remoto de baixa latência à GPU/desktop de máquinas no data center, servindo (a) cloud gaming (jogos-como-serviço) e (b) workstation GPU remota (render/IA). Frame o pipeline capture→encode(kodec)→transport(WebRTC/relay) →decode→input-return, o orçamento de latência, e a decisão build-vs-adopt sob o gate self-hosted-first. Decisões owner-gated (nome, placement L1/L2, build-vs-adopt) ficam DEFERIDAS à ratificação — este é um draft.
Status: RATIFICADO (2026-06-04, owner via /k-go). Origem: pedido do owner (áudio 2026-06-04,
~/Downloads/whatsapp/transcricoes.txtitem 01) + scoping#164.
0. Ratificação (2026-06-04)
As três decisões antes marcadas [OWNER] ficam ratificadas:
- Nome: Koder Beam (
Beam· slugkoder-beam· client CLIkbeam·daemon
beamd). Registrado emregistries/component-names.md. Cobre os dois perfis (cloud gaming + workstation GPU remota) sem viés gaming. - Placement: um único sector produto
products/horizontal/beam(RFC-006:
backend/= control-plane/orquestração de sessão GPU + agente no host + signaling;app/= clients desktopwebmobile/TV; encode reusaengines/kodec, NAT viainfra/net/relay). Obackend/expõe a API que o Arcade (#092) consome — não há sector separado emservices/media(evita split cross-domínio + colisão de slug; espelha o padrão Talk = product +engine/). - Build-vs-adopt: A→B. Adotar Sunshine (host) + Moonlight
(protocolo) como shadow-active interim (PoC/MVP rápido), com nativo
engines/kodec(NVENC/AV1) + WebRTC como alvo de flip, gated em paridade kodec (gate self-hosted G1/G2). O[self_hosted]block doproducts/horizontal/beam/koder.tomlregistra o par quando o módulo for scaffolded (aregistries/self-hosted-pairs.mdé regenerada de lá, não editada à mão).
Próximo passo de implementação: scaffold via /k-new-product + backend/`app` + abrir backlog (PoC de latência primeiro). Bloqueador de produção permanece o pool de GPU (§7), alinhado ao Arcade Onda 4.
1. Problema
Não há na Koder Stack um componente que faça acesso remoto de baixa latência à GPU de uma máquina no data center — o usuário joga / usa apps GPU-pesados sem ter placa de vídeo local; o frame é renderizado no servidor, codificado em hardware e transmitido; o input volta. É a categoria do Parsec, Moonlight/ Sunshine, GeForce NOW, NICE DCV, Unreal Pixel Streaming.
O mais próximo hoje — Koder Grid (products/dev/grid) — é client de protocolo (SSHRDPVNC) pra operador; categoria diferente (sem encoder GPU server-side nem orçamento de latência <100 ms). O Arcade (#092) cita "cloud streaming, modelo GeForce NOW" como feature deferida pra Onda 4, sem motor. Este RFC propõe o motor.
2. Goals / Non-goals
Goals
- G1. Render server-side com encode em hardware GPU (NVENC/AV1) e
transporte de baixa latência até o client.
- G2. Input return (tecladomousegamepad/touch) com RTT mínimo.
- G3. Dois perfis de uso: cloud gaming e workstation GPU remota.
- G4. Multi-tenant por construção; observável; always-on.
- G5. Clients nas surfaces Koder (desktopwebmobile/TV).
Non-goals
- Substituir o Grid (remote desktop por protocolo segue caso de uso próprio).
- Loja de jogos / billing — isso é o Arcade (
#092); este é a plataformaque ele consome.
- Provisionar o pool de GPU (infra separada; ver §7 dependências).
3. Arquitetura proposta (pipeline)
[GPU host no DC] [client Koder]
app/jogo → framebuffer
→ capture (DRM/KMS, NvFBC, wlr-screencopy)
→ encode H.264/HEVC/AV1 em hardware ── engines/kodec (NVENC) ──┐
→ packetize (RTP/WebRTC) │
transport (WebRTC SRTP + DataChannel) ────┼──→ decode (kodec/HW)
NAT traversal: infra/net/relay (TURN) │ → render
input events ◄──────────────── DataChannel (input) ◄────────┘ ← capture input- Capture: caminho headless GPU — alinhar com o que já funciona no seat
T4 (
gpu-seat-mutter-nvidia-wall-wlr-screencopy-works: mutter headless não liga na GPU; wl-screencopycage funciona). NvFBCDRM-KMS a avaliar. - Encode:
engines/kodecé o ponto de reuso natural (NVENC H.264/HEVC,AV1 quando pronto). Mapeia o gate self-hosted da kodec.
- Transport: WebRTC (SRTP media + DataChannel pra input) — funciona em
todas as surfaces (web nativamente), tem congestion control. Signaling via
infra/net/jet; TURNNAT via `infranet/relay`. - Orçamento de latência (meta glass-to-glass <100 ms LAN-region):
capture ≤5 ms · encode ≤8 ms (HW) · network 1-way (regional) ≤25 ms · jitter/buffer ≤10 ms · decode ≤8 ms · present ≤16 ms. Exige region-affinity (cliente roteado pra GPU pop mais próxima).
4. Build vs adopt — RATIFICADO A→B (ver §0), gate self-hosted-first
Duas vias (registrar a escolha em registries/self-hosted-pairs.md):
- A. Adotar FOSS (shadow-active): Sunshine (host) + protocolo
Moonlight/NVIDIA GameStream; clients Koder falam Moonlight. Mais rápido pra PoC; débito de soberania (não-nativo) — aceitável como interim sob o gate.
- B. Koder nativo: pipeline próprio sobre
engines/kodec(encoder) +WebRTC. Soberano, integra surfacesauthobservability Koder, mas é o caminho mais longo.
Recomendação do draft (não-ratificada): começar A pra PoC de latência (de-risca rápido no seat T4), com B como alvo de flip assim que a kodec tiver NVENC + AV1 em paridade. Decisão final = owner (Princípio #2 + self-hosted gate G1/G2).
5. Placement & naming — RATIFICADO (ver §0)
- Nome: Koder Beam (
koder-beam,kbeam/beamd) — registrado emcomponent-names.md. - Placement:
products/horizontal/beam(sector único;backend/expõe aAPI consumida pelo Arcade;
app/= clients). A alternativa de splitservices/media+products/horizontalfoi descartada na ratificação (split cross-domínio desnecessário; padrão Talk product+engine cobre).
6. Dimensões transversais
- Multi-tenancy (
multi-tenant-by-default.kmd): sessão GPU, fila efaturamento por tenant; isolamento por sessão (container/cgroup + VRAM).
- Always-on (
always-on.kmd): sessões são efêmeras mas o control-plane(scheduler de GPU, signaling) é always-on; rollout sem derrubar sessões.
- Observability (
observability-first.kmd): RED no signaling + métricasde QoE (latência glass-to-glass, frame drops, bitrate, RTT de input), correlacionadas por
trace_idde sessão; cardinalidade com budget.
7. Dependências / pré-requisitos
- Pool de GPU no DC — hoje só 1 Tesla T4 de teste (
s.khost1). Oprovisionamento de pool é o gargalo real e alinha com "Koder GPU infra" do Arcade
#092(Onda 4). Bloqueador de produção. engines/kodeccom NVENC exposto (caminho A não precisa; B precisa).infra/net/relayTURN operacional p/ NAT traversal.
8. Rollout proposto (faseado)
- PoC latência no seat T4: Sunshine host + kodec-NVENC, medir
glass-to-glass + RTT input num client Moonlight/WebRTC. (Antes de comprometer A vs B.)
- Owner ratifica nome + placement + build-vs-adopt →
component-names.md+self-hosted-pairs.md; criar o(s) Sector(s) e abrir backlog do módulo. - MVP single-region (control-plane + 1 GPU pool) → 1 surface client.
- Multi-region + region-affinity; integração Arcade (Onda 4); billing
royalty-per-minute (sub-spec do
#092).
8a. Evidência empírica — encode-leg PoC (2026-06-04, BEAM-001)
Spike no seat T4 (kruze-gpu-seat, LXC capabilities=all):
- NVENC presente no LXC; H.264 1080p60 @ 220 fps / 3.66×, *EVC @ 225 fps
/ 3.75× (gargalo = gerador testsrc em CPU, encoder folgado) → o orçamento de encode ≤8 ms (§3) é viável*no T4 com margem.
- AV1 NVENC FALHA no T4 (Turing sem AV1 encode; precisa Ada/RTX40+).
- Glass-to-glass end-to-end + input RTT continuam por medir (PoC maior,
gated no pool de GPU).
9. Open questions
- Perfil MVP: cloud gaming primeiro ou workstation-GPU genérica? (áudio cita
os dois).
- Codec alvo do MVP: H.264/HEVC (resolvido p/ T4 — *V1 indisponível no
T4* requer Ada/RTX40+; reavaliar quando o pool tiver GPU mais nova).
- Modelo de isolamento de sessão (container c/ GPU passthrough vs MIG no T4+).
- Anti-cheat (se gaming competitivo) — fora do MVP, alinhar com Arcade Onda 4-5.
10. Referências
#164 (scoping), #092 (Arcadecloud-streaming), `engineskodec,
productsdevgrid (categoria adjacente), infranetrelay,
kruze-gpu-seat.md`, policies citadas no frontmatter.