DynamoDB
primary key
begins_with method
database query
AWS

How can I Use begins_with method on primary key in DynamoDB?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In DynamoDB, you cannot use begins_with on the partition key part of a normal Query. A key condition must specify the partition key with equality, and prefix matching is supported only for the sort key side of the key condition. If you need prefix-style access on what is currently your primary lookup field, the real fix is usually a schema change or a secondary index.

The Core Rule for Query

For a Query operation, DynamoDB requires an equality condition on the partition key.

That means this shape is valid:

text
PartitionKey = :pk

And this shape can be added when there is a sort key:

text
PartitionKey = :pk AND begins_with(SortKey, :prefix)

But this is not valid for a partition key:

text
begins_with(PartitionKey, :prefix)

This is one of DynamoDB's most important query rules. Prefix matching is a sort-key refinement, not a replacement for partition-key equality.

Valid begins_with Example

Suppose your table uses:

  • partition key: CustomerId
  • sort key: OrderId

Then you can query all orders for one customer whose order ID starts with a prefix.

python
1import boto3
2
3client = boto3.client("dynamodb")
4
5response = client.query(
6    TableName="Orders",
7    KeyConditionExpression="CustomerId = :customer AND begins_with(OrderId, :prefix)",
8    ExpressionAttributeValues={
9        ":customer": {"S": "cust-123"},
10        ":prefix": {"S": "2025-"},
11    },
12)
13
14print(response["Items"])

This works because the partition key still uses equality and the prefix condition applies to the sort key.

Why It Does Not Work on the Partition Key

DynamoDB distributes items by partition key. A Query is efficient because it can go directly to the partition associated with one exact key value. A prefix match on the partition key would no longer be a direct partition lookup, so it is not supported in normal query key conditions.

That design is intentional. It is part of why DynamoDB query performance is predictable.

What to Do Instead

If your real access pattern is "find all items whose primary lookup starts with this prefix," you usually need a different schema.

Common options are:

  • move the prefix-searchable field into the sort key side of a composite key
  • create a global secondary index whose key design supports the prefix pattern
  • duplicate a search-oriented attribute specifically for that access pattern
  • use Scan only when the dataset is small and the cost is acceptable

The right answer is usually schema design, not trying to force a SQL-style prefix query into the existing partition key.

Secondary Index Example

A common redesign is to keep a stable partition key and move the searchable prefix field into a sort key on an index.

For example:

  • table partition key: TenantId
  • GSI partition key: TenantId
  • GSI sort key: Email

Then you can query one tenant's users whose email begins with a prefix.

python
1response = client.query(
2    TableName="Users",
3    IndexName="TenantEmailIndex",
4    KeyConditionExpression="TenantId = :tenant AND begins_with(Email, :prefix)",
5    ExpressionAttributeValues={
6        ":tenant": {"S": "tenant-42"},
7        ":prefix": {"S": "ana"},
8    },
9)

That is the DynamoDB-native way to support this pattern.

Scan Is Usually the Last Option

You can use a Scan with a filter expression that checks a prefix, but that is not the same as a query and can be expensive.

python
1response = client.scan(
2    TableName="Users",
3    FilterExpression="begins_with(UserId, :prefix)",
4    ExpressionAttributeValues={
5        ":prefix": {"S": "cust-"},
6    },
7)

This reads far more data and filters after reading. It is acceptable only when the table is small or the operation is rare.

Common Pitfalls

The most common mistake is assuming DynamoDB lets you treat the partition key like a SQL indexed text column. It does not. Partition-key queries require equality.

Another issue is reaching for Scan as the first answer. It may work functionally, but it often defeats the point of DynamoDB's predictable query model.

Developers also sometimes try to bolt prefix search onto a schema that was not designed for that access pattern. In DynamoDB, access patterns should drive key design from the start.

Finally, remember that begins_with in key conditions applies to the sort key side of the query, not to the partition key.

Summary

  • You cannot use begins_with on the partition key in a normal DynamoDB Query.
  • A query must specify the partition key with equality.
  • 'begins_with is valid on the sort key side of a composite key query.'
  • If you need prefix lookups, redesign the key or add an index that supports the access pattern.
  • Use Scan with great caution, because it is usually the least efficient fallback.

Course illustration
Course illustration

All Rights Reserved.