Blog

Como eu enxergo a arquitetura do Spotify.

Quinto texto da série em que eu leio arquiteturas conhecidas a partir de material público de engenharia. Não é a planta: é a leitura do que organiza o resto.

O Spotify é o que eu acho mais subestimado do conjunto, porque as duas coisas difíceis dele são invisíveis pra quem usa.

A primeira: o orçamento de latência

O produto tem uma promessa implícita: você aperta o play e a música começa. Não em três segundos. Agora.

Isso vira um orçamento, e orçamento é uma ferramenta de projeto que eu queria ver mais gente usar. Você define o total aceitável e distribui entre as etapas, sabendo que a soma não pode estourar.

DO TOQUE AO PRIMEIRO SOM — O ORÇAMENTO INTEIRO Resolver faixa metadados · cache local Autorizar direitos · região Primeiros bytes do áudio cache no aparelho → borda → origem Decodificar e tocar o total é a promessa · cada etapa gasta um pedaço dela A OTIMIZAÇÃO REAL É NÃO PRECISAR DA REDE: prefetch da próxima faixa da fila · cache local do que se ouve muito · início em qualidade menor
Orçamento de latência — a etapa mais cara é a que você consegue evitar

E aí vem a parte que eu acho a mais inteligente: a maior otimização não é deixar a rede mais rápida, é não usar a rede.

O aparelho guarda o que você ouve com frequência. Ele busca a próxima faixa da fila antes de você chegar nela. Ele começa a tocar com um trecho de qualidade menor enquanto o resto chega.

Nenhuma dessas três é sofisticada. Todas dependem de uma coisa só: alguém decidiu, no começo, que o número que importa é o tempo até o primeiro som, e desenhou pra trás a partir dele.

Vale registrar também a fase em que a distribuição era feita entre os próprios usuários, num modelo par a par, antes de as redes de distribuição ficarem baratas o bastante para substituir aquilo. É um bom lembrete de que arquitetura é datada: a decisão certa em 2010 deixou de ser em 2015, e desmontar um sistema que funciona porque o mundo mudou é uma decisão de engenharia legítima.

A segunda: o log de eventos é dinheiro

Cada reprodução gera um evento. Multiplicado por centenas de milhões de pessoas, isso é um dos maiores fluxos de eventos que existem.

E é aqui que o sistema fica interessante pra mim, porque o mesmo fluxo alimenta dois consumidores com exigências opostas.

Evento de play quem, o quê, quanto tempo Log de eventos uma escrita vários consumidores Personalização tolera perda · tolera atraso · aproximado serve Royalties não tolera perda nem duplicata · é contábil
O mesmo log, dois contratos — um aproximado, um exato

A personalização pode perder evento. Se 0,1% das reproduções não entrar no cálculo, a recomendação da semana continua boa. Ela tolera atraso, tolera duplicata e trabalha com estimativa.

O pagamento de direitos não pode. Ali cada reprodução é uma fração de centavo devida a alguém, e o total precisa fechar. Perder evento é não pagar. Duplicar é pagar duas vezes.

É o mesmo dado, com dois contratos de qualidade diferentes. E a consequência de arquitetura é que o caminho que alimenta o financeiro precisa de tudo que eu descrevi em o que é um core ledger: identificador estável por evento, deduplicação por constraint, e uma verificação periódica que confere se o total bate.

Tratar os dois caminhos com o mesmo rigor é caro demais de um lado e frouxo demais do outro. Separar os contratos é o que permite otimizar cada um pelo que ele realmente precisa. Escrevi sobre a impossibilidade de entrega exatamente uma vez em exactly-once é mentira — esse é o caso onde a distinção deixa de ser acadêmica e vira dinheiro.

A recomendação, e por que ela funciona

A parte de personalização combina abordagens que sozinhas seriam fracas.

Tem o sinal de comportamento coletivo: quem ouve isso também ouve aquilo. É poderoso e tem um ponto cego famoso, o começo frio — música nova, sem histórico, não é recomendada por ninguém, então nunca ganha histórico.

Tem o sinal de texto: o que se escreve sobre aquele artista em resenha, blog e playlist. Isso dá contexto cultural que o comportamento não dá.

E tem o sinal do próprio áudio: características extraídas do som, que funcionam mesmo para uma faixa que ninguém ouviu ainda. É a peça que resolve o começo frio.

O que eu levo daqui não é o algoritmo. É que cada sinal cobre a fraqueza do outro, e que a combinação foi desenhada a partir das falhas conhecidas de cada um. Isso é engenharia de sistema, não de modelo.

O que eu levo pra sistema pequeno

Escreva o orçamento antes da arquitetura. “Essa tela precisa responder em 300ms” é uma restrição que decide dezenas de escolhas depois. Sem o número, cada decisão é tomada isoladamente e a soma estoura.

A melhor otimização é remover a etapa. Cache local, prefetch e resultado parcial batem qualquer ajuste fino no que já existe.

Um fluxo de eventos, vários contratos. Se o mesmo dado alimenta análise e financeiro, eles não têm o mesmo requisito. Escrever isso explicitamente evita gastar demais num lado e de menos no outro.

Arquitetura tem prazo de validade. A decisão certa há cinco anos pode estar errada hoje porque o custo relativo das coisas mudou. Reavaliar não é retrabalho.

← Voltar pro blog