DynamoDB TTL: o guia completo para expirar itens
O Time to Live (TTL) permite que o DynamoDB exclua itens automaticamente uma vez que um timestamp que você armazena neles passe. Você nomeia um atributo que contém uma expiração em Unix-epoch, e o DynamoDB colhe os itens expirados em background — sem job de colheita, 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 compliance. O TTL é como você impõe isso sem executar sua própria varredura de exclusão.
Como funciona o DynamoDB TTL?
O TTL do DynamoDB auto-exclui itens uma vez que um timestamp Unix-epoch (segundos) que você armazena em um atributo designado passe. Você habilita o TTL na tabela, nomeia o atributo de expiração, e o DynamoDB colhe os itens expirados em background — tipicamente em poucos dias, sem custo de capacidade de escrita. Itens expirados permanecem legíveis até serem fisicamente excluídos.
- O TTL é um atributo que contém um timestamp Unix-epoch (segundos). Quando esse tempo passa, o item se torna elegível para exclusão.
- A exclusão é em background e best-effort — tipicamente em poucos dias após a expiração, não no segundo exato.
- Exclusões por TTL são gratuitas — elas não consomem capacidade de escrita, embora em uma tabela global a exclusão replicada custe uma escrita em cada outra região de réplica.
- Itens expirados mas ainda não excluídos ainda aparecem 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 "descarte eventos com mais de 90 dias" significa executar seu próprio
colhedor: fazer scan (ou query) por itens antigos num cronograma e fazer DeleteItem de cada um.
Esse scan queima capacidade de leitura, as exclusões queimam capacidade de escrita, e você é dono do
cronograma, das falhas e das retentativas.
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ê habilita o TTL em uma tabela e diz a ela qual atributo contém a expiração. Segundo o anúncio da AWS, você designa um atributo de item que contém um timestamp de expiração em Unix-epoch, e o DynamoDB cuida da exclusão automaticamente em background sem afetar o desempenho da tabela.
Duas propriedades importam para a correção:
- É best-effort, não exato. O DynamoDB varre por itens expirados e os exclui em background; a exclusão tipicamente acontece em poucos dias após a expiração. Um item é elegível no seu timestamp mas pode permanecer brevemente.
- Itens expirados ainda são legíveis até serem colhidos. Um
Querypode retornar um item cujo TTL já passou mas que ainda não foi excluído — então adicione umaFilterExpressionno atributo de expiração se "expirado = invisível imediatamente" for um requisito rígido.
E exclusões por TTL não consomem capacidade de escrita, que é o que o torna estritamente mais barato que um colhedor que você mesmo executa.
Um exemplo trabalhado: 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 de epoch:
| PK | SK | action | expiresAt | note |
|---|---|---|---|---|
| TENANT#acme | EVENT#2026-03-26T…#a0 | login.success | 1782259200 | 90-day tenant: eligible now |
| TENANT#acme | EVENT#2026-06-24T…#a1 | invoice.export | 1790035200 | still inside window |
| TENANT#globex EVENT#2026-06-24T…#b9 | role.granted | 2003184000 | 7-year compliance tenant |
O TTL é habilitado com expiresAt como o atributo de TTL. Quando o evento de 90 dias do acme
cruza 1782259200, o DynamoDB o exclui por conta própria em cerca de dois dias. Os
eventos do tenant de compliance carregam um expiresAt bem no futuro, então sobrevivem — mesma
tabela, mesmo mecanismo, retenção diferente por item.
O lado de 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 de uma leitura imediatamente um evento expirado-mas-não-colhido, adicione
expiresAt > :now à FilterExpression da consulta — embora lembre que um filtro
não reduz o custo de leitura (query vs scan).
Faça isso no DynoTable
O bug clássico de TTL é um expiresAt errado: armazenado em milissegundos em vez de
segundos, ou como uma string ISO, então o item ou nunca expira ou some
imediatamente. A única forma de pegar isso é olhar o valor de fato armazenado e
seu tipo.
O DynoTable mostra os atributos de cada item com seus tipos do DynamoDB, então você pode
confirmar que expiresAt é um Number em segundos de epoch — não uma String, não
milissegundos — antes de confiar a retenção real ao TTL.

Armadilhas e próximos passos
- Segundos de epoch, como um Number. Este é o erro de TTL mais comum de todos. Um valor em milissegundos empurra a expiração ~50.000 anos para o futuro; uma string ISO é ignorada por completo. Verifique o tipo e a unidade. Cole o valor no conversor de TTL — ele detecta automaticamente segundos vs milissegundos e sinaliza exatamente esse erro.
- Não confie no timing da exclusão. Alguns dias podem passar entre a expiração e a exclusão. Se "sumir no instante em que expira" importa, filtre pelo atributo nas leituras; não presuma que a linha se foi fisicamente.
- Exclusões por TTL aparecem no Streams. Uma exclusão por TTL emite um registro de stream sinalizado como gerado pelo sistema — o hook padrão para arquivar eventos que expiram no S3 antes de eles desaparecerem. Veja DynamoDB Streams.
- Exclusões por TTL também atingem . 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 guiava uma contagem.
O TTL cuida do fim da vida de um evento de forma barata. A próxima questão é 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 seu atributo de TTL é um Number Unix-epoch antes de você ligar o TTL.


