DynamoDB
Boolean Key
Query Optimization
AWS
NoSQL Database

DynamoDB query on boolean key

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

In DynamoDB, a boolean attribute can be stored on an item, but it cannot be used as a table key or index key. That distinction matters because a Query operation works only on key attributes, so the usual solution is to redesign the schema rather than trying to query directly on a boolean field.

The key limitation

DynamoDB supports boolean attributes for normal item data, but primary key and secondary index key attributes must be scalar key types that are suitable for indexing. In practice, if you want fast lookups by a true-or-false state, you usually model that state as a string or number key value instead of a boolean.

This is why questions about "querying on a boolean key" often hide a schema problem. The real design question is:

  • do you need a key-based lookup
  • or is a slower filter acceptable

If it must be efficient and selective, redesign the key.

Why Query and Scan are different

Query is efficient because it uses a partition key, and optionally a sort key condition, to read a narrow slice of data. Scan reads many or all items and filters afterward.

If you store an attribute like isActive: true, you can filter on it, but that is not the same as querying by key:

python
1from boto3.dynamodb.conditions import Attr
2import boto3
3
4dynamodb = boto3.resource("dynamodb")
5table = dynamodb.Table("Users")
6
7response = table.scan(
8    FilterExpression=Attr("isActive").eq(True)
9)
10
11print(response["Items"])

This works for small tables or admin tooling, but it does not scale like a real key-based access pattern.

A better schema: encode the state as a key-friendly value

Suppose you want "all active users in tenant acme". A common pattern is to keep the tenant as the partition key and encode the active state into a string sort key or secondary index key:

text
PK = TENANT#acme
SK = STATUS#ACTIVE#USER#123

Now your items remain expressive, and the indexed value is key-compatible.

A simplified item shape might look like this:

python
1item = {
2    "pk": "TENANT#acme",
3    "sk": "STATUS#ACTIVE#USER#123",
4    "userId": "123",
5    "isActive": True,
6}

You keep the boolean for application logic, but the query uses the string key.

Querying the redesigned model

With a key-friendly sort key, you can query efficiently:

python
1from boto3.dynamodb.conditions import Key
2import boto3
3
4dynamodb = boto3.resource("dynamodb")
5table = dynamodb.Table("Users")
6
7response = table.query(
8    KeyConditionExpression=(
9        Key("pk").eq("TENANT#acme") &
10        Key("sk").begins_with("STATUS#ACTIVE#")
11    )
12)
13
14for item in response["Items"]:
15    print(item["userId"], item["isActive"])

This is the kind of model DynamoDB is optimized for: predictable access patterns encoded into keys.

When a secondary index is the right choice

Sometimes the table’s primary key serves another access pattern already. In that case, add a global secondary index whose keys support the status-based query.

For example:

  • 'gsi1pk = TENANT#acme'
  • 'gsi1sk = ACTIVE'

or perhaps:

  • 'gsi1pk = ACTIVE'
  • 'gsi1sk = createdAt'

The best choice depends on whether you need results grouped by tenant, time, or some other dimension. The key lesson is the same: boolean state is often part of the model, but indexed lookup usually wants a string or numeric encoding.

Common Pitfalls

The biggest mistake is assuming that because DynamoDB stores boolean attributes, it can also index them as keys. Storage support and key support are not the same thing.

Another issue is using Scan with a filter as if it were a true query. It may look correct during development and then become expensive and slow as the table grows.

People also model a low-cardinality key without thinking about hot partitions. A field with only two values such as active and inactive is rarely a good standalone partition key at scale because the traffic clusters too heavily.

Finally, do not duplicate only the encoded string key and forget the original boolean if the application still benefits from a clear domain field. Keeping both is often the most readable design.

Summary

  • A DynamoDB boolean attribute can be stored, but it is not a good direct key model for Query.
  • 'Query uses key attributes, while Scan plus filter is a broader and slower operation.'
  • If you need efficient lookup by state, encode that state into a string or number key.
  • Secondary indexes are often the right place for status-based access patterns.
  • In DynamoDB, access-pattern design usually matters more than raw attribute type convenience.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.