Intermediário5 min de leitura

DynamoDB TTL

O Time to Live (TTL) permite que o DynamoDB delete itens automaticamente assim que um timestamp que você armazena neles passa. Você nomeia um atributo que contém um vencimento em Unix-epoch, e o DynamoDB ceifa os itens expirados em segundo plano — sem job ceifador, sem custo extra.

No cenário do log de auditoria, cada tenant tem uma política de retenção: manter eventos por 90 dias, ou 1 ano, ou 7 para os mais pesados em conformidade. O TTL é como você impõe isso sem rodar a sua própria varredura de deleção.

Como o DynamoDB TTL funciona?

O TTL do DynamoDB exclui itens automaticamente assim que um timestamp Unix-epoch (em segundos) armazenado em um atributo designado passa. Você ativa o TTL na tabela, nomeia o atributo de expiração, e o DynamoDB exclui os itens expirados em segundo plano — normalmente em até 48 horas, sem custo de capacidade de escrita. Itens expirados continuam legíveis até serem fisicamente deletados.

  • O TTL é um atributo que contém um timestamp Unix-epoch (segundos). Quando esse momento passa, o item se torna elegível para deleção.
  • A deleção é em segundo plano e best-effort — tipicamente em até alguns dias da expiração, não no segundo exato. A AWS mira em até 48 horas.
  • As deleções por TTL são gratuitas — elas não consomem capacidade de escrita.
  • Itens expirados-mas-ainda-não-deletados continuam aparecendo nas leituras, então filtre pelo atributo de expiração se você precisa escondê-los imediatamente.

O problema: expirar dados antigos você mesmo é caro

Sem o TTL, impor "descartar eventos com mais de 90 dias" significa rodar o seu próprio ceifador: fazer scan (ou query) por itens antigos em um cronograma e DeleteItem em cada um. Esse scan queima capacidade de leitura, as deleções queimam capacidade de escrita, e você é dono do cronograma, das falhas e dos retries.

Para um log de auditoria de alto volume, isso é um imposto constante e crescente só para jogar dados fora. O TTL move o trabalho inteiro para dentro do DynamoDB, de graça.

Como o TTL funciona

Você ativa o TTL em uma tabela e diz a ela qual atributo contém o vencimento. Segundo o anúncio da AWS, você "especifica um atributo de item contendo um timestamp de expiração em Unix epoch, e o DynamoDB cuida da deleção automaticamente em segundo plano — sem afetar o desempenho da tabela".

Duas propriedades importam para a correção:

  • É best-effort, não exato. O DynamoDB faz scan por itens expirados e os deleta em segundo plano; a AWS mira em deletar em até 48 horas da expiração. Um item é elegível no seu timestamp, mas pode permanecer por um breve período.
  • Itens expirados continuam legíveis até serem ceifados. Uma Query pode retornar um item cujo TTL já passou mas que ainda não foi deletado — então adicione uma FilterExpression no atributo de expiração se "expirado = invisível imediatamente" for um requisito rígido.

E as deleções por TTL não consomem capacidade de escrita, que é o que a torna estritamente mais barata que um ceifador caseiro.

Um exemplo prático: retenção por tenant

Cada evento de auditoria carrega um atributo expiresAt definido quando o evento é escrito — agora + a janela de retenção do tenant, em segundos epoch:

PKSKactionexpiresAtnote
TENANT#acmeEVENT#2026-03-26T…#a0login.success175887360090-day tenant: eligible now
TENANT#acmeEVENT#2026-06-24T…#a1invoice.export1766620800still inside window
TENANT#globex EVENT#2026-06-24T…#b9role.granted17981568007-year compliance tenant

O TTL é ativado com expiresAt como atributo de TTL. Quando o evento de 90 dias do acme cruza 1758873600, o DynamoDB o deleta por conta própria em cerca de dois dias. Os eventos do tenant de conformidade carregam um expiresAt em um futuro distante, então eles sobrevivem — mesma tabela, mesmo mecanismo, retenção diferente por item.

O lado da escrita é só adicionar um número quando você cria o evento. Você pode compor a cláusula SET expiresAt = :ttl e verificar o valor tipado :ttl no Construtor de Expressões do DynamoDB.

Para esconder imediatamente de uma leitura um evento expirado-mas-não-ceifado, adicione expiresAt > :now à FilterExpression da query — embora lembre que um filtro não reduz o custo de leitura (query vs scan).

Faça no DynoTable

O clássico bug de TTL é um expiresAt errado: armazenado em milissegundos em vez de segundos, ou como uma string ISO, de modo que o item ou nunca expira ou some imediatamente. A única forma de pegar isso é olhar o valor realmente armazenado e o seu tipo.

O DynoTable mostra os atributos de cada item com os seus tipos DynamoDB, então você pode confirmar que expiresAt é um Number em segundos epoch — não uma String, não milissegundos — antes de confiar no TTL com retenção real.

Verificando que o atributo expiresAt em um evento de auditoria no DynoTable é um Number em segundos Unix-epoch, o único valor sobre o qual o TTL age.
Verificando que o atributo expiresAt em um evento de auditoria no DynoTable é um Number em segundos Unix-epoch, o único valor sobre o qual o TTL age.

Armadilhas e próximos passos

  • Segundos epoch, como um Number. Esse é o erro de TTL de longe mais comum. Um valor em milissegundos empurra a expiração ~50.000 anos para frente; uma string ISO é ignorada por completo. Verifique o tipo e a unidade.
  • Não confie no timing da deleção. Até ~48 horas podem passar entre a expiração e a deleção. Se "sumido no instante em que expira" importa, filtre pelo atributo nas leituras; não assuma que a linha sumiu fisicamente.
  • As deleções por TTL aparecem no Streams. Uma deleção por TTL emite um registro de stream marcado como gerado pelo sistema — o gancho padrão para arquivar eventos que estão expirando no S3 antes de eles desaparecerem. Veja DynamoDB Streams.
  • As deleções por TTL também atingem os GSIs. Remover um item também o remove de qualquer índice secundário em que ele estava — o que é a limpeza pretendida, mas vale saber se um índice alimentava uma contagem.

O TTL cuida do fim da vida de um evento de forma barata. A próxima pergunta é o que você paga pelas escritas em primeiro lugar — capacidade On-Demand vs Provisionada.

Baixe o DynoTable para inspecionar os tipos de atributo dos seus itens e confirmar que o seu atributo de TTL é um Number em Unix-epoch antes de ligar o TTL.

Atualizado