4

I built a basic node.js API hosted on AWS Lambda and served over AWS API Gateway. This is the code:

'use strict';

// Require and initialize outside of your main handler
const mysql = require('serverless-mysql')({
    config: {
      host     : process.env.ENDPOINT,
      database : process.env.DATABASE,
      user     : process.env.USERNAME,
      password : process.env.PASSWORD
    }
  });

// Import the Dialogflow module from the Actions on Google client library.
const {dialogflow} = require('actions-on-google');

// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});

// Handle the Dialogflow intent named 'trip name'.
// The intent collects a parameter named 'tripName'.
app.intent('trip name', async (conv, {tripName}) => {

    // Run your query
    let results = await mysql.query('SELECT * FROM tablename where field = ? limit 1', tripName)

    // Respond with the user's lucky number and end the conversation.
    conv.close('Your lucky number is ' + results[0].id);

    // Run clean up function
    await mysql.end()
});

// Set the DialogflowApp object to handle the HTTPS POST request.
exports.fulfillment = app;

It receives a parameter (a trip name), looks it up in MySQL and returns the result.

My issue is that the API takes more than 5 seconds to respond which is slow.

I'm not sure why it's slow? the MySQL is a powerful Amazon Aurora and node.js is supposed to be fast.

I tested the function from the same AWS region as the MySQL (Mumbai) and it still times out so I don't think it has to do with distance between different regions.

The reason of slowness is carrying out any SQL query (even a dead simple SELECT). It does bring back the correct result but slowly.

When I remove the SQL part it becomes blazing fast. I increased the memory for Lambda to the maximum and redeployed Aurora to a far more powerful one.

Seif
  • 701
  • 4
  • 13
  • 32

1 Answers1

2

Lambda functions will run faster if you configure more memory. The less the memory configured, the worse the performance.

This means if you have configured your function to use 128MB, it's going to be run in a very low profile hardware.

On the other hand, if you configure it to use 3GB, it will run in a very decent machine.

At 1792MB, your function will run in a hardware with a dedicated core, which will speed up your code significantly considering you are making use of IO calls (network requests, for example). You can see this information here

There's no magic formula though. You have to run a few tests and see what memory configuration best suits your application. I would start with 3GB and eventually decrease it by chunks of 128MB until you find the right configuration.

Thales Minussi
  • 6,965
  • 1
  • 30
  • 48
  • 1
    I hiked memory to 3008 MB but Google Assistant still says: "Webhook call failed. Error: Request timeout". on Dev Tools, API response still takes just over 5 seconds. I can confirm the memory change has been propagated. When I remove SQL query from the code it works perfectly but querying the DB is essential for me. – Seif Aug 01 '19 at 09:45
  • 3
    Are you sure your function can connect to your Aurora database? Is your Lambda in a VPC? Otherwise it won't be able to connect to the Aurora Cluster – Thales Minussi Aug 01 '19 at 09:51
  • 1
    I didn't mention it in my answer as you didn't complain about the function not being able to connect to your SQL cluster, it seemed it was just a performance issue – Thales Minussi Aug 01 '19 at 09:52
  • 1
    O yes it does connect to Aurora and fetch the right result and it is in the same VPC. My point was that querying the DB is the cause of the slowness. Sorry for the confusion. – Seif Aug 01 '19 at 09:54
  • 2
    The logic @ThalesMinussi applies to Lambda, would also apply to Amazon Aurora. If making the call to Aurora is taking up the most time, redeploy it on a larger or even a memory optimized instance. If you are using Aurora Serverless, be aware that there can be a lengthy(ish) delay when calling it cold. – K Mo Aug 01 '19 at 10:03
  • I deployed a brand new DB with lots of memory and still it times out if I were to a dead simple SELECT statement! @ThalesMinussi – Seif Aug 02 '19 at 04:49
  • 1
    The Lambda does bring back the correct result but it's just inexplicably slow. @KMo – Seif Aug 02 '19 at 04:50