Multi-tenant DynamoDB tables create a common operational problem.
Imagine one table contains data for hundreds or thousands of customers:
Tenant A
Tenant B
Tenant C
...
Tenant 1000Now one customer asks for a copy of its data.
Or a deployment corrupts records for one tenant and the engineering team needs to recover only that customer's data.
Before filtered export, the practical options were often much broader. Teams could export the whole table and filter the data afterward, or write application code to read the tenant's records and copy them somewhere else.
Amazon DynamoDB now supports filtered export to Amazon S3, allowing developers to select the items and attributes that should be included in an export. The feature works with both full and incremental exports and uses DynamoDB's point-in-time recovery data rather than consuming table read capacity.
That changes the workflow considerably.
Instead of:
4 TB DynamoDB Table
|
v
Full Export
|
v
Filter Tenant Data
|
v
Desired Datasetyou can request:
DynamoDB Table
|
v
Filtered Export
|
+-- Tenant Condition
+-- Attribute Filter
+-- Attribute Projection
|
v
Amazon S3
|
v
Only Required DataFor multi-tenant systems, this can be useful for recovery, data sharing, tenant migration, compliance workflows, and analytics.
What Is DynamoDB Filtered Export?
DynamoDB export to Amazon S3 already allows full and incremental exports.
A full export captures table data as it existed at a selected point in time within the point-in-time recovery window.
An incremental export captures changes within a specified time window.
Filtered export adds another layer:
Export
|
+-- Which items?
|
+-- Which attributes?
|
+-- Which point in time?AWS introduced filtered export in October 2026. It allows a FilterSpecification to define:
KeyConditionExpressionFilterExpressionProjectionExpressionExpressionAttributeNamesExpressionAttributeValues
These expressions determine which items qualify and which attributes are written to S3.
Why This Matters for Multi-Tenant Applications
Consider a SaaS application with this table:
CustomerData
--------------------------------
TenantId
RecordId
Type
Status
CreatedAt
CustomerName
Email
Address
PaymentInformationSuppose the table contains:
Tenant A -> 500 GB
Tenant B -> 300 GB
Tenant C -> 200 GB
...
Total -> 4 TBA customer wants its data exported.
A full export would include every tenant.
The application would then need to identify the requested tenant's records.
Filtered export lets the export itself select the tenant.
Conceptually:
KeyConditionExpression
|
v
TenantId = "tenant-123"
|
v
Only matching partitionThis is especially useful when the tenant identifier is part of the DynamoDB partition-key design.
How Filtered Export Works
There are three important filtering concepts.
Key Condition
The key condition identifies the partition to export.
For example:
TenantId = "tenant-123"A key condition follows DynamoDB Query-style rules. It can specify one partition-key value and optionally a condition on the sort key.
Filter Expression
A filter expression can further restrict which items are included.
For example:
Status = "ACTIVE"This allows the export to select items based on non-key attributes.
Projection Expression
Projection determines which attributes are actually written.
For example:
TenantId,
RecordId,
Status,
CreatedAtThis is important when you want to share data without exporting every attribute.
The result is:
Tenant
|
v
Key Condition
|
v
Matching Items
|
v
Filter Expression
|
v
Selected Items
|
v
Projection Expression
|
v
Selected Attributes
|
v
S3Example DynamoDB Table Design
Consider a multi-tenant table:
PK SK
--------------------------------
TENANT#1001 ORDER#5001
TENANT#1001 ORDER#5002
TENANT#1002 ORDER#6001
TENANT#1003 ORDER#7001The item might look like:
{
"TenantId": "tenant-1001",
"OrderId": "order-5001",
"Status": "COMPLETED",
"CreatedAt": "2026-09-20T10:15:00Z",
"CustomerName": "Example Customer",
"Email": "[email protected]"
}If the application uses TenantId as the partition key, the export can target that partition.
A conceptual filter specification looks like:
{
"KeyConditionExpression": "#tenant = :tenant",
"ExpressionAttributeNames": {
"#tenant": "TenantId"
},
"ExpressionAttributeValues": {
":tenant": {
"S": "tenant-1001"
}
}
}This selects the requested tenant.
Exporting One Tenant With the AWS CLI
The AWS CLI supports the --filter-specification option on export-table-to-point-in-time.
A simplified example is:
aws dynamodb export-table-to-point-in-time \
--table-arn arn:aws:dynamodb:us-east-1:123456789012:table/CustomerData \
--export-time 2026-09-30T00:00:00Z \
--s3-bucket my-dynamodb-exports \
--s3-prefix exports/tenant-1001/ \
--export-format DYNAMODB_JSON \
--filter-specification '{
"KeyConditionExpression": "#tenant = :tenant",
"ExpressionAttributeNames": {
"#tenant": "TenantId"
},
"ExpressionAttributeValues": {
":tenant": {
"S": "tenant-1001"
}
}
}'The exact table ARN, bucket, region, and timestamp should come from the environment where the export is being performed.
The important part is the filter specification.
Selecting Specific Attributes
Sometimes the tenant's entire dataset should not be shared.
For example, the item contains:
TenantId
OrderId
Status
CreatedAt
CustomerName
Email
PaymentInformation
InternalNotesThe receiving system may only need:
TenantId
OrderId
Status
CreatedAtUse a projection expression:
{
"KeyConditionExpression": "#tenant = :tenant",
"ProjectionExpression": "#tenant, OrderId, #status, CreatedAt",
"ExpressionAttributeNames": {
"#tenant": "TenantId",
"#status": "Status"
},
"ExpressionAttributeValues": {
":tenant": {
"S": "tenant-1001"
}
}
}The exported item will contain only the selected attributes.
This is an important security improvement.
You do not have to export sensitive attributes and then depend on another process to remove them later.
Filtering Sensitive Data
Suppose a tenant requests its historical data for an audit.
The source item contains:
TenantId
OrderId
Status
CustomerName
Email
Phone
PaymentToken
InternalNotesThe external audit system needs:
TenantId
OrderId
Status
CreatedAtThe projection should explicitly select those fields.
Source Item
|
+-- TenantId -> Export
+-- OrderId -> Export
+-- Status -> Export
+-- CreatedAt -> Export
+-- Email -> Exclude
+-- Phone -> Exclude
+-- PaymentToken -> Exclude
+-- InternalNotes -> ExcludeThis is safer than exporting everything and trying to redact it afterward.
However, projection is an attribute allow-list, not a content scanner. If an included free-text field contains personal information, that information is still exported. AWS specifically notes that projection controls which attributes are written but does not inspect the values inside those attributes.
Filter Expression vs Key Condition
This distinction is important.
A key condition can restrict the partition being processed.
For example:
TenantId = "tenant-1001"A filter expression is applied after the relevant data is read for the export.
For example:
Status = "ACTIVE"Therefore:
Key Condition
|
v
Reduces Partitions Considered
|
v
Filter Expression
|
v
Selects Matching ItemsAWS notes that a key condition can reduce the data processed when it identifies a partition key, while a filter expression selects items without reducing the underlying data processed.
This is similar to an important DynamoDB concept: filtering is not the same thing as reducing the amount of data that has to be read.
Full Export vs Incremental Export
Filtered export works with both export types.
Full Filtered Export
A full filtered export gives you matching data as it existed at a selected point in time.
For example:
September 30, 2026
|
v
Tenant 1001
|
v
Point-in-Time ExportThis is useful for:
Tenant migration
Historical data sharing
Data recovery
Creating an isolated dataset
Incremental Filtered Export
An incremental export captures changes within a time window.
For example:
10:00
|
+-- Item changed
|
+-- Item deleted
|
+-- Item inserted
|
11:00You can filter those changes to a particular tenant.
This can be especially useful during incident recovery.
Recovering One Tenant After a Bad Deployment
Consider a multi-tenant application.
A bad deployment modifies records for one tenant between 10:00 and 10:45.
The table contains:
Tenant A
Tenant B
Tenant C
Tenant D
...You do not want to restore the entire table.
With filtered incremental export, the recovery workflow can look like:
DynamoDB PITR
|
v
Incremental Export
|
+-- Tenant = A
+-- Corruption Window
|
v
Amazon S3
|
v
Review Data
|
v
Recover Required ItemsAWS demonstrates this type of recovery workflow using filtered incremental export for a single tenant rather than restoring the entire table.
This is one of the strongest use cases for the feature.
Important Point: Export Is Not a Direct Restore
A filtered export writes data to Amazon S3.
It does not automatically rewrite the original DynamoDB table.
That separation is useful.
The workflow becomes:
DynamoDB
|
v
Filtered Export
|
v
S3
|
v
Review / Transform
|
v
Controlled RecoveryYou can inspect the exported data before deciding what should be written back.
This is much safer than immediately modifying production records.
Recovering Data Programmatically
Suppose the exported data contains the correct previous state.
An application or recovery script can read the exported records and perform controlled writes.
A simplified AWS SDK for .NET workflow could look like:
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
var client = new AmazonDynamoDBClient();
var request = new PutItemRequest
{
TableName = "CustomerData",
Item = new Dictionary<string, AttributeValue>
{
["TenantId"] = new AttributeValue { S = "tenant-1001" },
["OrderId"] = new AttributeValue { S = "order-5001" },
["Status"] = new AttributeValue { S = "COMPLETED" }
}
};
await client.PutItemAsync(request);In a real recovery tool, you would not blindly write every exported record.
You would typically add:
Validation
Conditional expressions
Logging
Idempotency
Dry-run mode
Error handling
Recovery checkpoints
For example:
var request = new PutItemRequest
{
TableName = "CustomerData",
Item = item,
ConditionExpression = "attribute_not_exists(OrderId)"
};The condition prevents an existing record from being overwritten accidentally.
The exact condition should match the recovery strategy.
Tenant Migration
Filtered export can also simplify moving one tenant between environments or Regions.
The workflow can look like:
Source Region
|
v
DynamoDB
|
v
Filtered Export
|
v
S3
|
v
Destination Region
|
v
DynamoDB ImportAWS documents this as one of the intended filtered-export patterns.
For a SaaS platform, this could be useful when:
A large customer moves to a dedicated environment.
A tenant changes geographic hosting requirements.
A customer needs isolated infrastructure.
A business unit is separated into another AWS account.
Instead of exporting the complete shared table, the export can target the tenant's partition.
Sharing Tenant Data
Another use case is customer data sharing.
Suppose a customer wants its historical order data.
You can create an export containing:
TenantId
OrderId
Status
CreatedAt
Amountwhile excluding:
InternalNotes
PaymentToken
OperationalMetadataThe S3 export can then be placed in an approved sharing workflow.
The important point is that the export should be treated as sensitive data.
An S3 bucket is not automatically a secure sharing mechanism just because it is inside AWS.
Use appropriate:
IAM policies
Bucket policies
Encryption
Lifecycle rules
Access logging
Data retention policies
Point-in-Time Recovery Is Required
Filtered export depends on DynamoDB point-in-time recovery.
AWS states that PITR must be enabled on the source table, and exports can target a point within the available recovery window. The current PITR window can extend up to 35 days.
That means filtered export should be considered part of the recovery architecture, not something to enable for the first time after an incident.
A basic strategy is:
DynamoDB Table
|
+-- PITR Enabled
|
+-- Filtered Export Available
|
v
Recovery WorkflowIf PITR is not enabled and the required historical state is no longer available, filtered export cannot recreate it.
Does Filtered Export Consume Table Capacity?
One of the useful characteristics of DynamoDB export to S3 is that the export reads from the point-in-time recovery backup rather than consuming the table's normal read capacity.
AWS states that filtered export does not consume table capacity or compete with production traffic for table throughput.
This makes the architecture different from an application-level export.
Compare:
Application Export
DynamoDB
|
v
Query / Scan
|
v
Application
|
v
S3with:
DynamoDB Export
DynamoDB PITR
|
v
Export Service
|
v
S3The second model avoids writing a custom process that has to page through the table and upload every item.
Cost Considerations
Filtered export uses the same export pricing model as full and incremental exports rather than charging a separate premium for filtering. AWS also notes that a key condition can reduce the data processed when it targets a specific partition.
There are still other costs to consider:
DynamoDB Export
+
S3 Storage
+
S3 Requests
+
Athena Query Costs
+
PITR
+
Recovery WritesA filtered export can be considerably smaller than a full table export, but it is not automatically free.
If the filter only removes attributes after the data is processed, the storage savings and processing behavior may differ from a filter that narrows the partition being exported.
Secondary Indexes
There is an important limitation to understand.
Filtered export does not support using secondary indexes as the basis of the export at launch, matching the behavior of full export.
That means you should design the export strategy around the base table's key structure.
For multi-tenant applications, this reinforces an architectural principle:
Tenant Isolation Requirement
|
v
Data Model
|
v
Partition Key StrategyIf tenant-level export is an important operational requirement, the tenant identifier should be part of the data model in a way that supports the required export workflow.
Common Mistakes
Using FilterExpression When a Key Condition Is Available
If you know the tenant partition key, prefer a key condition.
A filter expression may select the same records but does not provide the same reduction in data processed.
Exporting All Attributes
Do not export sensitive attributes simply because the receiving system might not use them.
Use ProjectionExpression to define an explicit attribute allow-list.
Treating the S3 Export as Safe by Default
The exported data can contain customer information.
Protect the destination bucket just like any other sensitive data store.
Forgetting PITR
Filtered export depends on point-in-time recovery.
Enable and monitor PITR before you need historical recovery.
Automatically Restoring Exported Data
Review exported data before writing it back to production.
A filtered export is a recovery input, not an instruction to overwrite the table.
Assuming FilterExpression Reduces Export Processing
A filter expression determines which items are written, but it does not necessarily reduce the underlying data processed.
Use key conditions when you can.
Troubleshooting
The Export Contains Too Many Items
Check the filter specification.
Verify:
KeyConditionExpression
FilterExpression
ExpressionAttributeValuesMake sure the tenant identifier is correct.
Sensitive Attributes Are Present
Check the ProjectionExpression.
If you do not specify a projection, the matching items can include all attributes.
No Data Is Exported
Check:
The requested point in time.
PITR availability.
The key condition.
Filter expression.
Attribute names.
Attribute value types.
For example, DynamoDB string values must be represented as DynamoDB string attribute values in the export request.
Filtered Export Is Still Larger Than Expected
Determine whether the filter is based on a key condition or only a non-key filter.
A non-key filter can reduce what is written without reducing the data that the export processes.
Recovery Produces Unexpected Results
Remember that point-in-time exports are not transaction-aware across partitions. AWS documents the export consistency model as eventual consistency across partitions rather than a single transactionally consistent snapshot.
For business-critical recovery, validate the exported state before applying changes.
Filtered Export vs Application-Level Export
Area | Filtered Export | Custom Application Export |
|---|---|---|
Implementation effort | Low | Higher |
Reads table capacity | No | Usually yes |
Point-in-time data | Yes | Requires application logic |
Tenant filtering | Yes | Yes |
Attribute projection | Yes | Yes |
Custom transformation | Limited | Flexible |
S3 destination | Native | Application-managed |
Recovery workflow | Strong fit | Requires custom tooling |
Operational complexity | Lower | Higher |
Application-level export still has a place.
If you need complex transformations, enrichment, API calls, or business-specific processing, custom code may be more appropriate.
If the requirement is simply:
"Give me this tenant's DynamoDB data."filtered export is much more direct.
Best Practices
Design tenant-aware partition keys when tenant-level export is a requirement.
Enable DynamoDB point-in-time recovery before you need it.
Prefer key conditions when they can narrow the export to a partition.
Use filter expressions for additional item-level conditions.
Use projection expressions as an explicit attribute allow-list.
Treat S3 exports as sensitive data.
Encrypt and restrict access to export buckets.
Review recovery data before writing it back to production.
Use conditional writes during recovery where appropriate.
Test tenant recovery before an incident occurs.
Log who initiated an export, what tenant was selected, and where the data was written.
Keep export and recovery procedures documented and repeatable.
When Should You Use Filtered Export?
Filtered export is particularly useful for:
Recovering one tenant after a bad deployment.
Moving one tenant between Regions.
Sharing selected tenant data.
Creating tenant-specific analytics datasets.
Supporting data portability workflows.
Performing targeted historical recovery.
Reducing the amount of unnecessary data placed into S3.
It is less suitable when you need significant transformations during extraction.
For those cases, use the export as an input to a separate processing pipeline.
Final Thoughts
DynamoDB filtered export addresses a problem that becomes painful as multi-tenant systems grow.
The table may contain terabytes of data, but the operational task may involve one customer.
Exporting the entire table just to find that customer is inefficient and creates unnecessary data-handling work.
Filtered export moves that selection closer to the database export itself.
You can specify the partition to export, filter matching items, and choose the attributes that should reach Amazon S3. The feature works with both full and incremental exports and does not consume the table's normal read capacity.
The strongest use case is targeted recovery.
A team can export the affected tenant's historical data, inspect it, validate the recovery set, and then perform controlled writes rather than restoring an entire shared table.
The feature does not remove the need for good DynamoDB modeling or recovery planning.
If tenant isolation matters, design the partition-key strategy with that requirement in mind. If data sharing matters, define attribute-level export boundaries. If recovery matters, enable PITR and test the complete workflow before production incidents occur.

Join the conversation! Your thoughts help the community grow.