How DynamoDB Projection Expressions Help You Optimize Costs And Performance
If you are not using projection expression, you’re overspending in database costs as well as suffer reduced performance.
What Are Projection Expressions?
In DynamoDB, when you query a table, by default you get back every attribute in the items returned.
But what if you don’t need every attribute of the requested items and only want to get back a subset of them?
This is what Projection Expressions are useful for.
Typical Use Case For Projection Expressions
Imagine you have a “music” table that stores artists and songs data.
In every item you have some information about the artist as well as some images for the song’s artwork, other cover images, and lyrics (amongst other attributes).
If you query for a song to retrieve the title and genre only, every query would also be hauling along with it extra images and lyrics data that will never be used.
At scale, this leads to fetching enormous amounts of data when you really only needed perhaps 1/10th of that data.
Benefits Of Projection Expressions
In DynamoDB, you can optimize this by specifying only the attributes you want to be returned, resulting in the most efficient queries every time.
This leads to 2 significant benefits:
Reducing costs: In DynamoDB you are charged per data fetched, not per item. The more data you fetch, the higher your costs are.
Improve performance: When querying for multiple items, the larger the size of the item, the slower the fetching will be. Specifying only what you need enhances performance, especially at scale.
Ultimately, by specifying only the attributes you need in your queries with a projection expression, your queries will yield much more efficient results.
Projection Expression Demo
Let’s now take a look at how to write our own projection expressions with the DynamoDB API.
const params = {
TableName: "music",
KeyConditionExpression: "artist_name = :artist AND song_name = :song",
ExpressionAttributeValues: {
":artist": "Taylor Swift",
":song": "Shake it off"
},
ProjectionExpression: "artist_name, song_name" //add attributes you need here
};
try {
const command = new QueryCommand(params);
const response = await docClient.send(command);
console.log(JSON.stringify(response.Items));
} catch (error) {
console.error(error);
}
}
In the code above, we fetch items that match our KeyConditionExpression of artist_name and song_name, and then we write the ProjectionExpression and specify the attributes we would like to get back.
This query will return matching items with only two attributes in each item: the artist_name and the song_name.
How much data did we save with the projection expression?
If we estimate about 20 bytes of data per attribute and more for the lyrics and images URLs, we are looking at somewhere in the 400–500 bytes range.
With 100 items, that’s at least 40KBs.
However, with projection expressions, we can drastically reduce the data returned by 90%: From 40KBs to 4KBs.
This leads to measurable performance, latency improvements, and cost reductions, especially at scale.
Conclusion
Projection Expressions in DynamoDB allow us to drastically reduce the amount of data returned in our queries.
This leads to significant performance improvements and cost savings.
By using projection expressions we can get back only the data we need for a given query, ensuring our queries remain efficient especially as the dataset grows.
📖 P.S. I’m putting together a FREE email course to help you learn DynamoDB design patterns that are not taught in other courses, you can sign up here:
https://www.buildawaitlist.com/waitlist/dynamodb-course
👋 My name is Uriel Bitton and I’m committed to helping you master Serverless, Cloud Computing, and AWS.
🚀 If you want to learn how to build serverless, scalable, and resilient applications, you can also follow me on Linkedin for valuable daily posts.
Thanks for reading and see you in the next one!