Use DynamoDB as a cache for slow or computationally expensive functions in Node.js.
This is a proof-of-concept demonstrating how DynamoDB can be used as a cache to speed up function calls and reduce API requests.
After you call a cached function for the first time with a given set of arguments, subsequent calls only hit the DynamoDB cache, rather than the original function or API call.
Use cases include:
- Saving the results of a rate-limited API
- Saving the results of a slow API
- Saving the results of mathematically complex computations
An in-memory cache works great if you're only caching function calls for one user, or are running a backend on a single machine.
If you're using serverless functions (e.g. AWS Lambda), it's not easy or reliable to cache function calls across separate invocations. That's the problem this example is designed to address.
Pass your slow function into the withCache
function from cache.js
as follows:
// original function call
yourFunction('hello');
// cached function call
const cachedFunction = withCache('YOUR_FUNCTION_NAME', yourFunction);
cachedFunction('hello');
Where 'YOUR_FUNCTION_NAME'
is whatever prefix you want to use in the cache, and yourFunction
is a slow function you'd like to cache.
The cached function will attempt to fetch the result of the function call from DynamoDB using the given prefix and arguments. If it doesn't find anything, it'll call the original function, and store the result in DynamoDB with a PK of YOUR_FUNCTION_NAME#hello
. If the function has multiple arguments, they are simply concatenated.
First, clone the repository and run npm install
at the project root.
In function-cache/serverless.yml
I've provided settings for a simple DynamoDB table using Serverless Components, but you could use your own, existing table, as long as the key schema matches.
If you want to use the Serverless Component to provision a table:
-
Create a Serverless account and make sure AWS is configured as a provider.
-
Install Serverless CLI globally
npm i -g serverless
-
Add appropriate org, app, service name, and table name to
function-cache/serverless.yml
-
cd function-cache && sls deploy
You may have to add AWS as a provider for this service specifically, from the Serverless Dashboard.
Once you've created the table, you should be good to go!
Make sure the function you want to cache takes strings or string-like objects as parameters, so that we can use it as a cache key.
-
Rename
.env.example
to.env
and add your own table name and AWS region (the ones you used above). -
Run
index.js
for an example of how the caching works.Note: The examples in
index.js
use your actual table for caching, so you'll have to delete those example entries if you want to use the same table in production.
As of 2021, DynamoDB limits item sizes to 400KB (about 400,000 characters), and key sizes to 2048 bytes (about 256 characters).
As such, this caching strategy won't work directly for extremely large items. For those, you could try distributing the parts of the item across multiple DynamoDB rows, with the same partition key and different sort keys.