# Configuring Lambda

## Environment Variables

* Key-Value pairs in string form, available to lamdba code.
* Lambda also adds its own system environment variables.
* Can be used to store secret values _(encrypted using KMS)_.
* Secrets can also be encrypted using Lambda secret service or CMK _(Customer Master Key)_.

## Logging & Monitoring

* If Lambda has execution role with an IAM policy that has write permission to CloudWatch, then all logs will be avaiable to CloudWatch Logs.
* Metrics are also displayed in AWS CloudWatch Metrics.
* Metrics such as success-rate, error count, throttles, async delivery failures, invocation count etc.
* Lambda Tracing can be enabled using `X-Ray` tracing _(Active Tracing)_.
  * Once `X-Ray` tracing is enabled, Lambda will have X-Ray daemon running.
  * Once enabled, `X-Ray` SDK can be used.
  *   Following environment variables should be configured in Lambda to communicate with `X-Ray`.

      | Variable Name              | Description                        |
      | -------------------------- | ---------------------------------- |
      | `_X_AMZN_TRACE_ID`         | Contains tracing header            |
      | `AWS_XRAY_CONTENT_MISSING` | By default, `LOG_ERROR`            |
      | `AWS_XRAY_DAEMON_ADDRESS`  | `X-Ray` Daemon `IP_ADDRESS`:`PORT` |

## Lambda Function Configuration

* RAM can be increased from 128 MB to 10 GB, in 1 MB increments.
* The more RAM you add, the more VCPU credits get added.
* At 1792 MB, a function has equivalent of one full [vCPU](https://stackoverflow.com/questions/52090968/what-vcpus-in-fargate-really-mean).
* After 1792 MB, you get more than one vCPU, so to benefit from it use multi threading.
* So, for CPU bound processing in lambda, make sure to increase the RAM, as there is no explicit setting to select number of `vCPUS`.
* Lambda by default will timeout by 3 seconds, but this can be increased upto 15 minutes.

## Lambda concurrency executions

* Concurrency limit of upto 1000 concurrent executions.
* **Reserved concurrency** can be set to limit the concurrency at function level.
* It fucntion is invoked above the given concurrency limit, then it will trigger a **Throttle**.
  * For synchronous invocation, on encountering this limit lambda will throw `429` ThrottleError.
  * For asynchronous invocation, this will retry automatically and event will go to DLQ.
* Higher than `1000` concurrent executions can be achieved by connecting with AWS support team.

### Concurrency Issues

* **Limit issue**
  * Concurrency Limit applies to all the functions in an account.
* **Asynchronous Invocations**
  * If functions doesnt have enough concurrency available to process all the events, additional requests are throttled.
  * For throttling errors, Lambda returns the event to the queue and attempt to run the function again for upto 6 hours.
  * The retry interval increases the exponentially from 1 second after first attempt to upto maximum of 5 minutes.
* **Cold Start & Provisioned Concurrency**
  * On first invocation of a lambda function, code is loaded and all code outside the lambda handler has to be run i.e., all the initialization code.
  * If initialization is large, then the process takes time. As a result, the first request served by new instances has higher latency than the rest.
  * To solve this cold start problem, one can use **Provisioned Concurrency**.
    * This allocates concurrency even before the function is invoked i.e, maintain a warm pool of execution context.
    * So, cold start never happens and all invocations have lower latency.
    * Application auto scaling can manage the concurrency _(schedule or target utilization)_.
    * Will incur additional charges for this setup.

## Lambda Function dependencies

* External dependencies should be packages along with code and `zip` it together.
* Once `zip` is created, upload it to Lambda, if less than 50 MB, else upload to S3 first and refer it from there.
* AWS SDK comes by default with every lamdba function.

## References

* [Provisioned and Reserved Concurrency](https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html)
