Pular para o conteúdo

Design clássico · Sênior

Flash sale (venda relâmpago)

Projeto de entrevista clássico. Pontos centrais: reservas e concorrência e controle de sobrecarga.

16 min de leitura · Conteúdo revisado em 23 de outubro de 2026

Resposta curta

Projeto de entrevista clássico. Pontos centrais: reservas e concorrência e controle de sobrecarga. A venda relâmpago isola um pedaço difícil do comércio eletrônico: vender uma quantidade muito limitada de estoque sob demanda extrema. A meta é deixar os compradores disputarem as unidades de forma justa e concluírem a compra sem nunca vender além do estoque.

01 · CONTEXTO

Poucas unidades, muita gente

A venda relâmpago isola um pedaço difícil do comércio eletrônico: vender uma quantidade muito limitada de estoque sob demanda extrema. A meta é deixar os compradores disputarem as unidades de forma justa e concluírem a compra sem nunca vender além do estoque.

O fluxo ganha uma etapa entre ver o produto e pagar: a reserva da unidade. O pagamento passa por um terceiro e leva segundos, e não se pode manter o estoque preso numa transação aberta de banco durante todo esse tempo. A reserva tira a unidade de circulação de imediato e deixa o acerto do dinheiro para depois.

O material público lista quatro aprofundamentos que formam o roteiro deste caso: manter a consistência sob contenção extrema, liberar com eficiência as reservas vencidas, lidar com milhões de usuários chegando de uma vez e tornar justo o acesso ao estoque limitado.

02 · CORRIDA

O contador que fica negativo

A forma ingênua de vender é ler a contagem disponível, conferir se é maior que zero e depois decrementá-la. Para um comprador isolado isso está correto. Com dois compradores no mesmo instante, os dois leem a mesma contagem, os dois concluem que há unidade para vender e os dois seguem para a cobrança do cartão.

Quando as duas gravações chegam, a primeira leva a contagem a zero e a segunda decrementa de novo, e a contagem fica negativa. O vendedor termina com um reembolso a fazer e dois clientes insatisfeitos.

  1. Dois compradores pedem a última unidade quase no mesmo instante.

    Diagrama da arquitetura: Corrida na baixa de estoque
    CLComprador Aquer a unidade
    CLComprador Bquer a unidade
    CPServiço de checkout
    DBBanco de estoque
  2. Os dois pedidos leem a mesma contagem e veem uma unidade disponível.

    Diagrama da arquitetura: Corrida na baixa de estoque
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoqueuma unidade
  3. Cada um conclui que há unidade para vender e segue para a cobrança.

    Diagrama da arquitetura: Corrida na baixa de estoque
    CLComprador A
    CLComprador B
    CPServiço de checkoutdecide vender
    DBBanco de estoque
  4. A primeira gravação leva a contagem a zero e a segunda decrementa de novo, deixando-a negativa.

    Diagrama da arquitetura: Corrida na baixa de estoque
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoquecontagem negativa
  5. Uma linha de contagem única obriga todo checkout do item a atualizar a mesma linha, o que prepara a próxima seção.

    Diagrama da arquitetura: Corrida na baixa de estoque
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoquelinha única

03 · LINHA QUENTE

Uma linha só, uma fila só

Na descrição do Hello Interview para o trabalho da Shopify, a tentativa óbvia num banco relacional era uma linha por item com um contador de quantidade. Todo checkout de um item popular tinha de atualizar a mesma linha, e o InnoDB, motor do MySQL, concede o travamento da linha a uma transação por vez, de modo que os demais compradores esperam. Milhares de checkouts do mesmo item colapsavam num único travamento.

A saída documentada espalha a disputa. Para reservar unidades, o sistema seleciona e trava linhas disponíveis e as retira do conjunto. O recurso SKIP LOCKED faz o MySQL pular linhas travadas e procurar outra disponível; assim, dois compradores do mesmo item travam linhas diferentes e confirmam em paralelo, em vez de esperar atrás de um contador compartilhado.

O ganho tem um limite. Um item com muito estoque poderia gerar centenas de milhares de linhas quase ociosas, por isso há um teto de linhas por item e um processo de reposição que mantém o conjunto abastecido.

  1. Dois compradores do mesmo item chegam ao checkout.

    Diagrama da arquitetura: Reserva por linha-unidade com reposição
    CLComprador Apede reserva
    CLComprador Bpede reserva
    CPServiço de checkout
    DBBanco de estoque e reservas
    CPReposição do conjunto
  2. Numa transação curta, o checkout seleciona e trava linhas disponíveis e as retira do conjunto.

    Diagrama da arquitetura: Reserva por linha-unidade com reposição
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoque e reservastrava linhas
    CPReposição do conjunto
  3. O segundo comprador passa por cima das linhas já travadas e trava outras, sem esperar.

    Diagrama da arquitetura: Reserva por linha-unidade com reposição
    CLComprador A
    CLComprador Bsem esperar
    CPServiço de checkout
    DBBanco de estoque e reservaslinhas diferentes
    CPReposição do conjunto
  4. A reserva fica gravada como uma linha com prazo, e os travamentos só existem dentro das transações curtas que a tocam.

    Diagrama da arquitetura: Reserva por linha-unidade com reposição
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoque e reservasreserva com prazo
    CPReposição do conjunto
  5. Um processo de reposição mantém o conjunto abastecido quando ele esvazia.

    Diagrama da arquitetura: Reserva por linha-unidade com reposição
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoque e reservas
    CPReposição do conjuntorepõe linhas
  6. Uma corrida pode esvaziar o conjunto antes de a reposição chegar; então a própria reserva reabastece o conjunto na hora e tenta de novo.

    Diagrama da arquitetura: Reserva por linha-unidade com reposição
    CLComprador A
    CLComprador B
    CPServiço de checkout
    DBBanco de estoque e reservasconjunto vazio
    CPReposição do conjunto
AspectoContador únicoUma linha por unidade
Como o estoque é guardadoUma linha por item com um contador de quantidadeLinhas disponíveis que o checkout trava e retira do conjunto
Sob disputaMilhares de checkouts do item colapsam num único travamentoCompradores travam linhas diferentes e confirmam em paralelo
O que se pagaTodo checkout do item atualiza a mesma linhaUm processo novo de reposição para operar, monitorar e acionar, cuja falha típica é o conjunto vazio no meio da venda

04 · ATOMICIDADE

Contar num lugar, vender em outro

O mesmo relato mostra por que o contador pode não poder ficar fora do banco que guarda o estoque. Antes, o Redis registrava as unidades reservadas temporariamente e o MySQL registrava as unidades que o comerciante de fato tinha. Como mecanismo de concorrência, o Redis funcionava, mas as duas gravações aconteciam em bancos diferentes e não podiam ser confirmadas juntas.

Os dois erros custam dinheiro: vender a última unidade a dois compradores obriga a cancelar um pedido, e esconder uma unidade que ainda está no armazém faz o comerciante perder uma venda. Se o sistema atualiza o MySQL e cai antes de limpar a reserva no Redis, a compra está concluída, mas o Redis ainda trata aquelas unidades como reservadas, e o sistema esconde estoque que está disponível. Na ordem inversa o erro é o oposto: a reserva é limpa, a queda vem antes da atualização e as unidades voltam à venda mesmo já vendidas. Trocar a ordem só muda qual falha é possível.

O commit em duas fases também não resolve: exigiria que os dois bancos participassem do mesmo protocolo de coordenação, o que o Redis não podia fazer.

05 · PRAZO

Reservas que ninguém avisa que acabaram

Reservar não é comprar. Se o pagamento falha ou o comprador sai do checkout, há um sinal explícito que libera a reserva. Se o comprador apenas fecha o notebook, nenhum sinal chega, e, se nada devolver as unidades, a venda aparece como esgotada enquanto o armazém ainda tem estoque. Por isso o prazo precisa viver nos dados, e algo ainda em execução tem de agir quando ele passa.

Com um contador em Redis, a saída tentadora é um TTL, mas um TTL na chave do contador apagaria o contador inteiro, e não a reserva de um comprador. Uma chave por reserva também não ajuda: o Redis não tem um jeito rápido de obter a contagem a partir de um monte de chaves por reserva.

Para o desenho em MySQL, o Hello Interview diz que o post da Shopify não informa o que ela fez e dá um palpite próprio: guardar a reserva como uma linha com prazo e contar como ativas só as reservas ainda não vencidas. Vencido o prazo, a reserva deixa de contar e a próxima reposição devolve a capacidade. Uma rotina de limpeza ainda é desejável, mas é coleta de lixo, não correção.

06 · ENTRADA

A multidão antes do banco

Mesmo um desenho correto de estoque precisa de proteção contra milhões de usuários chegando de uma vez, que o material lista como aprofundamento à parte. Uma sala de espera virtual encaminha o excesso de usuários a uma fila personalizada, preservando a experiência e protegendo os servidores de origem de serem sobrecarregados com requisições.

Uma sala de espera bem-feita lembra o estado de cada visitante, para que ninguém perca o lugar na fila nem tenha de reentrar se sair do site, e abre vagas mais depressa acompanhando o fluxo de entrada e de saída.

Além da fila, o próprio servidor precisa se proteger. Vazão é tudo o que chega; a vazão útil (goodput) é a parte tratada sem erros e com latência baixa o bastante para o cliente aproveitar a resposta. Descartar carga permite manter a vazão útil mesmo quando a carga oferecida cresce, e rejeitar cedo é o ponto mais barato para descartar, ao custo de visibilidade.

  1. Uma multidão tenta abrir a venda ao mesmo tempo.

    Diagrama da arquitetura: Admissão antes do checkout
    CLMultidão de compradoreschegada em massa
    EDGSala de espera na borda
    CPServiço de checkout
    DBBanco de estoque
  2. A sala de espera encaminha o excesso de usuários a uma fila personalizada, em vez de deixá-lo chegar à origem.

    Diagrama da arquitetura: Admissão antes do checkout
    CLMultidão de compradores
    EDGSala de espera na bordafila de espera
    CPServiço de checkout
    DBBanco de estoque
  3. A sala guarda o estado de cada visitante, que assim mantém o lugar na fila.

    Diagrama da arquitetura: Admissão antes do checkout
    CLMultidão de compradores
    EDGSala de espera na bordalugar guardado
    CPServiço de checkout
    DBBanco de estoque
  4. Só o tráfego admitido chega ao checkout, que ainda pode descartar cedo o que exceder sua capacidade.

    Diagrama da arquitetura: Admissão antes do checkout
    CLMultidão de compradores
    EDGSala de espera na borda
    CPServiço de checkoutdescarta excedente
    DBBanco de estoque
  5. O banco de estoque recebe apenas a carga que sobrou depois dessas camadas.

    Diagrama da arquitetura: Admissão antes do checkout
    CLMultidão de compradores
    EDGSala de espera na borda
    CPServiço de checkout
    DBBanco de estoquecarga controlada

O material público trata a justiça do acesso ao estoque limitado como um aprofundamento à parte, ao lado da consistência, da expiração das reservas e da multidão.

Perguntas frequentes

O que é Flash sale (venda relâmpago)?

Projeto de entrevista clássico. Pontos centrais: reservas e concorrência e controle de sobrecarga.

O que o design de Flash sale (venda relâmpago) cobre?

Ele está organizado nestas seções: Poucas unidades, muita gente, O contador que fica negativo, Uma linha só, uma fila só, Contar num lugar, vender em outro, Reservas que ninguém avisa que acabaram e A multidão antes do banco.

Quanto tempo leva Flash sale (venda relâmpago) e qual é o nível?

Leva cerca de 16 minutos para ler e tem nível Sênior.

Agora projete você mesmo

Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.