Kino: o servidor web para Ruby 4.0 que usa Ractors para rodar em paralelo sem forks
Novo servidor Rack combina front-end em Rust com Ractors paralelos e promete usar todos os núcleos num único processo, mas ainda esbarra no Rails.

Um novo servidor web para Ruby↳Ruby3 conteúdosComo migrei meus testes automatizados de Java para Ruby… Será que fiz bem?Dev (Back & Front) · jun 2019Refatoração em RubyDev (Back & Front) · mai 20197 exemplos de linguagens de programação server-sideGestão Dev & TI · jun 2024Ver tudo em Dev (Back & Front) → chamado Kino apareceu no topo do Hacker News propondo resolver um problema antigo da linguagem: como usar todos os núcleos de CPU sem pagar o custo de memória do modelo de fork por processo. O projeto, publicado no GitHub no repositório yaroslav/kino, exige Ruby 4.0+ e usa os Ractors para rodar código Ruby de fato em paralelo dentro de um único processo.
O problema que ele ataca
A GVL (Global VM Lock) do Ruby permite que apenas uma thread execute código Ruby por vez. Por isso, servidores como o Puma em produção fazem fork de um processo por núcleo, e cada cópia paga o custo de memória do app inteiro. Os Ractors, introduzidos como recurso experimental no Ruby 3.0 e retrabalhados no Ruby 4.0 (com Ractor::Port, shareable_proc e menos contenção de lock), não têm essa limitação: cada Ractor tem seu próprio lock, então um processo consegue rodar Ruby em paralelo.
Segundo o README do projeto, o que faltava era um servidor que soubesse despachar requisições para esses Ractors, e as mudanças do Ruby 4.0 tornaram isso viável de construir.
Como funciona por dentro
A arquitetura é híbrida. Um front-end escrito em Rust (usando tokio + hyper) cuida da rede, enquanto Ractors paralelos executam a aplicação Rack 3. Há também um modo de fallback baseado em threads tradicionais para tudo que ainda não roda em Ractor, incluindo Rails.
São três modos de operação:
:ractor:workersRactors, cada um comthreadsthreads. Exige que o app sejaRactor.shareable?(middleware congelado, endpoints viashareable_proc). Forçar esse modo com um app não compartilhável levantaKino::UnshareableAppError.:threaded: a mesma máquina, mas com Threads comuns. Roda qualquer app Rack, inclusive Rails, mas serializado pela GVL para trabalho de CPU.:auto(padrão): usa:ractorquando o app é compartilhável, senão emite um aviso e cai para:threaded.
O projeto se apresenta como "Puma-shaped": mesma topologia de workers × threads, DSL de configuração familiar e uma CLI kino. A promessa é que quem sabe rodar Puma sabe rodar Kino.
Os números do benchmark
Os testes foram medidos numa instância AWS↳AWS20 conteúdosE-mails de verificação com AWS SES + Lambda (Node.js) e Terraform: do zero ao envioDevSecOps · out 2025Codex na AWS: chegada do agente da OpenAI à nuvem da AmazonDevSecOps · abr 2026Salesforce e AWS ampliam colaboração em IA, CRM e marketplaceDevSecOps · nov 2023Ver tudo em DevSecOps → c7a.2xlarge (8 núcleos AMD EPYC, 16 GB, Amazon Linux 2023), com Ruby 4.0.5 e YJIT. O Puma rodou com 8 workers × 3 threads; o Kino ficou em um único processo. As requisições foram medidas com wrk.
Em endpoints leves de I/O, o README afirma que todo modo do Kino fica de 1,5x a 2,1x à frente do cluster de forks do Puma. Alguns números da tabela principal (req/s):
/plaintext: Kino:ractor229.534 vs Puma 118.176/10k: Kino:ractor178.083 vs Puma 106.768/cpu (fib): Kino:ractor77.999 vs Puma 58.006 (ganho de +34%)
O destaque é a CPU pura: o modo Ractor roda trabalho de CPU mais de 5x mais rápido que o próprio modo threaded do Kino (limitado pela GVL), tudo no mesmo processo pequeno.
Na memória (medida por PSS), o app sintético de benchmark rodou com ~7x menos memória no modo Ractor: 148 MB do Kino contra 1.068 MB do cluster Puma de 8 workers.
A ressalva importante: Rails
Aqui está o ponto que o dev brasileiro precisa entender antes de se animar. Rails não é Ractor.shareable hoje, então o Kino o serve apenas no modo :threaded de fallback, ou seja, um único processo limitado pela GVL. E os números mudam de figura:
- Kino
:threaded(um processo): 2.637 req/s, 92 MB - Puma cluster (8 workers): 12.138 req/s, 389 MB
O próprio README chama isso de "trade-off honesto": o cluster de forks do Puma usa os 8 núcleos e serve ~4,6x mais throughput, mas ao custo de ~4x mais memória. O Rails em modo Ractor fecharia essa diferença de throughput com o custo de memória de um único processo, mas os bloqueios estão no upstream (o próprio Ruby/Rails), rastreados em doc/rails-on-ractors.md.
Ou seja: para a maioria das aplicações Rails em produção no Brasil, o ganho imediato não existe hoje. O apelo real é para apps Rack "puros" (Sinatra, Roda ou serviços customizados) que você consiga tornar Ractor-shareable.
A ferramenta kino --check
Um detalhe prático interessante: como descobrir por que seu app não roda em modo Ractor costuma ser um pesadelo (o famoso Ractor::IsolationError sem contexto), o Kino traz o comando kino --check. Ele não modifica nada e lista cada bloqueador: variáveis capturadas com o local onde foram definidas, variáveis de instância por caminho, e a armadilha de ivars em nível de classe. Exemplo da saída:
$ kino --check
check: app is NOT Ractor-shareable
- app (Proc at app.rb:12)—captures `cache` = {} (Hash) (unshareable)
hints: freeze config at boot; build endpoints with Ractor.shareable_proc;
keep per-worker resources in Ractor.store_if_absent; or run mode :threaded.O status de saída é 0/1, então funciona em pipelines de CI.
Plumbing de produção
O servidor não é só um experimento de performance. Ele inclui drain gracioso, supervisão e respawn de crashes, filas limitadas com backpressure de 503, timeouts de requisição (que devolvem 504 sem matar o handler), proteções contra slowloris e handshakes TLS travados, TLS via rustls, e um hook on_error para integrar com rastreadores de erro. Há também um control plane de leitura (/stats, /metrics no formato Prometheus, /ready e /live para probes de Kubernetes) que continua respondendo mesmo quando todos os workers Ruby estão ocupados.
A instalação dispensa compilador Rust nas versões liberadas, que trazem gems nativas pré-compiladas para Linux (x86_64/aarch64, glibc e musl) e macOS arm64:
bundle add kino
bundle exec kino --init # gera kino.rb comentado
bundle exec kino # usa config.ru + kino.rb na porta 9292O que fica em aberto
O próprio README é explícito: Ractors são oficialmente experimentais no Ruby 4.0, e o Kino também. O modo threaded é descrito como sólido, mas o projeto se posiciona como "a melhor forma de experimentar Ractors hoje", não como substituto de produção do Puma para Rails. Com um roadmap que depende de mudanças no próprio Ruby e no Rails, o Kino é mais um sinal de que o ecossistema Ruby está finalmente construindo ferramentas em cima dos Ractors do que uma troca imediata de servidor. Vale acompanhar, principalmente para quem mantém serviços Rack CPU-bound e quer parar de pagar memória por fork.
Fonte: Hacker News
Este artigo foi escrito por Redação iMasters, um agente de inteligência artificial com revisão editorial humana. Publicado sob revisão editorial de Rafael Chinaglia - iMasters e validação técnica de Tiago Baeta. Saiba como produzimos no expediente.










Comentários
Ninguém comentou ainda. Começa a conversa?