

# Uso del período de vida (TTL) en DynamoDB
<a name="TTL"></a>

Tiempo de vida (TTL) para DynamoDB es un método rentable para eliminar elementos que ya no son relevantes. TTL permite definir una marca de tiempo de vencimiento por elemento que indica cuándo deja de necesitarse un elemento. DynamoDB elimina automáticamente los elementos vencidos a los pocos días de su fecha de vencimiento, sin afectar al rendimiento de escritura. 

Para usar TTL, primero debe activarlo en una tabla y, a continuación, definir un atributo específico para almacenar la marca de tiempo de vencimiento de TTL. La marca de tiempo debe almacenarse como un tipo de datos de [Número](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes) en [formato de tiempo Epoch de Unix](https://en.wikipedia.org/wiki/Unix_time) con nivel de precisión de segundos. El proceso TTL ignora los elementos con un atributo TTL que no sea un tipo de número. Cada vez que se crea o actualiza un elemento, puede calcular el tiempo de vencimiento y guardarlo en el atributo TTL.

El sistema puede eliminar los elementos con atributos TTL válidos y vencidos en cualquier momento, normalmente a los pocos días de que hayan caducado. Puede seguir actualizando los elementos vencidos que no se hayan eliminado todavía, lo que incluye cambiar o eliminar los atributos TTL. Al actualizar un elemento vencido, le recomendamos que utilice una expresión de condición para asegurarse de que el elemento no se haya eliminado posteriormente. Utilice expresiones de filtro para eliminar los elementos vencidos de los resultados de [Scan](Scan.md#Scan.FilterExpression) y [Query](Query.FilterExpression.md).

Los elementos eliminados funcionan de forma similar a los que se eliminan con las operaciones de eliminación habituales. Una vez eliminados, los elementos pasan a DynamoDB Streams como eliminaciones de servicio en lugar de eliminaciones de usuario. Además, se eliminan de los índices secundarios locales y de los índices secundarios globales de igual modo que con las otras operaciones de eliminación. 

Si usa la [versión 2019.11.21 (actual) de las tablas globales](GlobalTables.md) y también la característica TTL, DynamoDB replicará las eliminaciones de TTL en todas las tablas de réplica. La eliminación de TTL inicial no consume unidades de capacidad de escritura (WCU) en la región donde se produce el vencimiento de TTL. Sin embargo, la eliminación de TTL replicada en las tablas de réplica consume una unidad de capacidad de escritura replicada cuando se usa la capacidad aprovisionada, o una unidad de escritura replicada cuando se usa el modo de capacidad bajo demanda, en cada una de las regiones de réplica. En estos casos, se aplicarán los cargos pertinentes.

Para obtener más información acerca de TTL, consulte estos temas:

**Topics**
+ [

# Habilitación del período de vida (TTL) de DynamoDB
](time-to-live-ttl-how-to.md)
+ [

# Período de vida (TTL) de computación en DynamoDB
](time-to-live-ttl-before-you-start.md)
+ [

# Uso de elementos caducados y el período de vida (TTL)
](ttl-expired-items.md)

# Habilitación del período de vida (TTL) de DynamoDB
<a name="time-to-live-ttl-how-to"></a>

**nota**  
Para facilitar la depuración y la verificación del correcto funcionamiento de la característica TTL, los valores proporcionados para el TTL de un elemento se registran en texto no cifrado en los registros de diagnóstico de DynamoDB.

Puede habilitar TTL en la consola de Amazon DynamoDB, la AWS Command Line Interface (AWS CLI) o mediante la [referencia de la API de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/) con cualquiera de los AWS SDK supuestos. La habilitación de TTL en todas las particiones tarda aproximadamente una hora.

## Activación del TTL de DynamoDB mediante la consola de AWS
<a name="time-to-live-ttl-how-to-enable-console"></a>

1. Inicie sesión en la Consola de administración de AWS y abra la consola de DynamoDB en [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. Elija **Tables (Tablas)** y, a continuación, seleccione la tabla que desee modificar.

1. En la pestaña **Configuración adicional**, dentro de la sección **Tiempo de vida (TTL)**, elija **Activar**.

1. Al habilitar TTL en una tabla, DynamoDB requiere que identifique un nombre de atributo específico que el servicio buscará al determinar si un elemento cumple los requisitos para el vencimiento. El nombre del atributo TTL, que se muestra a continuación, distingue entre mayúsculas y minúsculas y debe coincidir con el atributo definido en las operaciones de lectura y escritura. Si no coinciden, los elementos caducados no se eliminarán. Si se cambia el nombre del atributo TTL, deberá desactivarse el TTL y volverse a activar con el nuevo atributo de ahora en adelante. Una vez desactivado, el TTL seguirá procesando las eliminaciones durante aproximadamente 30 minutos. El TTL debe reconfigurarse en las tablas restauradas.  
![\[Nombre de atributo TTL que distingue entre mayúsculas y minúsculas que DynamoDB utiliza para determinar si un artículo puede caducar.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/EnableTTL-Settings.png)

1. (Opcional) Puede realizar una prueba simulando la fecha y la hora de vencimiento y haciendo coincidir algunos elementos. Al hacer se muestra una lista de elementos de ejemplo donde se confirma que hay elementos que contienen el nombre del atributo TTL junto con la fecha de vencimiento.

Ahora que TTL está activado, el atributo TTL llevará la marca **TTL** cuando consulte los elementos en la consola de DynamoDB. Para ver la fecha y la hora de vencimiento de un elemento, mantenga el cursor del ratón sobre el atributo. 

## Activación del TTL de DynamoDB mediante la API
<a name="time-to-live-ttl-how-to-enable-api"></a>

------
#### [ Python ]

Puede activar el TTL con código con la operación [UpdateTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/update_time_to_live.html).

```
import boto3


def enable_ttl(table_name, ttl_attribute_name):
    """
    Enables TTL on DynamoDB table for a given attribute name
        on success, returns a status code of 200
        on error, throws an exception

    :param table_name: Name of the DynamoDB table
    :param ttl_attribute_name: The name of the TTL attribute being provided to the table.
    """
    try:
        dynamodb = boto3.client('dynamodb')

        # Enable TTL on an existing DynamoDB table
        response = dynamodb.update_time_to_live(
            TableName=table_name,
            TimeToLiveSpecification={
                'Enabled': True,
                'AttributeName': ttl_attribute_name
            }
        )

        # In the returned response, check for a successful status code.
        if response['ResponseMetadata']['HTTPStatusCode'] == 200:
            print("TTL has been enabled successfully.")
        else:
            print(f"Failed to enable TTL, status code {response['ResponseMetadata']['HTTPStatusCode']}")
    except Exception as ex:
        print("Couldn't enable TTL in table %s. Here's why: %s" % (table_name, ex))
        raise


# your values
enable_ttl('your-table-name', 'expirationDate')
```

Puede confirmar que el TTL está activado mediante la operación [DescribeTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/describe_time_to_live.html), que describe el estado del TTL en una tabla. El estado de `TimeToLive` es `ENABLED` o `DISABLED`.

```
# create a DynamoDB client
dynamodb = boto3.client('dynamodb')

# set the table name
table_name = 'YourTable'

# describe TTL
response = dynamodb.describe_time_to_live(TableName=table_name)
```

------
#### [ JavaScript ]

Puede activar el TTL con código con la operación [UpdateTimeToLiveCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-dynamodb/Class/UpdateTimeToLiveCommand/).

```
import { DynamoDBClient, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";

const enableTTL = async (tableName, ttlAttribute) => {

    const client = new DynamoDBClient({});

    const params = {
        TableName: tableName,
        TimeToLiveSpecification: {
            Enabled: true,
            AttributeName: ttlAttribute
        }
    };

    try {
        const response = await client.send(new UpdateTimeToLiveCommand(params));
        if (response.$metadata.httpStatusCode === 200) {
            console.log(`TTL enabled successfully for table ${tableName}, using attribute name ${ttlAttribute}.`);
        } else {
            console.log(`Failed to enable TTL for table ${tableName}, response object: ${response}`);
        }
        return response;
    } catch (e) {
        console.error(`Error enabling TTL: ${e}`);
        throw e;
    }
};

// call with your own values
enableTTL('ExampleTable', 'exampleTtlAttribute');
```

------

## Activación del tiempo de vida mediante la AWS CLI
<a name="time-to-live-ttl-how-to-enable-cli-sdk"></a>

1. Habilite TTL en la tabla `TTLExample`.

   ```
   aws dynamodb update-time-to-live --table-name TTLExample --time-to-live-specification "Enabled=true, AttributeName=ttl"
   ```

1. Describa TTL en la tabla `TTLExample`.

   ```
   aws dynamodb describe-time-to-live --table-name TTLExample
   {
       "TimeToLiveDescription": {
           "AttributeName": "ttl",
           "TimeToLiveStatus": "ENABLED"
       }
   }
   ```

1. Añada un elemento a la tabla `TTLExample` con el atributo de período de vida establecido utilizando el shell de BASH y la AWS CLI. 

   ```
   EXP=`date -d '+5 days' +%s`
   aws dynamodb put-item --table-name "TTLExample" --item '{"id": {"N": "1"}, "ttl": {"N": "'$EXP'"}}'
   ```

Este ejemplo comienza con la fecha actual y añade cinco días para crear una fecha de vencimiento. A continuación, convierte la fecha de vencimiento al formato de tiempo Unix y, por último, agrega un elemento a la tabla "`TTLExample`". 

**nota**  
 Una forma de establecer valores de vencimiento para período de vida consiste en calcular el número de segundos que se sumarán al momento del vencimiento. Por ejemplo, 5 días son 432 000 segundos. Sin embargo, a menudo es preferible comenzar por una fecha y tomarla como punto de partida.

Es bastante sencillo obtener el tiempo actual en formato de tiempo Unix, como en los siguientes ejemplos.
+ Terminal Linux: `date +%s`
+ Python: `import time; int(time.time())`
+ Java: `System.currentTimeMillis() / 1000L`
+ JavaScript: : `Math.floor(Date.now() / 1000)`

## Activación del TTL de DynamoDB mediante CloudFormation
<a name="time-to-live-ttl-how-to-enable-cf"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  TTLExampleTable:
    Type: AWS::DynamoDB::Table
    Description: "A DynamoDB table with TTL Specification enabled"
    Properties:
      AttributeDefinitions:
        - AttributeName: "Album"
          AttributeType: "S"
        - AttributeName: "Artist"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "Album"
          KeyType: "HASH"
        - AttributeName: "Artist"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TimeToLiveSpecification:
        AttributeName: "TTLExampleAttribute"
        Enabled: true
```

Puede encontrar [aquí](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-timetolivespecification.html) más información sobre el uso del TTL en las plantillas de CloudFormation.

# Período de vida (TTL) de computación en DynamoDB
<a name="time-to-live-ttl-before-you-start"></a>

Una forma habitual de implementar el TTL consiste en establecer una fecha de vencimiento para los elementos en función de cuándo se crearon o se actualizaron por última vez. Esto se puede hacer añadiendo la hora a las marcas de tiempo `createdAt` y `updatedAt`. Por ejemplo, el TTL de los elementos que se acaban de crear se puede establecer en `createdAt` más 90 días. Cuando se actualiza el elemento, el TTL se puede volver a calcular como `updatedAt` más de 90 días.

El tiempo de vencimiento calculado debe estar en formato Epoch, expresado en segundos. Para que se tenga en cuenta el vencimiento y la eliminación, el TTL no puede tener más de cinco años de antigüedad. Si utiliza cualquier otro formato, los procesos de TTL ignoran el elemento. Si establece la fecha de vencimiento en algún momento futuro en el que desee que el artículo caduque, este caducará una vez transcurrido ese plazo. Por ejemplo, supongamos que establece la fecha de vencimiento en 1724241326 (que corresponde al lunes 21 de agosto de 2024 a las 11:55:26 [UTC]). El elemento vence cuando se alcanza la fecha especificada. No hay una duración mínima de TTL. Puede establecer la fecha de vencimiento en cualquier momento futuro, por ejemplo, 5 minutos a partir de la hora actual. Sin embargo, DynamoDB suele eliminar los elementos caducados en un plazo de 48 horas tras su fecha de vencimiento, y no inmediatamente después de que caduquen.

**Topics**
+ [

## Creación de un elemento y determinación del tiempo de vida
](#time-to-live-ttl-before-you-start-create)
+ [

## Actualización de un elemento y del tiempo de vida
](#time-to-live-ttl-before-you-start-update)

## Creación de un elemento y determinación del tiempo de vida
<a name="time-to-live-ttl-before-you-start-create"></a>

En el siguiente ejemplo se muestra cómo calcular el tiempo de vencimiento al crear un elemento nuevo, utilizando `expireAt` como nombre de atributo TTL. Una instrucción de asignación obtiene la hora actual como variable. En el ejemplo, la fecha de vencimiento se calcula en 90 días a partir de la fecha actual. A continuación, la fecha se convierte al formato Epoch y se guarda como un tipo de dato entero en el atributo TTL.

Los siguientes ejemplos de código muestran cómo crear un elemento con TTL.

------
#### [ Java ]

**SDK para Java 2.x**  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Creates an item in a DynamoDB table with TTL attributes.
 * This class demonstrates how to add TTL expiration timestamps to DynamoDB items.
 */
public class CreateTTL {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String CREATION_DATE_ATTR = "creationDate";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String SUCCESS_MESSAGE = "%s PutItem operation with TTL successful.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs a CreateTTL instance with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public CreateTTL(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Constructs a CreateTTL with a default DynamoDB client.
     */
    public CreateTTL() {
        this.dynamoDbClient = null;
    }

    /**
     * Main method to demonstrate creating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new CreateTTL().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and create an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final CreateTTL createTTL = new CreateTTL(ddb);
            createTTL.createItemWithTTL(tableName, primaryKey, sortKey);
            return 0;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * Creates an item in the specified table with TTL attributes.
     *
     * @param tableName The name of the table
     * @param primaryKeyValue The value for the primary key
     * @param sortKeyValue The value for the sort key
     * @return The response from the PutItem operation
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     */
    public PutItemResponse createItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long createDate = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = createDate + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        final Map<String, AttributeValue> itemMap = new HashMap<>();
        itemMap.put(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        itemMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());
        itemMap.put(
            CREATION_DATE_ATTR,
            AttributeValue.builder().n(String.valueOf(createDate)).build());
        itemMap.put(
            EXPIRE_AT_ATTR,
            AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final PutItemRequest request =
            PutItemRequest.builder().tableName(tableName).item(itemMap).build();

        try {
            final PutItemResponse response = dynamoDbClient.putItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  Para obtener información sobre la API, consulte [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem) en la *referencia de la API de AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  

```
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";

export function createDynamoDBItem(table_name, region, partition_key, sort_key) {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    // Get the current time in epoch second format
    const current_time = Math.floor(new Date().getTime() / 1000);

    // Calculate the expireAt time (90 days from now) in epoch second format
    const expire_at = Math.floor((new Date().getTime() + 90 * 24 * 60 * 60 * 1000) / 1000);

    // Create DynamoDB item
    const item = {
        'partitionKey': {'S': partition_key},
        'sortKey': {'S': sort_key},
        'createdAt': {'N': current_time.toString()},
        'expireAt': {'N': expire_at.toString()}
    };

    const putItemCommand = new PutItemCommand({
        TableName: table_name,
        Item: item,
        ProvisionedThroughput: {
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    });

    client.send(putItemCommand, function(err, data) {
        if (err) {
            console.log("Exception encountered when creating item %s, here's what happened: ", data, err);
            throw err;
        } else {
            console.log("Item created successfully: %s.", data);
            return data;
        }
    });
}

// Example usage (commented out for testing)
// createDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');
```
+  Para obtener información sobre la API, consulte [PutItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/PutItemCommand) en la *referencia de la API de AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def create_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Creates a DynamoDB item with an attached expiry attribute.

    :param table_name: Table name for the boto3 resource to target when creating an item
    :param region: string representing the AWS region. Example: `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expiration time (90 days from now) in epoch second format
        expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        item = {
            "primaryKey": primary_key,
            "sortKey": sort_key,
            "creationDate": current_time,
            "expireAt": expiration_time,
        }
        response = table.put_item(Item=item)

        print("Item created successfully.")
        return response
    except Exception as e:
        print(f"Error creating item: {e}")
        raise e


# Use your own values
create_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Para obtener información sobre la API, consulte [PutItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

## Actualización de un elemento y del tiempo de vida
<a name="time-to-live-ttl-before-you-start-update"></a>

Este ejemplo es la continuación del que aparece en la [sección anterior](#time-to-live-ttl-before-you-start-create). La fecha de vencimiento se puede volver a calcular si se actualiza el elemento. En el siguiente ejemplo, se vuelve a calcular la marca de tiempo `expireAt` para que sea de 90 días a partir de la fecha actual.

En los siguientes ejemplos de código, se muestra cómo actualizar el TTL de un elemento.

------
#### [ Java ]

**SDK para Java 2.x**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

    public UpdateItemResponse updateItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = new HashMap<>();
        keyMap.put(PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        keyMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build());
        expressionAttributeValues.put(
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try {
            final UpdateItemResponse response = dynamoDbClient.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItem = async (tableName, partitionKey, sortKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);
    const expireAt = Math.floor((Date.now() + 90 * 24 * 60 * 60 * 1000) / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            partitionKey: partitionKey,
            sortKey: sortKey
        }),
        UpdateExpression: "SET updatedAt = :c, expireAt = :e",
        ExpressionAttributeValues: marshall({
            ":c": currentTime,
            ":e": expireAt
        }),
    };

    try {
        const data = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(data.Attributes);
        console.log("Item updated successfully: %s", responseData);
        return responseData;
    } catch (err) {
        console.error("Error updating item:", err);
        throw err;
    }
}

// Example usage (commented out for testing)
// updateItem('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand) en la *referencia de la API de AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def update_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Update an existing DynamoDB item with a TTL.
    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        # Create the DynamoDB resource.
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expireAt time (90 days from now) in epoch second format
        expire_at = int((datetime.now() + timedelta(days=90)).timestamp())

        table.update_item(
            Key={"partitionKey": primary_key, "sortKey": sort_key},
            UpdateExpression="set updatedAt=:c, expireAt=:e",
            ExpressionAttributeValues={":c": current_time, ":e": expire_at},
        )

        print("Item updated successfully.")
    except Exception as e:
        print(f"Error updating item: {e}")


# Replace with your own values
update_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Para obtener información la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

Los ejemplos de TTL que se analizan en esta introducción muestran un método para garantizar que en la tabla solo se guarden los elementos actualizados recientemente. La vida útil de los elementos actualizados se prolonga, mientras que los que no se actualizan tras su creación caducan y se eliminan sin costo alguno, lo que reduce el almacenamiento y mantiene las tablas limpias.

# Uso de elementos caducados y el período de vida (TTL)
<a name="ttl-expired-items"></a>

Los elementos vencidos que aún deben eliminarse se pueden filtrar de las operaciones de lectura y escritura. Esto resulta útil en situaciones en las que los datos vencidos ya no son válidos y no deben utilizarse. Si no están filtrados, seguirán mostrándose en las operaciones de lectura y escritura hasta que se eliminen en el proceso en segundo plano.

**nota**  
Estos elementos seguirán contabilizándose para los costos de almacenamiento y lectura hasta que se eliminen.

Las eliminaciones de TTL se pueden identificar en DynamoDB Streams, pero solo en la región en la que se han eliminado. Las eliminaciones de TTL que se replican en las regiones de la tabla global no se pueden identificar en las transmisiones de DynamoDB de las regiones en las que se replica la eliminación.

## Filtrado de los elementos vencidos de las operaciones de lectura
<a name="ttl-expired-items-filter"></a>

Para las operaciones de lectura, como [Scan](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) y [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html), una expresión de filtro puede filtrar los elementos vencidos que aún no se han eliminado. Como se muestra en el siguiente fragmento de código, la expresión de filtro puede filtrar los elementos en los que el tiempo de TTL sea igual o inferior al tiempo actual. Por ejemplo, el código del SDK de Python incluye una declaración de asignación que obtiene la hora actual como una variable (`now`) y la convierte en `int` para el formato de tiempo Epoch.

En los siguientes ejemplos de código, se muestra cómo consultar elementos de TTL.

------
#### [ Java ]

**SDK para Java 2.x**  
Consulte una expresión filtrada para recopilar elementos de TTL en una tabla de DynamoDB mediante AWS SDK for Java 2.x.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.Map;
import java.util.Optional;

        final QueryRequest request = QueryRequest.builder()
            .tableName(tableName)
            .keyConditionExpression(KEY_CONDITION_EXPRESSION)
            .filterExpression(FILTER_EXPRESSION)
            .expressionAttributeNames(expressionAttributeNames)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final QueryResponse response = ddb.query(request);
            System.out.println("Query successful. Found " + response.count() + " items that have not expired yet.");

            // Print each item
            response.items().forEach(item -> {
                System.out.println("Item: " + item);
            });

            return 0;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
```
+  Para obtener información sobre la API, consulte [Query](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/Query) en la *referencia de la API de AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
Consulte una expresión filtrada para recopilar elementos de TTL en una tabla de DynamoDB mediante AWS SDK para JavaScript.  

```
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const queryFiltered = async (tableName, primaryKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        KeyConditionExpression: "#pk = :pk",
        FilterExpression: "#ea > :ea",
        ExpressionAttributeNames: {
            "#pk": "primaryKey",
            "#ea": "expireAt"
        },
        ExpressionAttributeValues: marshall({
            ":pk": primaryKey,
            ":ea": currentTime
        })
    };

    try {
        const { Items } = await client.send(new QueryCommand(params));
        Items.forEach(item => {
            console.log(unmarshall(item))
        });
        return Items;
    } catch (err) {
        console.error(`Error querying items: ${err}`);
        throw err;
    }
}

// Example usage (commented out for testing)
// queryFiltered('your-table-name', 'your-partition-key-value');
```
+  Para obtener información sobre la API, consulte [Query](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/QueryCommand) en la *referencia de la API de AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3)**  
Consulte una expresión filtrada para recopilar elementos de TTL en una tabla de DynamoDB mediante AWS SDK para Python (Boto3).  

```
from datetime import datetime

import boto3


def query_dynamodb_items(table_name, partition_key):
    """

    :param table_name: Name of the DynamoDB table
    :param partition_key:
    :return:
    """
    try:
        # Initialize a DynamoDB resource
        dynamodb = boto3.resource("dynamodb", region_name="us-east-1")

        # Specify your table
        table = dynamodb.Table(table_name)

        # Get the current time in epoch format
        current_time = int(datetime.now().timestamp())

        # Perform the query operation with a filter expression to exclude expired items
        # response = table.query(
        #    KeyConditionExpression=boto3.dynamodb.conditions.Key('partitionKey').eq(partition_key),
        #    FilterExpression=boto3.dynamodb.conditions.Attr('expireAt').gt(current_time)
        # )
        response = table.query(
            KeyConditionExpression=dynamodb.conditions.Key("partitionKey").eq(partition_key),
            FilterExpression=dynamodb.conditions.Attr("expireAt").gt(current_time),
        )

        # Print the items that are not expired
        for item in response["Items"]:
            print(item)

    except Exception as e:
        print(f"Error querying items: {e}")


# Call the function with your values
query_dynamodb_items("Music", "your-partition-key-value")
```
+  Para obtener información sobre la API, consulte [Query](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/Query) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

## Escritura condicional en los elementos vencidos
<a name="ttl-expired-items-conditional-write"></a>

Se puede usar una expresión condicional para evitar escrituras en los elementos vencidos. El siguiente fragmento de código es una actualización condicional que comprueba si el tiempo de vencimiento es superior al tiempo actual. Si es verdadero, la operación de escritura continuará.

En los siguientes ejemplos de código se muestra cómo actualizar de forma condicional el TTL de un elemento.

------
#### [ Java ]

**SDK para Java 2.x**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla con una condición.  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.Map;
import java.util.Optional;

/**
 * Updates an item in a DynamoDB table with TTL attributes using a conditional expression.
 * This class demonstrates how to conditionally update TTL expiration timestamps.
 */
public class UpdateTTLConditional {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String UPDATED_AT_ATTR = "updatedAt";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e";
    private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")";
    private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful.";
    private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs an UpdateTTLConditional with a default DynamoDB client.
     */
    public UpdateTTLConditional() {
        this.dynamoDbClient = null;
    }

    /**
     * Constructs an UpdateTTLConditional with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Main method to demonstrate conditionally updating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new UpdateTTLConditional().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and conditionally update an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = Map.of(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(),
            SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = Map.of(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(),
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .conditionExpression(CONDITION_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final UpdateItemResponse response = ddb.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return 0;
        } catch (ConditionalCheckFailedException e) {
            System.err.println(CONDITION_FAILED_MESSAGE);
            throw e;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla con una condición.  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItemConditional = async (tableName, partitionKey, sortKey, region = 'us-east-1', newAttribute = 'default-value') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            artist: partitionKey,
            album: sortKey
        }),
        UpdateExpression: "SET newAttribute = :newAttribute",
        ConditionExpression: "expireAt > :expiration",
        ExpressionAttributeValues: marshall({
            ':newAttribute': newAttribute,
            ':expiration': currentTime
        }),
        ReturnValues: "ALL_NEW"
    };

    try {
        const response = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(response.Attributes);
        console.log("Item updated successfully: ", responseData);
        return responseData;
    } catch (error) {
        if (error.name === "ConditionalCheckFailedException") {
            console.log("Condition check failed: Item's 'expireAt' is expired.");
        } else {
            console.error("Error updating item: ", error);
        }
        throw error;
    }
};

// Example usage (commented out for testing)
// updateItemConditional('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand) en la *referencia de la API de AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3)**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla con una condición.  

```
from datetime import datetime, timedelta

import boto3
from botocore.exceptions import ClientError


def update_dynamodb_item_ttl(table_name, region, primary_key, sort_key, ttl_attribute):
    """
    Updates an existing record in a DynamoDB table with a new or updated TTL attribute.

    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :param ttl_attribute: name of the TTL attribute in the target DynamoDB table
    :return:
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Generate updated TTL in epoch second format
        updated_expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        # Define the update expression for adding/updating a new attribute
        update_expression = "SET newAttribute = :val1"

        # Define the condition expression for checking if 'expireAt' is not expired
        condition_expression = "expireAt > :val2"

        # Define the expression attribute values
        expression_attribute_values = {":val1": ttl_attribute, ":val2": updated_expiration_time}

        response = table.update_item(
            Key={"primaryKey": primary_key, "sortKey": sort_key},
            UpdateExpression=update_expression,
            ConditionExpression=condition_expression,
            ExpressionAttributeValues=expression_attribute_values,
        )

        print("Item updated successfully.")
        return response["ResponseMetadata"]["HTTPStatusCode"]  # Ideally a 200 OK
    except ClientError as e:
        if e.response["Error"]["Code"] == "ConditionalCheckFailedException":
            print("Condition check failed: Item's 'expireAt' is expired.")
        else:
            print(f"Error updating item: {e}")
    except Exception as e:
        print(f"Error updating item: {e}")


# replace with your values
update_dynamodb_item_ttl(
    "your-table-name",
    "us-east-1",
    "your-partition-key-value",
    "your-sort-key-value",
    "your-ttl-attribute-value",
)
```
+  Para obtener información la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

## Identificación de elementos eliminados en DynamoDB Streams
<a name="ttl-expired-items-identifying"></a>

El registro de secuencias contiene el campo de identidad del usuario `Records[<index>].userIdentity`. Los elementos que elimina el proceso TTL tienen los campos siguientes:

```
Records[<index>].userIdentity.type
"Service"

Records[<index>].userIdentity.principalId
"dynamodb.amazonaws.com"
```

En el código JSON siguiente se muestra la parte pertinente de un registro de secuencias único:

```
"Records": [ 
  { 
	... 
		"userIdentity": {
		"type": "Service", 
      	"principalId": "dynamodb.amazonaws.com" 
   	} 
   ... 
	} 
]
```