Pular para o conteúdo

Por que a Lucimark roda inteira na Cloudflare

Workers, D1, R2 e um Durable Object por cliente. O que ganhamos, o que doeu e por que não existe um Docker no nosso stack.

Foto de Paulo R.

por3 min de leitura

Ilustração de uma rede de telas distribuída ao redor de camadas abstratas de compute, banco, mídia e estado.

Toda plataforma de DOOH resolve o mesmo problema básico: uma tela em algum lugar precisa saber o que tocar, agora, mesmo que a internet daquele ponto caia três vezes por dia. A partir daí as decisões divergem bastante.

A nossa foi rodar tudo na borda da Cloudflare. Sem servidor de aplicação, sem fila gerenciada de terceiros, sem Docker em lugar nenhum — nem em desenvolvimento.

O desenho

Quatro peças fazem o trabalho pesado:

  • Workers servem a API inteira (Hono). Nenhuma requisição de player passa por um datacenter fixo: ela é atendida no ponto de presença mais perto da tela.
  • D1 guarda o catálogo global — tenants, usuários, diretório de players.
  • R2 guarda a mídia. Sem custo de egresso, o que importa quando cada tela baixa os mesmos arquivos de vídeo.
  • Durable Objects guardam o estado de cada cliente. Um TenantDO por organização, com SQLite embutido.

A quarta é a que mais define o resto.

Um Durable Object por cliente

O instinto normal seria uma tabela playlists com uma coluna tenant_id, e um WHERE em toda query. Funciona, e é onde quase todo SaaS começa.

Nós fomos por outro caminho: cada organização tem o seu próprio Durable Object, com o seu próprio banco. Playlists, agendamentos, provas de veiculação e assets daquele cliente vivem lá dentro, e em lugar nenhum além disso.

Isso compra três coisas de uma vez:

  1. Isolamento por construção. Não existe query que possa vazar dados entre clientes, porque não existe uma tabela compartilhada para vazar. O erro clássico de esquecer o WHERE tenant_id deixa de ser possível.
  2. Coordenação sem fila. Um DO é single-threaded por definição. Quando dez telas do mesmo cliente reconectam ao mesmo tempo depois de uma queda de energia, elas conversam com o mesmo objeto, em ordem. Não precisamos de lock distribuído para nada disso.
  3. Localidade. O objeto migra para perto de quem mais o usa.

O preço é real e vale dizer: você perde a query global. "Quantas telas estão ativas na plataforma inteira?" deixa de ser um SELECT COUNT(*) e vira um fan-out ou uma projeção que você mantém de propósito. Toda pergunta que atravessa clientes passa a exigir trabalho explícito.

Para o nosso caso, valeu. As perguntas que importam no dia a dia — "essa playlist mudou?", "essa tela está viva?", "o que tocou ontem nessa tela?" — são todas dentro de um cliente só.

O que doeu

Migrações dentro do DO. Migrar um banco central é uma operação; migrar N bancos, cada um acordando quando o cliente aparece, é outra. Nossa regra hoje é dura: o SQL que roda no boot do TenantDO é só DDL e tem que ser barato. Qualquer backfill pesado vai para um alarm ou waitUntil, fora do caminho crítico. Aprendemos isso da forma normal — um boot que ficou lento demais.

Limites de CPU por requisição. Workers não são o lugar para transcodificar vídeo. Nada que seja pesado de CPU roda em linha; ou vai para um serviço próprio, ou vira Workflow.

Observabilidade. Estado espalhado por milhares de objetos não aparece num dashboard sozinho. Custa esforço deliberado projetar o que importa para fora.

O que não precisamos construir

A parte mais fácil de subestimar é o que some do backlog.

Não temos servidor para escalar, nem cluster para atualizar, nem certificado TLS para renovar, nem CDN para configurar na frente da mídia. wrangler dev sobe o stack inteiro na máquina do dev — sem docker compose, sem Postgres local, sem seis containers para lembrar de derrubar.

Para um time pequeno operando uma rede de telas que precisa ficar de pé, essa é a decisão que mais rende.

Comece com uma tela, grátis

Comece no plano grátis com 1 tela. Faça upgrade quando a rede crescer.

Compartilhar

Foto de Paulo R.

Paulo R.

Fundador e CTO

Fundador da Lucimark. Constrói a plataforma de ponta a ponta — do player Android na tela até os Workers que servem a API.

Ver perfil completo de Paulo R.

Receba os próximos artigos por e-mail

Sem spam — só quando publicarmos algo novo sobre DOOH, produto ou engenharia.

Ao inscrever-se, você concorda em receber e-mails da Lucimark. Pode cancelar quando quiser.

Usamos cookies analíticos para entender quais artigos são lidos e como melhorar o blog. Você pode aceitar, rejeitar os não necessários ou escolher suas preferências.