title: AWS Lambda: Redis ElastiCache connection timeout error
body: <p>I have a lambda function using Node 12.</p>
  <p>I need to add a new connection to a Redis database hosted in AWS ElastiCache.</p>
  <p>Both are in one private VPC and the security groups/subnets are configured properly.</p>
  <p><strong>Solution:</strong></p>
  <p>globals.js:</p>
  <pre><code>const redis = require('redis');
  const redisClient = redis.createClient(
    `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}/${process.env.REDIS_DB}`,
  );
  redisClient.on('error', (err) =&gt; {
    console.log('REDIS CLIENT ERROR:' + err);
  });
  module.exports.globals = {
    REDIS: require('../helpers/redis')(redisClient),
  };
  </code></pre>
  <p>index.js (outside handler):</p>
  <pre><code>const { globals } = require('./config/globals');
  global.app = globals;
  
  const lambda_handler = (event, context, callback) =&gt; { ... }
  exports.handler = lambda_handler;
  </code></pre>
  <p>helpers/redis/index.js:</p>
  <pre><code>const get = require('./get');
  module.exports = (redisClient) =&gt; {
    return {
      get:  get(redisClient)
    };
  };
  </code></pre>
  <p>helpers/redis/get.js:</p>
  <pre><code>module.exports = (redisClient) =&gt; {
    return (key, cb) =&gt; {
      redisClient.get(key, (err, reply) =&gt; {
        if (err) {
          cb(err);
        } else {
          cb(null, reply);
        }
      });
    };
  };
  </code></pre>
  <p>Function call:</p>
  <pre><code>app.REDIS.get(redisKey, (err, reply) =&gt; {
    console.log(`REDIS GET: ${err} ${reply}`);
  });
  </code></pre>
  <p><strong>Problem:</strong>
  When increasing lambda timeout to a value greater than Redis timeout, I get this error:</p>
  <blockquote>
  <p>REDIS CLIENT ERROR:Error: Redis connection to ... failed - connect ETIMEDOUT ...</p>
  </blockquote>
  <p><strong>Addition:</strong></p>
  <p>I tried quiting/closing the connection after each transaction:</p>
  <pre><code>module.exports = (redisClient) =&gt; {
  
    return (cb) =&gt; {
  
      redisClient.quit((err, reply) =&gt; {
        if (err) {
          cb(err);
        } else {
          cb(null, reply);
        }
      });
    };
  };
  </code></pre>
  <pre><code>app.REDIS.get(redisKey, (err, reply) =&gt; {
    console.log(`REDIS GET: ${err} ${reply}`);
    if (err) {
      cb(err);
    } else {
      if (reply) {
        app.REDIS.quit(() =&gt; {
          cb()
        });
      }
    }
  })
  </code></pre>
  <p>Error:</p>
  <blockquote>
  <p>REDIS GET: AbortError: GET can't be processed. The connection is already closed.</p>
  </blockquote>
  <p>Extra Notes:</p>
  <ul>
  <li>I have to use callbacks, this is why I pass ones in the above examples</li>
  <li>I'm using <code>&quot;redis&quot;: &quot;^3.0.2&quot;</code></li>
  <li>It's not a configuration issue as the cache was accessed hundred of times in a small period of time but it then started giving the timeout errors.</li>
  <li>Everything works normally locally</li>
  </ul>