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 partitioning schema. This guide focuses on two capabilities: retention configuration (default and custom) and custom partition keys 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 by creating a table with 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", ×treamwrite.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
The databaseName property references an existing Timestream database. The tableName property sets the table’s identifier. Without explicit retentionProperties, Timestream uses defaults: 73,000 days (200 years) for magnetic storage and 6 hours for memory storage.
Configure custom retention periods and tags
Applications with specific cost or compliance requirements control how long data remains in fast memory storage versus cheaper magnetic storage.
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", ×treamwrite.TableArgs{
DatabaseName: pulumi.Any(exampleAwsTimestreamwriteDatabase.DatabaseName),
TableName: pulumi.String("example"),
RetentionProperties: ×treamwrite.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 defines two storage tiers. The memoryStoreRetentionPeriodInHours controls how long recent data stays in fast, expensive memory (8 hours here). After that window, data moves to magneticStoreRetentionPeriodInDays (30 days here), which is slower but cheaper. Queries against memory storage are faster; queries against magnetic storage cost less but take longer.
Define a custom partition key for query optimization
High-cardinality workloads benefit from custom 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", ×treamwrite.TableArgs{
DatabaseName: pulumi.Any(exampleAwsTimestreamwriteDatabase.DatabaseName),
TableName: pulumi.String("example"),
Schema: ×treamwrite.TableSchemaArgs{
CompositePartitionKey: ×treamwrite.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 (time-series value). The enforcementInRecord property set to REQUIRED means every ingested record must include the attr1 dimension. Queries filtering on attr1 scan less data, improving performance and reducing costs.
Beyond these examples
These snippets focus on specific table-level features: table creation and naming, retention tier configuration, and custom partition keys. They’re intentionally minimal rather than full time-series solutions.
The examples reference pre-existing infrastructure such as Timestream databases (databaseName references). 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
- Schema enforcement modes beyond REQUIRED
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 FREEFrequently Asked Questions
Configuration & Immutability
databaseName, tableName, and schema properties are immutable. Changing any of these forces table replacement.magneticStoreRetentionPeriodInDays defaults to 73000 days (~200 years) and memoryStoreRetentionPeriodInHours defaults to 6 hours.Advanced Features
schema.compositePartitionKey property with enforcementInRecord, name, and type fields. For example, set type to DIMENSION and enforcementInRecord to REQUIRED.Import & Migration
tableName:databaseName with the import command. For example: pulumi import aws:timestreamwrite/table:Table example ExampleTable:ExampleDatabase.