# Data Streaming na AWS: Kinesis, Firehose, Flink ou MSK?

Tem um tipo de dado que não pode esperar. A transação suspeita que precisa ser barrada agora, não amanhã no relatório. O clique do usuário que, se você lê na hora, vira recomendação certeira, e se lê depois, vira oportunidade perdida. Por muito tempo a gente tratou tudo igual: junta um monte de dado, guarda num banco, e processa em lote mais tarde. Só que tem coisa que vive no agora.

A imagem que me ajuda a explicar isso é a de um rio. Repara que a água não para pra ser usada. Ela passa, e quem está na margem aproveita no caminho: um move a roda do moinho, outro irriga a plantação, outro gera energia. Ninguém represa tudo primeiro pra só então usar. Agora troca a água por dado e você tem data streaming: a informação chega num fluxo contínuo e você reage no instante em que ela passa, em vez de empilhar tudo pra processar lá na frente.

É essa diferença que separa reagir de só descobrir depois. Um banco que barra a fraude no segundo da transação, um e-commerce que recomenda no clique, uma fábrica que ajusta a máquina antes de ela quebrar: em todos, processar depois é quase não processar, porque quando o batch da meia-noite roda o momento já passou.

Só que "streaming na AWS" confunde, porque são quatro serviços de nomes parecidos e até gente boa erra qual usar. Vem comigo que eu separo.

> **Nota de validade:** escrevi este guia em junho de 2026 e revisei em julho de 2026 (a conta já inclui o On-demand Advantage e uma correção importante sobre ordenação). Serviço de streaming muda rápido: modo, quota e preço. Vou manter o post em dia, mas se algo não bater com a tela na tua frente, confere a [doc oficial do Kinesis](https://docs.aws.amazon.com/streams/latest/dev/introduction.html) e me avisa nos comentários que eu corrijo.

## Antes do serviço, o conceito: stream ou batch

Batch é juntar um monte de dado e processar de tempos em tempos, tipo o relatório que roda de madrugada. Streaming é processar evento a evento, conforme chega. Não competem: cada um resolve um tipo de problema. Fechamento contábil do mês é batch e está ótimo. Alerta de fraude é streaming, porque um minuto de atraso já é dinheiro perdido. O erro é usar batch onde o negócio precisa reagir na hora.

## O mapa: os quatro serviços (e o que cada um faz de verdade)

Antes de entrar em cada um, dois avisos que evitam confusão. Primeiro, a AWS **renomeou** dois serviços: o **Kinesis Data Firehose** virou **Amazon Data Firehose** (fev/2024) e o **Kinesis Data Analytics** virou **Amazon Managed Service for Apache Flink** (ago/2023). Se você achar tutorial com o nome antigo, é o mesmo serviço, só trocou a placa. E o Data Streams ganhou um modo novo, o **On-demand Advantage**, que eu explico já já.

Segundo, pra quem vem do Kafka: o que lá é **topic**, aqui no Kinesis é **stream**; o que lá é **partition**, aqui é **shard**. O mapa ajuda, mas não é idêntico: a `PartitionKey` do Kinesis passa por um hash que escolhe o shard, então várias chaves diferentes podem dividir o mesmo shard. Daqui pra frente eu uso o nome certo de cada serviço, mas saiba que os dois mundos se espelham.

![Pipeline de Data Streaming na AWS: produtores enviam eventos pro Kinesis Data Streams, que alimenta um consumer Lambda em tempo real, o Amazon Data Firehose entregando no S3 e o Managed Service for Apache Flink processando pra um dashboard; o Amazon MSK aparece como entrada alternativa.](https://cdn.hashnode.com/uploads/covers/615b22eead6beb6f6506f2b9/79b54b09-9e82-40cb-a658-abb20264f673.png align="center")

### Kinesis Data Streams: o rio que você pode reler

É o coração da história. O stream (o topic, lembra?) é durável: produtores escrevem, consumidores leem, e o dado fica retido por um tempo (até 365 dias), então dá pra reprocessar. É o "log" do rio. Use quando você precisa de um stream durável, com replay, e vai construir o consumer (uma Lambda, ou um app com a Kinesis Client Library, a KCL, que cuida da distribuição de shards e do checkpoint pra você). A capacidade vem dividida em **shards** (as partitions), cada um com um teto de escrita e leitura, e você escolhe entre três modos de capacidade:

*   **Provisioned:** você define o número de shards e paga por eles, ligados ou não.
    
*   **On-demand:** a AWS gerencia os shards sozinha e você paga pelo throughput que usa.
    
*   **On-demand Advantage** (o mais novo): traz warm throughput, com capacidade instantânea pra picos, até 10 GiB/s. Um detalhe que a página de vendas não grita: é um modo de billing da CONTA, com compromisso mínimo de uso (25 MiB/s por pelo menos 24h, cobrado mesmo que você use menos). Em troca, o throughput sai 60%+ mais barato e some a cobrança por stream-hora. Faz sentido a partir de volume de verdade; pro stream pequeno, fica nos dois primeiros modos.
    

### Amazon Data Firehose: só me entrega num destino

Esse foi renomeado de Kinesis Data Firehose em 2024, mesma coisa, nome novo. Aqui você não escreve consumer, é o papel que o Kafka Connect faz no mundo Kafka (os sink connectors). Você aponta uma fonte e um destino (S3, OpenSearch, Redshift e outros) e o Firehose entrega, com buffering, transformação opcional e compressão no caminho. Não tem replay, é entrega quase em tempo real. Use quando o objetivo é pegar o stream e jogar num lugar, sem lógica de consumo própria.

### Managed Service for Apache Flink: processamento COM estado

Esse era o Kinesis Data Analytics, renomeado em 2023. Roda Apache Flink gerenciado pra processamento com estado, o que o Kafka Streams ou o ksqlDB fazem no mundo Kafka: janelas (somar por minuto), joins entre streams, e exactly-once na recuperação do estado. Quando a pergunta é "qual a média móvel dos últimos 5 minutos por usuário", a resposta mora aqui. A infraestrutura de estado, checkpoint e recuperação é responsabilidade do serviço; a semântica de ponta a ponta (o que os teus sources e sinks garantem) e a compatibilidade do estado entre versões continuam sendo decisões suas.

### Amazon MSK (e MSK Serverless): Kafka gerenciado

Se o teu mundo já é Kafka (ecossistema, Kafka API, portabilidade entre nuvens, time que manja), o MSK é o Kafka gerenciado da AWS. O MSK Serverless provisiona e escala a capacidade sozinho e gerencia as partições do topic, sem você dimensionar cluster. Use quando você precisa do Kafka de verdade, não de um equivalente nativo.

## Quando usar cada um

| Você quer... | Serviço AWS | Equivalente no Kafka |
| --- | --- | --- |
| stream durável e replayável, com consumer seu | Kinesis Data Streams | Apache Kafka (Amazon MSK) |
| só entregar o stream num destino, sem escrever código | Amazon Data Firehose | Kafka Connect (sink) |
| processamento com estado (janela, join, agregação) | Managed Service for Apache Flink | Kafka Streams / ksqlDB |

Na vida real, muita arquitetura combina esses serviços em três camadas: entrada, entrega e processamento. Data Streams na entrada, Firehose entregando uma cópia crua no S3 pra histórico, e Flink processando em tempo real pra dashboard. E a entrada não precisa ser o Data Streams: dá pra ter MSK na frente e o Flink depois, porque o Managed Flink lê tanto do Kinesis quanto do MSK.

## Mão na massa: produtor e consumidor no Kinesis Data Streams

O produtor escreve eventos no stream. Repara na `PartitionKey`: ela passa por um hash que decide em qual shard o registro cai. Mesma chave, mesmo shard, e o shard é o território onde a ordem pode existir.

```js
import { KinesisClient, PutRecordsCommand } from "@aws-sdk/client-kinesis";

const kinesis = new KinesisClient({});

await kinesis.send(new PutRecordsCommand({
  StreamName: "eventos-clientes",
  Records: [
    {
      Data: Buffer.from(JSON.stringify({ userId: "u-42", evento: "clique", ts: Date.now() })),
      PartitionKey: "u-42", // mesma chave = mesmo shard (o territorio da ordem)
    },
  ],
}));
```

Agora a pegadinha que quase todo mundo descobre tarde, eu incluso: **o** `PutRecords`**, esse de lote, não garante a ordem**. Nem com a mesma chave. Ele processa cada registro individualmente, aceita sucesso parcial (metade do lote entra, metade falha e você reenvia), e a [doc é explícita](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html): se você precisa ler na ordem em que escreveu, o caminho é o `PutRecord` no singular, serial, encadeando o `SequenceNumberForOrdering` de cada escrita na seguinte:

```js
import { KinesisClient, PutRecordCommand } from "@aws-sdk/client-kinesis";

const kinesis = new KinesisClient({});

const putEvento = async (payload, sequenciaAnterior) =>
  kinesis.send(new PutRecordCommand({
    StreamName: "eventos-clientes",
    PartitionKey: payload.userId, // mesma entidade, mesmo shard
    Data: Buffer.from(JSON.stringify(payload)),
    // encadeia a escrita anterior: e isso que garante a sequencia
    ...(sequenciaAnterior ? { SequenceNumberForOrdering: sequenciaAnterior } : {}),
  }));

const login = await putEvento({ userId: "u-42", evento: "login" });
await putEvento({ userId: "u-42", evento: "compra" }, login.SequenceNumber);
```

![A ordem vive dentro do shard: a PartitionKey passa pelo hash e escolhe o shard; eventos da mesma chave ficam em sequência no mesmo shard; entre shards não existe ordem global. PutRecords de lote não garante ordem, ordem estrita pede PutRecord serial encadeado.](https://cdn.hashnode.com/uploads/covers/615b22eead6beb6f6506f2b9/962c8710-392d-4e8c-8ce7-167f49807b27.png align="center")

Com isso o consumidor sempre vê "login" antes de "compra". O preço é honesto: você trocou o throughput do lote pela garantia de sequência. Se são milhares de eventos por segundo e a ordem estrita não é requisito, o `PutRecords` é a escolha certa. A garantia que você pede muda a conta que você paga; arquitetura é isso.

Do lado de lá, o consumidor serverless é uma Lambda com event source mapping no stream. E aqui vai a segunda verdade que separa exemplo de blog de código de produção: a entrega é **at-least-once**, o mesmo evento pode chegar duas vezes. Então o handler precisa ser idempotente e saber falhar por item, sem derrubar o lote inteiro:

```js
export const handler = async (event) => {
  const batchItemFailures = [];

  for (const record of event.Records) {
    try {
      const payload = JSON.parse(Buffer.from(record.kinesis.data, "base64").toString("utf8"));

      // Em producao: consulte e grave um eventId num store idempotente
      // ANTES do efeito colateral. Duplicata processada duas vezes = cliente cobrado duas vezes.
      console.log(payload.userId, payload.evento);
    } catch (error) {
      // falha SO este item; o resto do lote segue
      batchItemFailures.push({ itemIdentifier: record.kinesis.sequenceNumber });
    }
  }

  return { batchItemFailures };
};
```

O retorno de falhas parciais só tem efeito com `ReportBatchItemFailures` ligado no event source mapping. E pra produção de verdade eu ainda colocaria idempotência persistente, Logger e Metrics do [AWS Lambda Powertools](https://docs.powertools.aws.dev/lambda/typescript/latest/), limite de retries, idade máxima do registro e um destination pra falha. Um poison record não pode travar o shard pra sempre.

Um detalhe pra fechar: a **ordem é por shard**, não no stream inteiro. Se a ordem importa pra uma entidade (um usuário, um pedido), a chave é a dessa entidade. Senão, os eventos espalham pelos shards e a ordem global vira ilusão.

## Os trade-offs honestos

*   **Ordenação e escala:** a ordem é por shard, não global, e ordem estrita pede `PutRecord` serial (o lote não garante). A escolha da partition key não é um detalhe, é uma decisão de design que define como a sua aplicação se comporta E como ela escala. Chave enviesada joga tráfego demais num shard só (o hot shard) e você perde throughput mesmo pagando por vários; e cada partition key aguenta no máximo 1 MiB/s, não importa o warm throughput que você configurou. Isso sozinho rende um post inteiro, e vai ter.
    
*   **Duplicata e observabilidade:** a entrega é at-least-once, então replay e retry exigem consumer idempotente; reprocessar um evento que cobra o cliente duas vezes só troca um incidente por outro. E consumer lag precisa de alarme: streaming sem observabilidade vira batch acidental, o evento chega agora e o consumer processa meia hora depois. O Well-Architected dá nome a essas contas: Reliability pede idempotência e recuperação, Operational Excellence pede métrica e alarme, Cost Optimization pede modo de capacidade que siga o tráfego real, não a esperança do time.
    
*   **Retenção e replay:** Data Streams retém e deixa reprocessar; Firehose não, ele entrega e segue.
    
*   **Custo:** provisioned paga shard mesmo parado; on-demand paga uma taxa por stream-hora mais o uso. Stream ligado 24/7 com tráfego previsível às vezes sai mais barato provisionado. Custo é decisão de arquitetura, como o Werner Vogels martela no Frugal Architect, e é o mesmo papo de [disponibilidade tem um preço](https://willpeixoto.dev/resiliencia-custo-ha-multi-regiao-ou-on-premise).
    
*   **Latência:** streaming é baixa, mas não é zero. O Firehose ainda tem buffering (de segundos a minutos), então não conte com ele pra reação instantânea.
    

## Kinesis ou MSK?

Se você não tem compromisso com Kafka, o Kinesis é mais simples e nativo, casa melhor com Lambda e o resto do serverless. Se você já vive de Kafka (conectores, ferramentas, multi-cloud, time treinado), o MSK te dá o Kafka sem você operar o cluster na unha. A escolha é de contexto e ecossistema; "qual é o melhor" é a pergunta errada.

## O que você leva

*   Data streaming é processar no fluxo, em tempo real, pra reagir no momento (fraude, recomendação, IoT). Batch é pra quando o atraso não dói.
    
*   Kinesis Data Streams é o stream durável e replayável; Amazon Data Firehose entrega num destino; Managed Service for Apache Flink faz processamento com estado; MSK é Kafka gerenciado.
    
*   A ordem é por shard, então escolha a partition key com intenção. E ordem ESTRITA pede `PutRecord` serial com `SequenceNumberForOrdering`: o `PutRecords` de lote não garante.
    
*   Lambda com Kinesis é at-least-once: idempotência e falha por item (`batchItemFailures`) fazem parte do desenho, não são luxo.
    
*   Provisioned ou on-demand é decisão de custo, e arquitetura real combina os serviços em vez de escolher um só.
    

## Sua vez

Você usa streaming em algum projeto? Conta qual desses quatro entrou no teu desenho, e se já te queimou escolher o errado. Manda aquele joinha, compartilha com quem ainda processa tudo no batch da meia-noite, e bora trocar ideia. Valeu demais!

BUILD. SCALE. REPEAT. =D

## Fontes

*   [Amazon Kinesis Data Streams (FAQs)](https://aws.amazon.com/kinesis/data-streams/faqs/)
    
*   [PutRecords não garante ordenação (API Reference)](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html)
    
*   [PutRecord e SequenceNumberForOrdering (API Reference)](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html)
    
*   [Lambda com Kinesis: falhas parciais (ReportBatchItemFailures)](https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-batchfailurereporting.html)
    
*   [Kinesis Data Streams On-demand Advantage](https://aws.amazon.com/blogs/big-data/amazon-kinesis-data-streams-launches-on-demand-advantage-for-instant-throughput-increases-and-streaming-at-scale/)
    
*   [Fault tolerance no Managed Service for Apache Flink](https://docs.aws.amazon.com/managed-flink/latest/java/how-fault.html)
    
*   [Amazon Managed Service for Apache Flink (renomeação)](https://aws.amazon.com/blogs/aws/announcing-amazon-managed-service-for-apache-flink-renamed-from-amazon-kinesis-data-analytics/)
    
*   [Amazon Data Firehose](https://aws.amazon.com/blogs/machine-learning/category/analytics/amazon-kinesis/amazon-data-firehose/)
