Create AWS Timestream Tables

The aws:timestreamwrite/table:Table resource, part of the Pulumi AWS provider, defines a Timestream table within a database: its name, retention policies, and optional partition schema. This guide focuses on two capabilities: retention configuration (default and custom) and partition key schema for query optimization.

Timestream tables belong to Timestream databases that must exist before table creation. The examples are intentionally small. Combine them with your own database resources and ingestion pipelines.

Create a table with default retention

Most deployments start with minimal configuration, relying on AWS-managed retention defaults.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.timestreamwrite.Table("example", {
    databaseName: exampleAwsTimestreamwriteDatabase.databaseName,
    tableName: "example",
});
import pulumi
import pulumi_aws as aws

example = aws.timestreamwrite.Table("example",
    database_name=example_aws_timestreamwrite_database["databaseName"],
    table_name="example")
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/timestreamwrite"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := timestreamwrite.NewTable(ctx, "example", &timestreamwrite.TableArgs{
			DatabaseName: pulumi.Any(exampleAwsTimestreamwriteDatabase.DatabaseName),
			TableName:    pulumi.String("example"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.TimestreamWrite.Table("example", new()
    {
        DatabaseName = exampleAwsTimestreamwriteDatabase.DatabaseName,
        TableName = "example",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.timestreamwrite.Table;
import com.pulumi.aws.timestreamwrite.TableArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Table("example", TableArgs.builder()
            .databaseName(exampleAwsTimestreamwriteDatabase.databaseName())
            .tableName("example")
            .build());

    }
}
resources:
  example:
    type: aws:timestreamwrite:Table
    properties:
      databaseName: ${exampleAwsTimestreamwriteDatabase.databaseName}
      tableName: example

When you omit retentionProperties, Timestream applies defaults: 6 hours in memory storage (fast queries on recent data) and 73,000 days in magnetic storage (cost-effective long-term retention). The databaseName property links the table to its parent database.

Configure custom retention periods

Applications with specific lifecycle requirements control how long data stays in each storage tier.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.timestreamwrite.Table("example", {
    databaseName: exampleAwsTimestreamwriteDatabase.databaseName,
    tableName: "example",
    retentionProperties: {
        magneticStoreRetentionPeriodInDays: 30,
        memoryStoreRetentionPeriodInHours: 8,
    },
    tags: {
        Name: "example-timestream-table",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.timestreamwrite.Table("example",
    database_name=example_aws_timestreamwrite_database["databaseName"],
    table_name="example",
    retention_properties={
        "magnetic_store_retention_period_in_days": 30,
        "memory_store_retention_period_in_hours": 8,
    },
    tags={
        "Name": "example-timestream-table",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/timestreamwrite"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := timestreamwrite.NewTable(ctx, "example", &timestreamwrite.TableArgs{
			DatabaseName: pulumi.Any(exampleAwsTimestreamwriteDatabase.DatabaseName),
			TableName:    pulumi.String("example"),
			RetentionProperties: &timestreamwrite.TableRetentionPropertiesArgs{
				MagneticStoreRetentionPeriodInDays: pulumi.Int(30),
				MemoryStoreRetentionPeriodInHours:  pulumi.Int(8),
			},
			Tags: pulumi.StringMap{
				"Name": pulumi.String("example-timestream-table"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.TimestreamWrite.Table("example", new()
    {
        DatabaseName = exampleAwsTimestreamwriteDatabase.DatabaseName,
        TableName = "example",
        RetentionProperties = new Aws.TimestreamWrite.Inputs.TableRetentionPropertiesArgs
        {
            MagneticStoreRetentionPeriodInDays = 30,
            MemoryStoreRetentionPeriodInHours = 8,
        },
        Tags = 
        {
            { "Name", "example-timestream-table" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.timestreamwrite.Table;
import com.pulumi.aws.timestreamwrite.TableArgs;
import com.pulumi.aws.timestreamwrite.inputs.TableRetentionPropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Table("example", TableArgs.builder()
            .databaseName(exampleAwsTimestreamwriteDatabase.databaseName())
            .tableName("example")
            .retentionProperties(TableRetentionPropertiesArgs.builder()
                .magneticStoreRetentionPeriodInDays(30)
                .memoryStoreRetentionPeriodInHours(8)
                .build())
            .tags(Map.of("Name", "example-timestream-table"))
            .build());

    }
}
resources:
  example:
    type: aws:timestreamwrite:Table
    properties:
      databaseName: ${exampleAwsTimestreamwriteDatabase.databaseName}
      tableName: example
      retentionProperties:
        magneticStoreRetentionPeriodInDays: 30
        memoryStoreRetentionPeriodInHours: 8
      tags:
        Name: example-timestream-table

The retentionProperties block sets memoryStoreRetentionPeriodInHours (how long data remains in fast memory) and magneticStoreRetentionPeriodInDays (how long data persists in cost-effective magnetic storage). Here, data moves from memory to magnetic storage after 8 hours and is deleted after 30 days. This balances query performance on recent data with storage costs.

Define a custom partition key for query optimization

High-cardinality workloads benefit from partition keys that align with query patterns.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.timestreamwrite.Table("example", {
    databaseName: exampleAwsTimestreamwriteDatabase.databaseName,
    tableName: "example",
    schema: {
        compositePartitionKey: {
            enforcementInRecord: "REQUIRED",
            name: "attr1",
            type: "DIMENSION",
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.timestreamwrite.Table("example",
    database_name=example_aws_timestreamwrite_database["databaseName"],
    table_name="example",
    schema={
        "composite_partition_key": {
            "enforcement_in_record": "REQUIRED",
            "name": "attr1",
            "type": "DIMENSION",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/timestreamwrite"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := timestreamwrite.NewTable(ctx, "example", &timestreamwrite.TableArgs{
			DatabaseName: pulumi.Any(exampleAwsTimestreamwriteDatabase.DatabaseName),
			TableName:    pulumi.String("example"),
			Schema: &timestreamwrite.TableSchemaArgs{
				CompositePartitionKey: &timestreamwrite.TableSchemaCompositePartitionKeyArgs{
					EnforcementInRecord: pulumi.String("REQUIRED"),
					Name:                pulumi.String("attr1"),
					Type:                pulumi.String("DIMENSION"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.TimestreamWrite.Table("example", new()
    {
        DatabaseName = exampleAwsTimestreamwriteDatabase.DatabaseName,
        TableName = "example",
        Schema = new Aws.TimestreamWrite.Inputs.TableSchemaArgs
        {
            CompositePartitionKey = new Aws.TimestreamWrite.Inputs.TableSchemaCompositePartitionKeyArgs
            {
                EnforcementInRecord = "REQUIRED",
                Name = "attr1",
                Type = "DIMENSION",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.timestreamwrite.Table;
import com.pulumi.aws.timestreamwrite.TableArgs;
import com.pulumi.aws.timestreamwrite.inputs.TableSchemaArgs;
import com.pulumi.aws.timestreamwrite.inputs.TableSchemaCompositePartitionKeyArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Table("example", TableArgs.builder()
            .databaseName(exampleAwsTimestreamwriteDatabase.databaseName())
            .tableName("example")
            .schema(TableSchemaArgs.builder()
                .compositePartitionKey(TableSchemaCompositePartitionKeyArgs.builder()
                    .enforcementInRecord("REQUIRED")
                    .name("attr1")
                    .type("DIMENSION")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:timestreamwrite:Table
    properties:
      databaseName: ${exampleAwsTimestreamwriteDatabase.databaseName}
      tableName: example
      schema:
        compositePartitionKey:
          enforcementInRecord: REQUIRED
          name: attr1
          type: DIMENSION

The schema block defines a compositePartitionKey that Timestream uses to organize data physically. The type property specifies whether the key comes from a DIMENSION (metadata attribute) or MEASURE (numeric value). Setting enforcementInRecord to REQUIRED ensures every ingested record includes the partition key, preventing write failures. Custom partition keys reduce the data scanned per query when filters match the partition dimension.

Beyond these examples

These snippets focus on specific table-level features: table creation and naming, retention tier configuration, and partition key schema definition. They’re intentionally minimal rather than full time-series solutions.

The examples reference pre-existing infrastructure such as Timestream databases (via databaseName). They focus on configuring the table rather than provisioning the surrounding database or ingestion infrastructure.

To keep things focused, common table patterns are omitted, including:

  • Magnetic store write properties (magneticStoreWriteProperties)
  • Multi-attribute composite partition keys
  • Tag-based organization and cost tracking

These omissions are intentional: the goal is to illustrate how each table feature is wired, not provide drop-in time-series modules. See the Timestream Table resource reference for all available configuration options.

Let's create AWS Timestream Tables

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Immutability
What properties can't I change after creating a Timestream table?
The databaseName, tableName, and schema properties are immutable. Changing any of these requires replacing the table.
What are the default retention periods for Timestream tables?
If not specified, magneticStoreRetentionPeriodInDays defaults to 73000 days and memoryStoreRetentionPeriodInHours defaults to 6 hours.
Data Retention & Storage
What's the difference between memory store and magnetic store retention?
Memory store holds recent data (default 6 hours) for fast queries, while magnetic store holds historical data (default 73000 days) for long-term storage. Configure both using retentionProperties.
Advanced Features
How do I configure a custom partition key for my table?
Set schema.compositePartitionKey with enforcementInRecord, name, and type properties. For example, use type: "DIMENSION" and enforcementInRecord: "REQUIRED" to enforce partition key presence.
Import & Migration
How do I import an existing Timestream table into Pulumi?
Use the format table_name:database_name (colon-separated) with pulumi import. For example: pulumi import aws:timestreamwrite/table:Table example ExampleTable:ExampleDatabase.

Using a different cloud?

Explore database guides for other cloud providers: