Math Challenge
Mais

Arquitetura: o que roda, e como conferir

O Math Challenge roda inteiramente sobre a Cloudflare. Esta página separa o que já está rodando do que só está projetado, e dá o comando que comprova cada afirmação.

Última conferência contra a produção:

O que está rodando hoje

Todo o resto do inventário está projetado e não criado. Está listado mais abaixo, nome por nome, porque uma página que só mostra as peças que existem é um folheto.

HTTP/3, QUIC e 0-RTT

O HTTP/3 sobre QUIC está ligado na zona, e a retomada 0-RTT também, que permite a quem volta enviar a primeira requisição sem pagar um novo aperto de mão. Nenhuma das duas é afirmada a partir de uma página de documentação: as duas linhas abaixo foram lidas direto da produção, pela mesma conferência que roda depois de cada implantação. Uma chave que alguém desliga num painel não deixa rastro no repositório: o código não perceberia.

Lido da produção na data acima:

alt-svc: h3=":443"; ma=86400
TLS 1.3 · Max Early Data: 14336

O que isso não resolve: o HTTP/3 acelera o transporte, não o trabalho. Um pacote pesado de JavaScript trava a thread principal sobre QUIC exatamente como sobre TCP. Por isso o orçamento de peso mais abaixo importa mais do que o protocolo.

RPC nativo entre Workers

Os dois Workers conversam por um service binding, com chamadas de métodos tipados em vez de requisições HTTP. A Cloudflare descreve o que isso custa:

When you use Service Bindings, there is zero overhead or added latency. By default, both Workers run on the same thread of the same Cloudflare server.

RPC to another Worker (over a Service Binding) usually does not even cross a network. In fact, the other Worker usually runs in the very same thread as the caller, reducing latency to zero.

Cloudflare, documentação dos Service Bindings e anúncio do RPC nativo de JavaScript

Um RPC que não cruza a rede não pode ser superado por um que cruza, por mais eficiente que seja sua serialização. O caminho completo — primeiro Worker, segundo Worker, D1 — responde num endpoint público de saúde, então dá para conferir em vez de acreditar.

Por que não gRPC

O gRPC foi pedido pelo nome. A pesquisa o descartou por três fatos independentes, cada um suficiente sozinho:

  1. O Workers não consegue fazer chamadas gRPC de saída. O runtime não tem streaming bidirecional de HTTP/2, e há uma issue aberta no repositório do próprio runtime da Cloudflare acompanhando isso.
  2. O navegador também não fala gRPC. O cliente web implementa outro protocolo, cai para HTTP/1.1 — o que cancela parte das vantagens — e não suporta nem streaming de cliente nem chamadas bidirecionais.
  3. Os trailers de HTTP, de que o gRPC precisa para carregar o status, têm suporte limitado no proxy de borda da Cloudflare. Quem documentou isso foi a própria Cloudflare.

O que sobrou não é prêmio de consolação. Adotar gRPC aqui teria sido adotar a geração anterior com mais trabalho e menos resultado. O pedido e a evidência que o derrubou estão os dois no registro público de decisões: é para isso que ele serve.

Zero requisições a terceiros

Sem CDN de fontes, sem script de analytics, sem quadro incorporado, sem folha de estilo externa. Nenhuma requisição sai para um servidor que não seja nosso. Isso é conferido contra o HTML que a produção realmente serve, não contra as nossas intenções.

A Raleway é hospedada por nós como fonte variável, em dois arquivos: latin e latin-ext. O segundo não é opcional: sem ele, o ñ, o ç, o ã, o õ e o ü de cinco dos nossos locales caem para outra tipografia, justamente nos caracteres que os tornam aqueles locales. E a razão que pesa mais do que o desempenho: carregar uma fonte de um terceiro entrega a esse terceiro o endereço e a assinatura de navegador de cada visitante, nas páginas públicas de um produto para crianças.

A inferência roda dentro da rede

Os 23 auditores adversariais já rodam sobre o Workers AI, e o tutor vai para lá também: a inferência fica na Cloudflare em vez de ir para uma API externa. A chamada acontece dentro do Worker, sem viagem externa, e o aparelho de referência é um celular Android de entrada em dados móveis lentos, onde a latência custa tanto quanto o preço.

O que isso abre mão está escrito em vez de maquiado. O modo JSON do Workers AI é de melhor esforço, então a validação de esquema é conosco. Um veredicto que não valida conta como auditor falho, nunca como auditor limpo: o modo de falha barato é rodar de novo, e o caro é uma violação que ninguém viu.

As tentativas nunca vão para o D1

O D1 tem teto de 10 GB por banco de dados. Uma linha por tentativa chegaria nessa parede por erro de projeto e não por crescimento: o primeiro limite duro desta arquitetura se alcança errando, não dando certo. As tentativas cruas vão para o Analytics Engine; o D1 fica com as contas, os metadados de conteúdo e os agregados. Um auditor determinístico bloqueia o commit que esquecer disso.

Nós mesmos medimos, e nunca uma criança

O desempenho de campo quem mede somos nós e nunca um terceiro: um script embutido de cerca de 600 bytes que reporta a um endpoint nosso, que grava no Analytics Engine — nunca no D1 e nunca num serviço de fora. Nada do que ele envia identifica uma pessoa, e ele nunca é carregado na tela de uma criança: o endpoint também recusa essas faixas, de modo que as duas pontas falham fechadas. Um auditor guarda o código; a conferência em produção guarda a outra metade, porque a plataforma pode injetar um beacon próprio no nível da zona e isso não deixa arquivo nenhum para inspecionar.

Quanto pesam as páginas

Página mais pesada: 9,5 KB compactados com gzip, que é como elas viajam. Todo o JavaScript de cliente do site: 2,6 KB. Todo o CSS: 1,5 KB. O orçamento que bloqueia um commit é de 12 KB por página e 60 KB para todo o JavaScript de cliente somado.

Medido na data acima. Rode você mesmo o auditor e recebe o número em vez da nossa palavra.

O orçamento de desempenho, e o que ainda não afirmamos

O orçamento é INP abaixo de 150 ms, LCP abaixo de 2,5 s e CLS abaixo de 0,1. 150 e não os 200 de praxe, porque este é um jogo de alta frequência de interação: uma criança toca muitas vezes por sessão e cada toque é medido. É exatamente o perfil em que o INP quebra.

Dito sem enfeite: isso são orçamentos, não resultados. Nenhuma medição de campo durou o suficiente para que o auditor que faz valer os limiares tenha algo a fazer valer. Até lá, esta página não afirma nenhum resultado de desempenho.

A frota de auditores

8 auditores determinísticos rodam a cada commit, em milissegundos, e bloqueiam. 23 auditores adversariais com modelos de linguagem rodam antes de abrir um pull request, instruídos a encontrar a violação e não a aprovar. Ao todo são 39 planejados; 8 ainda esperam a fase que os habilita, e aparecem como pendentes em vez de sumirem em silêncio.

Duas regras os fazem servir em vez de atrapalhar. Todo auditor precisa citar a decisão ou o documento de pesquisa que faz valer: um que não consiga apontar um identificador real está opinando, e o veredicto dele não bloqueia. E anular um auditor exige escrever por quê, num arquivo commitado junto com a mudança que precisou da anulação.

O que ainda não existe

O inventário é escrito antes de os objetos existirem, para que quem criar um escreva sua linha no registro no mesmo pull request. Um recurso criado e não documentado é um recurso que ninguém vai conseguir apagar daqui a um ano. Isto está projetado e não criado:

Quem opera isto, e quem fornece

A Ignia opera a infraestrutura. Cada objeto que esta página nomeia mora numa conta da Cloudflare que a Ignia opera — operar contas da Cloudflare, para os próprios produtos e para clientes, faz parte do que a Ignia faz. O Math Challenge é um projeto da Ignia, patrocinado pela Ignia.

A Cloudflare fornece a plataforma. Workers, D1, KV, R2, Analytics Engine e a rede em que eles rodam são produtos da Cloudflare, operados pela Cloudflare. A Ignia opera; a Cloudflare fornece. Dois verbos, duas empresas, separados de propósito — e o motivo de separá-los é o mesmo em que esta página inteira se apoia: quem lê uma página de arquitetura é quem confere.

Uma dessas duas metades cabe numa consulta pública de DNS. Lida na data acima:

dig +short NS math.kilowatto.com
alberto.ns.cloudflare.com.
colette.ns.cloudflare.com.

A outra metade não dá para consultar em lugar nenhum, e a gente diz isso. Que este domínio é servido pela Cloudflare, qualquer um confirma. Que a Ignia opera a conta é uma afirmação nossa: não existe registro público onde conferir. Dizer assim vale mais do que enfeitar, porque basta uma única afirmação que não dá para conferir para o leitor parar de conferir as outras.

O que esta página não afirma, de propósito: que a Ignia seja parceira da Cloudflare. Não citamos nenhum nível de parceria nem exibimos selo algum, porque não há diretório público onde você pudesse verificar isso. Numa página cuja promessa inteira é “e é assim que se confere”, uma afirmação que não se pode conferir custa mais do que vale.

A Ignia, nas palavras dela: ignia.cloud

Como conferir qualquer uma dessas coisas

o anúncio de HTTP/3 nos cabeçalhos de resposta
curl -sI https://math.kilowatto.com/en/ | grep alt-svc
0-RTT: o ticket de sessão do TLS 1.3 e sua permissão de dados antecipados
openssl s_client -connect math.kilowatto.com:443 -tls1_3 -sess_out s.pem
openssl sess_id -in s.pem -text | grep "Max Early Data"
o caminho de RPC: primeiro Worker, segundo Worker, D1
curl -s https://math.kilowatto.com/api/health
os pesos citados acima, a partir do repositório
node audits/bundle-budget.mjs

Fontes

  1. About Service bindings — Cloudflare Workers docs
  2. We've added JavaScript-native RPC to Cloudflare Workers
  3. Support HTTP/2 bidirectional streaming (gRPC) in Workers/Durable Objects — cloudflare/workerd issue #6455
  4. gRPC Web (PROTOCOL-WEB) — gRPC core documentation
  5. Road to gRPC — Cloudflare blog
  6. HTTP/3 (with QUIC) — Cloudflare Speed docs
  7. D1 Platform limits — Cloudflare docs
  8. JSON Mode — Cloudflare Workers AI docs

O Math Challenge é um projeto da Ignia, e roda sobre a Cloudflare. São duas afirmações e ficam separadas de propósito: dizer que a Ignia fornece a infraestrutura seria desmentido por uma única consulta de DNS, e quem lê uma página de arquitetura é exatamente quem faria essa consulta. ignia.cloud