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 1000

Now 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 Dataset

you can request:

DynamoDB Table
      |
      v
Filtered Export
      |
      +-- Tenant Condition
      +-- Attribute Filter
      +-- Attribute Projection
      |
      v
Amazon S3
      |
      v
Only Required Data

For 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:

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
PaymentInformation

Suppose the table contains:

Tenant A  -> 500 GB
Tenant B  -> 300 GB
Tenant C  -> 200 GB
...
Total     -> 4 TB

A 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 partition

This 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,
CreatedAt

This 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
S3

Example 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#7001

The 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
InternalNotes

The receiving system may only need:

TenantId
OrderId
Status
CreatedAt

Use 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
InternalNotes

The external audit system needs:

TenantId
OrderId
Status
CreatedAt

The projection should explicitly select those fields.

Source Item
     |
     +-- TenantId       -> Export
     +-- OrderId        -> Export
     +-- Status         -> Export
     +-- CreatedAt      -> Export
     +-- Email          -> Exclude
     +-- Phone          -> Exclude
     +-- PaymentToken   -> Exclude
     +-- InternalNotes  -> Exclude

This 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 Items

AWS 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 Export

This is useful for:

Incremental Filtered Export

An incremental export captures changes within a time window.

For example:

10:00
  |
  +-- Item changed
  |
  +-- Item deleted
  |
  +-- Item inserted
  |
11:00

You 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 Items

AWS 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 Recovery

You 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:

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 Import

AWS documents this as one of the intended filtered-export patterns.

For a SaaS platform, this could be useful when:

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
Amount

while excluding:

InternalNotes
PaymentToken
OperationalMetadata

The 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:

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 Workflow

If 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
S3

with:

DynamoDB Export

DynamoDB PITR
   |
   v
Export Service
   |
   v
S3

The 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 Writes

A 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 Strategy

If 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
ExpressionAttributeValues

Make 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:

  1. The requested point in time.

  2. PITR availability.

  3. The key condition.

  4. Filter expression.

  5. Attribute names.

  6. 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

  1. Design tenant-aware partition keys when tenant-level export is a requirement.

  2. Enable DynamoDB point-in-time recovery before you need it.

  3. Prefer key conditions when they can narrow the export to a partition.

  4. Use filter expressions for additional item-level conditions.

  5. Use projection expressions as an explicit attribute allow-list.

  6. Treat S3 exports as sensitive data.

  7. Encrypt and restrict access to export buckets.

  8. Review recovery data before writing it back to production.

  9. Use conditional writes during recovery where appropriate.

  10. Test tenant recovery before an incident occurs.

  11. Log who initiated an export, what tenant was selected, and where the data was written.

  12. Keep export and recovery procedures documented and repeatable.

When Should You Use Filtered Export?

Filtered export is particularly useful for:

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.