State Time-to-Live (TTL)

Manage state with TTL.

Dapr enables per state set request time-to-live (TTL). This means that applications can set time-to-live per state stored, and these states cannot be retrieved after expiration.

For supported state stores, you simply set the ttlInSeconds metadata when publishing a message. Other state stores will ignore this value. For some state stores, you can specify a default expiration on a per-table/container basis.

Native state TTL support

When state TTL has native support in the state store component, Dapr forwards the TTL configuration without adding any extra logic, maintaining predictable behavior. This is helpful when the expired state is handled differently by the component.

When a TTL is not specified, the default behavior of the state store is retained.

Persisting state (ignoring an existing TTL)

To explicitly persist a state (ignoring any TTLs set for the key), specify a ttlInSeconds value of -1.

Supported components

Refer to the TTL column in the state store components guide.

Example

You can set state TTL in the metadata as part of the state store set request:

  1. #dependencies
  2. from dapr.clients import DaprClient
  3. #code
  4. DAPR_STORE_NAME = "statestore"
  5. with DaprClient() as client:
  6. client.save_state(DAPR_STORE_NAME, "order_1", str(orderId), state_metadata={
  7. 'ttlInSeconds': '120'
  8. })

To launch a Dapr sidecar and run the above example application, you’d then run a command similar to the following:

  1. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
  1. // dependencies
  2. using Dapr.Client;
  3. // code
  4. await client.SaveStateAsync(storeName, stateKeyName, state, metadata: new Dictionary<string, string>() {
  5. {
  6. "metadata.ttlInSeconds", "120"
  7. }
  8. });

To launch a Dapr sidecar and run the above example application, you’d then run a command similar to the following:

  1. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 dotnet run
  1. // dependencies
  2. import (
  3. dapr "github.com/dapr/go-sdk/client"
  4. )
  5. // code
  6. md := map[string]string{"ttlInSeconds": "120"}
  7. if err := client.SaveState(ctx, store, "key1", []byte("hello world"), md); err != nil {
  8. panic(err)
  9. }

To launch a Dapr sidecar and run the above example application, you’d then run a command similar to the following:

  1. dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run .
  1. curl -X POST -H "Content-Type: application/json" -d '[{ "key": "order_1", "value": "250", "metadata": { "ttlInSeconds": "120" } }]' http://localhost:3601/v1.0/state/statestore
  1. Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '[{"key": "order_1", "value": "250", "metadata": {"ttlInSeconds": "120"}}]' -Uri 'http://localhost:3601/v1.0/state/statestore'

Last modified June 19, 2023: Merge pull request #3565 from dapr/aacrawfi/skip-secrets-close (b1763bf)