AWS Serverless with Node: cache data for a certain amount of time (TTL)

Elvis Ciotti
2 min readJan 31, 2024

In AWS serverless, code executed outside the handler is only executed once during the cold start, and for the next 15 minutes, the next invocations are “warm starts”, that means the code outside the handler won’t be executed again during this period. This is the best place to connect to a database or initialise constants or cache. See he AWS documentation about execution environments.

So, if you define a global variable / constant outside the handler and you initialise it there, it will stay without being reset. You can quickly test this yourself by creating a lambda function where you place let counter=0 outside the handler, then counter++ in the handler and return the value. You’ll see the value increasing at next invocation. But if you want 15 mins, it’ll start from zero.

Cache data for the whole lambda lifecycle (15 mins)

to do that, you can simply define a cache object to outside the handler

let cache = {}

and then inside the handler, you just use it


/**
* @param {import('aws-lambda').APIGatewayEvent} event
*/
export handler = async (event) => {
const cacheKey = 'mykey';
if (cache[cacheKey]) {
console.log("return cached data");
return cache[cacheKey];
}
// expensive operation e.g. network call
console.log("calling the network to fetch data");
const dataExpensiveToCalculate = await axios.get(...);
cache[cacheKey] = dataExpensiveToCalculate;

return
}

The conditional code will probably stay in a separate file/service, but I’m keeping this minimal to make it easier to understand.

Cache data for a defined amount of time (e.g. 30 seconds)

To cache data but expire it before the end of the lambda lifecycle, you can manually store the timestamp, and consider items invalid by comparing with the current timestamp.

Or you can use a library that already does so. I’ve use node-cache that seemed to work fine for me.

Install with npm install node-cache — save

then just use it like this

import NodeCache from 'node-cache';

const cache = new NodeCache();

/**
* @param {import('aws-lambda').APIGatewayEvent} event
*/
export handler = async (event) => {
const cacheKey = 'mykey';
const cacheLifetimeSeconds = 30;

if (cache.has(cacheKey) {
console.log("return cached data");
return cache.get(cacheKey);
}
// expensive operation e.g. network call
console.log("calling the network to fetch data");
const networkData = await axios.get(...);
cache.set(cacheKey, networkData, cacheLifetimeSeconds);

return
}

Note the call to set , you’ll need to pass the time to live (ttl) in seconds. If it’s 30 seconds, it means that for the next 30 seconds your handler will returned cache data, but after that, the has with return false, so the network will be used again to get fresh data.

--

--

Elvis Ciotti

Software Contractor — Java, Spring, k8s, AWS, Javascript @ London - hire me at https://www.linkedin.com/in/elvisciotti