DynamoDB TTL attribute must be a Number

TL;DR — O Time to Live do DynamoDB só exclui um item quando seu atributo TTL designado contém um Number representando um timestamp de época Unix em segundos. Uma String como "1735689600", um valor em milissegundos, uma data ISO-8601, ou um atributo ausente é silenciosamente ignorado — o item nunca expira. Armazene o TTL como um Number de segundos de época e reescreva os itens afetados.

O que significa

# A second UpdateTimeToLive call within one hour of the first raises:
ValidationException  (TTL settings can only be modified once per table per hour)

# The quieter failure — no error at all, item just never expires:
TTL attribute "expiresAt" = "2026-01-01T00:00:00Z"   ← String, ignored
TTL attribute "expiresAt" = 1735689600000            ← milliseconds: tens of thousands of years away

Habilitar o TTL (UpdateTimeToLive) é bem-sucedido mesmo quando o atributo ainda não existe ou é do tipo errado — o DynamoDB não faz verificação de tipo de antemão. A falha aparece depois: o processo TTL em segundo plano só exclui um item quando o atributo é um Number contendo um timestamp de época Unix em segundos que está no passado (e não mais que cinco anos no passado). Qualquer outra coisa é tratada como "sem expiração".

Por que isso acontece

  • Armazenado como String — o valor é {"S": "1735689600"} em vez de {"N": "1735689600"}. O TTL ignora tipos não-N.
  • Milissegundos em vez de segundosDate.now() (JavaScript) retorna milissegundos; um valor de 13 dígitos está dezenas de milhares de anos no futuro, então o item efetivamente nunca expira.
  • Uma string de data ISO-8601 / legível em vez de segundos de época.
  • Um timestamp mais de cinco anos no passado — o processo TTL o ignora em vez de excluir o item.
  • Um nome de atributo diferente daquele registrado com o TTL (o nome é sensível a maiúsculas).
  • Chamar UpdateTimeToLive novamente cedo demais — a mudança leva até uma hora para processar completamente, e qualquer chamada UpdateTimeToLive adicional para a mesma tabela durante essa hora levanta um ValidationException.

Como corrigir

  1. Escreva o valor de TTL como um Number em segundos de épocaMath.floor(Date.now() / 1000) + ttlSeconds em JavaScript, int(time.time()) + ttl em Python. Nunca armazene milissegundos.
  2. Use o tipo N, não S. Com o cliente de baixo nível isso é {"N": "1735689600"}; o Document Client faz marshal de um número nativo por você.
  3. Combine o nome de atributo registrado exatamente, incluindo maiúsculas. Confirme-o com DescribeTimeToLive.
  4. Faça backfill dos itens existentes — itens escritos antes da correção ainda carregam o valor ruim; reescreva-os com um Number correto de segundos de época.
  5. Espere uma hora entre mudanças de config de TTLUpdateTimeToLive leva até uma hora para processar, e chamadas adicionais durante essa janela são rejeitadas com um ValidationException.

Quer ver o tipo de fio de todo atributo enquanto navega por uma tabela? O app desktop DynoTable renderiza tags de tipo N/S/M inline, então um TTL armazenado como String se destaca antes de custar um item não expirado.

FAQ

Por que meu TTL do DynamoDB não está excluindo itens? O atributo TTL precisa ser um Number contendo um timestamp de época Unix em segundos. Um valor de String, um valor em milissegundos, uma data ISO, ou um nome que não corresponde ao atributo TTL registrado são todos silenciosamente ignorados, então o item nunca expira. A exclusão também não é imediata — o DynamoDB tipicamente remove itens expirados dentro de alguns dias de seu horário de expiração.

O DynamoDB valida o tipo do atributo TTL quando eu habilito o TTL? Não. UpdateTimeToLive é bem-sucedido mesmo se o atributo está ausente ou é do tipo errado. O requisito de tipo (Number, segundos de época) só é imposto pelo processo de exclusão em segundo plano, e é por isso que um TTL ruim falha silenciosamente.

Erros relacionados

Referências

Verificado pela última vez em 2026-07-13 contra a documentação oficial da AWS vinculada acima.

Trabalhe com o DynamoDB sem o Console

Um cliente desktop rápido para DynamoDB que roda o SQL de verdade que o DynamoDB não consegue — JOINs, GROUP BY, agregações — com edição visual e um agente de IA com suas próprias chaves do Bedrock.

Teste grátis de 30 dias, sem cartão de crédito — depois o plano Grátis sem limite de tempo.