Repository: cdklabs/cdk-monitoring-constructs (language: python)

Issue:
[lambda] Duration and/or Timeout monitoring
### Feature scope

Lambda

### Describe your suggested feature

I'd like to be a able to configure monitoring of function duration to alarm if any executions are nearing the configured timeout, or timing out. Currently, I am doing this with:

`myFunction.metricDuration({ statistic: 'Maximum' }).createAlarm( ... )`,

but I'd like to be able to do something like:

```typescript
myMonitoringFacade.monitorLambdaFunction({
  lambdaFunction: myFunctions,
  addMaxLatencyAlarm: {
    Warning: {
      maxLatencyMillis: 900_000,
    }
  }
})
```

The P99 latency metric is a decent proxy for this, but having an option for the maximum / P100 duration would be useful imo.

Finding and alarming on actual timeouts is a bit trickier (requires searching the logs), but is possible and would also be useful.


Discussion / hints:

Fix patch:
diff --git a/API.md b/API.md
index 6588b82b..4eedf74a 100644
--- a/API.md
+++ b/API.md
@@ -23729,6 +23729,7 @@ const lambdaFunctionMonitoringOptions: LambdaFunctionMonitoringOptions = { ... }
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addLatencyP99Alarm">addLatencyP99Alarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.LatencyThreshold">LatencyThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addLowTpsAlarm">addLowTpsAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.LowTpsThreshold">LowTpsThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addMaxIteratorAgeAlarm">addMaxIteratorAgeAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.MaxAgeThreshold">MaxAgeThreshold</a>}</code> | *No description.* |
+| <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addMaxLatencyAlarm">addMaxLatencyAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.LatencyThreshold">LatencyThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addMinInvocationsCountAlarm">addMinInvocationsCountAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.MinUsageCountThreshold">MinUsageCountThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addProvisionedConcurrencySpilloverInvocationsCountAlarm">addProvisionedConcurrencySpilloverInvocationsCountAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.RunningTaskCountThreshold">RunningTaskCountThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addProvisionedConcurrencySpilloverInvocationsRateAlarm">addProvisionedConcurrencySpilloverInvocationsRateAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.RunningTaskRateThreshold">RunningTaskRateThreshold</a>}</code> | *No description.* |
@@ -23985,6 +23986,16 @@ public readonly addMaxIteratorAgeAlarm: {[ key: string ]: MaxAgeThreshold};
 
 ---
 
+##### `addMaxLatencyAlarm`<sup>Optional</sup> <a name="addMaxLatencyAlarm" id="cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addMaxLatencyAlarm"></a>
+
+```typescript
+public readonly addMaxLatencyAlarm: {[ key: string ]: LatencyThreshold};
+```
+
+- *Type:* {[ key: string ]: <a href="#cdk-monitoring-constructs.LatencyThreshold">LatencyThreshold</a>}
+
+---
+
 ##### `addMinInvocationsCountAlarm`<sup>Optional</sup> <a name="addMinInvocationsCountAlarm" id="cdk-monitoring-constructs.LambdaFunctionMonitoringOptions.property.addMinInvocationsCountAlarm"></a>
 
 ```typescript
@@ -24075,6 +24086,7 @@ const lambdaFunctionMonitoringProps: LambdaFunctionMonitoringProps = { ... }
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addLatencyP99Alarm">addLatencyP99Alarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.LatencyThreshold">LatencyThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addLowTpsAlarm">addLowTpsAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.LowTpsThreshold">LowTpsThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addMaxIteratorAgeAlarm">addMaxIteratorAgeAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.MaxAgeThreshold">MaxAgeThreshold</a>}</code> | *No description.* |
+| <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addMaxLatencyAlarm">addMaxLatencyAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.LatencyThreshold">LatencyThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addMinInvocationsCountAlarm">addMinInvocationsCountAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.MinUsageCountThreshold">MinUsageCountThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addProvisionedConcurrencySpilloverInvocationsCountAlarm">addProvisionedConcurrencySpilloverInvocationsCountAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.RunningTaskCountThreshold">RunningTaskCountThreshold</a>}</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addProvisionedConcurrencySpilloverInvocationsRateAlarm">addProvisionedConcurrencySpilloverInvocationsRateAlarm</a></code> | <code>{[ key: string ]: <a href="#cdk-monitoring-constructs.RunningTaskRateThreshold">RunningTaskRateThreshold</a>}</code> | *No description.* |
@@ -24379,6 +24391,16 @@ public readonly addMaxIteratorAgeAlarm: {[ key: string ]: MaxAgeThreshold};
 
 ---
 
+##### `addMaxLatencyAlarm`<sup>Optional</sup> <a name="addMaxLatencyAlarm" id="cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addMaxLatencyAlarm"></a>
+
+```typescript
+public readonly addMaxLatencyAlarm: {[ key: string ]: LatencyThreshold};
+```
+
+- *Type:* {[ key: string ]: <a href="#cdk-monitoring-constructs.LatencyThreshold">LatencyThreshold</a>}
+
+---
+
 ##### `addMinInvocationsCountAlarm`<sup>Optional</sup> <a name="addMinInvocationsCountAlarm" id="cdk-monitoring-constructs.LambdaFunctionMonitoringProps.property.addMinInvocationsCountAlarm"></a>
 
 ```typescript
@@ -59236,6 +59258,7 @@ new LambdaFunctionMetricFactory(metricFactory: MetricFactory, props: LambdaFunct
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricFaultRate">metricFaultRate</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricInvocationCount">metricInvocationCount</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricInvocationRate">metricInvocationRate</a></code> | *No description.* |
+| <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyInMillis">metricLatencyInMillis</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP50InMillis">metricLatencyP50InMillis</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP90InMillis">metricLatencyP90InMillis</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP99InMillis">metricLatencyP99InMillis</a></code> | *No description.* |
@@ -59278,19 +59301,31 @@ public metricInvocationCount(): Metric | MathExpression
 public metricInvocationRate(): Metric | MathExpression
 ```
 
-##### `metricLatencyP50InMillis` <a name="metricLatencyP50InMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP50InMillis"></a>
+##### `metricLatencyInMillis` <a name="metricLatencyInMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyInMillis"></a>
+
+```typescript
+public metricLatencyInMillis(latencyType: LatencyType): Metric | MathExpression
+```
+
+###### `latencyType`<sup>Required</sup> <a name="latencyType" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyInMillis.parameter.latencyType"></a>
+
+- *Type:* <a href="#cdk-monitoring-constructs.LatencyType">LatencyType</a>
+
+---
+
+##### ~~`metricLatencyP50InMillis`~~ <a name="metricLatencyP50InMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP50InMillis"></a>
 
 ```typescript
 public metricLatencyP50InMillis(): Metric | MathExpression
 ```
 
-##### `metricLatencyP90InMillis` <a name="metricLatencyP90InMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP90InMillis"></a>
+##### ~~`metricLatencyP90InMillis`~~ <a name="metricLatencyP90InMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP90InMillis"></a>
 
 ```typescript
 public metricLatencyP90InMillis(): Metric | MathExpression
 ```
 
-##### `metricLatencyP99InMillis` <a name="metricLatencyP99InMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP99InMillis"></a>
+##### ~~`metricLatencyP99InMillis`~~ <a name="metricLatencyP99InMillis" id="cdk-monitoring-constructs.LambdaFunctionMetricFactory.metricLatencyP99InMillis"></a>
 
 ```typescript
 public metricLatencyP99InMillis(): Metric | MathExpression
@@ -59697,6 +59732,7 @@ public createTpsWidget(width: number, height: number): GraphWidget
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.latencyAnnotations">latencyAnnotations</a></code> | <code>aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.maxIteratorAgeAnnotations">maxIteratorAgeAnnotations</a></code> | <code>aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.maxIteratorAgeMetric">maxIteratorAgeMetric</a></code> | <code>aws-cdk-lib.aws_cloudwatch.Metric \| aws-cdk-lib.aws_cloudwatch.MathExpression</code> | *No description.* |
+| <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.maxLatencyMetric">maxLatencyMetric</a></code> | <code>aws-cdk-lib.aws_cloudwatch.Metric \| aws-cdk-lib.aws_cloudwatch.MathExpression</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.memoryUsageAnnotations">memoryUsageAnnotations</a></code> | <code>aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]</code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.metricFactory">metricFactory</a></code> | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMetricFactory">LambdaFunctionMetricFactory</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LambdaFunctionMonitoring.property.namingStrategy">namingStrategy</a></code> | <code><a href="#cdk-monitoring-constructs.MonitoringNamingStrategy">MonitoringNamingStrategy</a></code> | *No description.* |
@@ -59895,6 +59931,16 @@ public readonly maxIteratorAgeMetric: Metric | MathExpression;
 
 ---
 
+##### `maxLatencyMetric`<sup>Required</sup> <a name="maxLatencyMetric" id="cdk-monitoring-constructs.LambdaFunctionMonitoring.property.maxLatencyMetric"></a>
+
+```typescript
+public readonly maxLatencyMetric: Metric | MathExpression;
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.Metric | aws-cdk-lib.aws_cloudwatch.MathExpression
+
+---
+
 ##### `memoryUsageAnnotations`<sup>Required</sup> <a name="memoryUsageAnnotations" id="cdk-monitoring-constructs.LambdaFunctionMonitoring.property.memoryUsageAnnotations"></a>
 
 ```typescript
@@ -71767,6 +71813,7 @@ Create a two sets of dashboards: standard set (interactive) and a copy (bitmap).
 | <code><a href="#cdk-monitoring-constructs.LatencyType.TM999_TOP">TM999_TOP</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LatencyType.TM9999_TOP">TM9999_TOP</a></code> | *No description.* |
 | <code><a href="#cdk-monitoring-constructs.LatencyType.AVERAGE">AVERAGE</a></code> | *No description.* |
+| <code><a href="#cdk-monitoring-constructs.LatencyType.MAX">MAX</a></code> | *No description.* |
 
 ---
 
@@ -71870,6 +71917,11 @@ Create a two sets of dashboards: standard set (interactive) and a copy (bitmap).
 ---
 
 
+##### `MAX` <a name="MAX" id="cdk-monitoring-constructs.LatencyType.MAX"></a>
+
+---
+
+
 ### LogLevel <a name="LogLevel" id="cdk-monitoring-constructs.LogLevel"></a>
 
 Level of a given log.
diff --git a/lib/common/monitoring/alarms/LatencyAlarmFactory.ts b/lib/common/monitoring/alarms/LatencyAlarmFactory.ts
index 9d18c751..4514fcfa 100644
--- a/lib/common/monitoring/alarms/LatencyAlarmFactory.ts
+++ b/lib/common/monitoring/alarms/LatencyAlarmFactory.ts
@@ -28,6 +28,7 @@ export enum LatencyType {
   TM999_TOP = "TM(99.9%:100%)",
   TM9999_TOP = "TM(99.99%:100%)",
   AVERAGE = "Average",
+  MAX = "Maximum",
 }
 
 export function getLatencyTypeStatistic(latencyType: LatencyType) {
@@ -72,6 +73,8 @@ export function getLatencyTypeStatistic(latencyType: LatencyType) {
       return MetricStatistic.TM9999_TOP;
     case LatencyType.AVERAGE:
       return MetricStatistic.AVERAGE;
+    case LatencyType.MAX:
+      return MetricStatistic.MAX;
     default:
       throw new Error(
         "Unsupported latency type (unknown statistic): " + latencyType
@@ -90,10 +93,12 @@ export function getLatencyTypeExpressionId(latencyType: LatencyType) {
     case LatencyType.P9999:
     case LatencyType.P100:
       // remove the P prefix
-      return latencyType.substr(1);
+      return latencyType.substring(1);
     case LatencyType.AVERAGE:
       // making it shorter for backwards compatibility
       return "Avg";
+    case LatencyType.MAX:
+      return "Max";
     default:
       // use as-is
       return latencyType;
@@ -119,6 +124,8 @@ export function getLatencyTypeLabel(latencyType: LatencyType) {
     case LatencyType.AVERAGE:
       // no suffix here, since we already have average
       return "Average";
+    case LatencyType.MAX:
+      return "Maximum";
     default:
       // use as-is
       return latencyType + averageSuffix;
diff --git a/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts b/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts
index 194412e6..f916e4c2 100644
--- a/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts
+++ b/lib/monitoring/aws-apigateway/ApiGatewayMetricFactory.ts
@@ -138,21 +138,21 @@ export class ApiGatewayMetricFactory {
   }
 
   /**
-   * @deprecated use metricLatencyInMillis instead
+   * @deprecated Use {@link metricLatencyInMillis} instead.
    */
   metricLatencyP99InMillis() {
     return this.metricLatencyInMillis(LatencyType.P99);
   }
 
   /**
-   * @deprecated use metricLatencyInMillis instead
+   * @deprecated Use {@link metricLatencyInMillis} instead.
    */
   metricLatencyP90InMillis() {
     return this.metricLatencyInMillis(LatencyType.P90);
   }
 
   /**
-   * @deprecated use metricLatencyInMillis instead
+   * @deprecated Use {@link metricLatencyInMillis} instead.
    */
   metricLatencyP50InMillis() {
     return this.metricLatencyInMillis(LatencyType.P50);
diff --git a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts
index b57c65eb..659a6429 100644
--- a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts
+++ b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMetricFactory.ts
@@ -133,42 +133,42 @@ export class ApiGatewayV2HttpApiMetricFactory {
   }
 
   /**
-   * @deprecated use metricLatencyInMillis instead
+   * @deprecated Use {@link metricLatencyInMillis} instead.
    */
   metricLatencyP50InMillis() {
     return this.metricLatencyInMillis(LatencyType.P50);
   }
 
   /**
-   * @deprecated use metricLatencyInMillis instead
+   * @deprecated Use {@link metricLatencyInMillis} instead.
    */
   metricLatencyP90InMillis() {
     return this.metricLatencyInMillis(LatencyType.P90);
   }
 
   /**
-   * @deprecated use metricLatencyInMillis instead
+   * @deprecated Use {@link metricLatencyInMillis} instead.
    */
   metricLatencyP99InMillis() {
     return this.metricLatencyInMillis(LatencyType.P99);
   }
 
   /**
-   * @deprecated use metricIntegrationLatencyInMillis instead
+   * @deprecated Use {@link metricIntegrationLatencyInMillis} instead.
    */
   metricIntegrationLatencyP50InMillis() {
     return this.metricIntegrationLatencyInMillis(LatencyType.P50);
   }
 
   /**
-   * @deprecated use metricIntegrationLatencyInMillis instead
+   * @deprecated Use {@link metricIntegrationLatencyInMillis} instead.
    */
   metricIntegrationLatencyP90InMillis() {
     return this.metricIntegrationLatencyInMillis(LatencyType.P90);
   }
 
   /**
-   * @deprecated use metricIntegrationLatencyInMillis instead
+   * @deprecated Use {@link metricIntegrationLatencyInMillis} instead.
    */
   metricIntegrationLatencyP99InMillis() {
     return this.metricIntegrationLatencyInMillis(LatencyType.P99);
diff --git a/lib/monitoring/aws-lambda/LambdaFunctionMetricFactory.ts b/lib/monitoring/aws-lambda/LambdaFunctionMetricFactory.ts
index 88145ba9..8aa54234 100644
--- a/lib/monitoring/aws-lambda/LambdaFunctionMetricFactory.ts
+++ b/lib/monitoring/aws-lambda/LambdaFunctionMetricFactory.ts
@@ -1,9 +1,12 @@
 import { IFunction } from "aws-cdk-lib/aws-lambda";
 
 import {
+  LatencyType,
   MetricFactory,
   MetricStatistic,
   RateComputationMethod,
+  getLatencyTypeLabel,
+  getLatencyTypeStatistic,
 } from "../../common";
 
 export interface LambdaFunctionMetricFactoryProps {
@@ -45,7 +48,7 @@ export class LambdaFunctionMetricFactory {
   }
 
   /**
-   * @deprecated use metricInvocationRate
+   * @deprecated Use {@link metricInvocationRate} instead.
    */
   metricTps() {
     return this.metricFactory.toRate(
@@ -111,31 +114,34 @@ export class LambdaFunctionMetricFactory {
     );
   }
 
-  metricLatencyP99InMillis() {
+  metricLatencyInMillis(latencyType: LatencyType) {
     return this.metricFactory.adaptMetric(
       this.lambdaFunction.metricDuration({
-        statistic: MetricStatistic.P99,
-        label: "P99",
+        statistic: getLatencyTypeStatistic(latencyType),
+        label: getLatencyTypeLabel(latencyType),
       })
     );
   }
 
+  /**
+   * @deprecated Use {@link metricLatencyInMillis} instead.
+   */
+  metricLatencyP99InMillis() {
+    return this.metricLatencyInMillis(LatencyType.P99);
+  }
+
+  /**
+   * @deprecated Use {@link metricLatencyInMillis} instead.
+   */
   metricLatencyP90InMillis() {
-    return this.metricFactory.adaptMetric(
-      this.lambdaFunction.metricDuration({
-        statistic: MetricStatistic.P90,
-        label: "P90",
-      })
-    );
+    return this.metricLatencyInMillis(LatencyType.P90);
   }
 
+  /**
+   * @deprecated Use {@link metricLatencyInMillis} instead.
+   */
   metricLatencyP50InMillis() {
-    return this.metricFactory.adaptMetric(
-      this.lambdaFunction.metricDuration({
-        statistic: MetricStatistic.P50,
-        label: "P50",
-      })
-    );
+    return this.metricLatencyInMillis(LatencyType.P50);
   }
 
   metricConcurrentExecutions() {
diff --git a/lib/monitoring/aws-lambda/LambdaFunctionMonitoring.ts b/lib/monitoring/aws-lambda/LambdaFunctionMonitoring.ts
index cfa173de..e512c255 100644
--- a/lib/monitoring/aws-lambda/LambdaFunctionMonitoring.ts
+++ b/lib/monitoring/aws-lambda/LambdaFunctionMonitoring.ts
@@ -56,6 +56,7 @@ export interface LambdaFunctionMonitoringOptions extends BaseMonitoringProps {
   readonly addLatencyP50Alarm?: Record<string, LatencyThreshold>;
   readonly addLatencyP90Alarm?: Record<string, LatencyThreshold>;
   readonly addLatencyP99Alarm?: Record<string, LatencyThreshold>;
+  readonly addMaxLatencyAlarm?: Record<string, LatencyThreshold>;
 
   readonly addFaultCountAlarm?: Record<string, ErrorCountThreshold>;
   readonly addFaultRateAlarm?: Record<string, ErrorRateThreshold>;
@@ -143,6 +144,7 @@ export class LambdaFunctionMonitoring extends Monitoring {
   readonly p50LatencyMetric: MetricWithAlarmSupport;
   readonly p90LatencyMetric: MetricWithAlarmSupport;
   readonly p99LatencyMetric: MetricWithAlarmSupport;
+  readonly maxLatencyMetric: MetricWithAlarmSupport;
   readonly faultCountMetric: MetricWithAlarmSupport;
   readonly faultRateMetric: MetricWithAlarmSupport;
   readonly invocationCountMetric: MetricWithAlarmSupport;
@@ -202,9 +204,18 @@ export class LambdaFunctionMonitoring extends Monitoring {
       props
     );
     this.tpsMetric = this.metricFactory.metricTps();
-    this.p50LatencyMetric = this.metricFactory.metricLatencyP50InMillis();
-    this.p90LatencyMetric = this.metricFactory.metricLatencyP90InMillis();
-    this.p99LatencyMetric = this.metricFactory.metricLatencyP99InMillis();
+    this.p50LatencyMetric = this.metricFactory.metricLatencyInMillis(
+      LatencyType.P50
+    );
+    this.p90LatencyMetric = this.metricFactory.metricLatencyInMillis(
+      LatencyType.P90
+    );
+    this.p99LatencyMetric = this.metricFactory.metricLatencyInMillis(
+      LatencyType.P99
+    );
+    this.maxLatencyMetric = this.metricFactory.metricLatencyInMillis(
+      LatencyType.MAX
+    );
     this.faultCountMetric = this.metricFactory.metricFaultCount();
     this.faultRateMetric = this.metricFactory.metricFaultRate();
     this.invocationCountMetric = this.metricFactory.metricInvocationCount();
@@ -359,6 +370,18 @@ export class LambdaFunctionMonitoring extends Monitoring {
       this.latencyAnnotations.push(createdAlarm.annotation);
       this.addAlarm(createdAlarm);
     }
+    for (const disambiguator in props.addMaxLatencyAlarm) {
+      const alarmProps = props.addMaxLatencyAlarm[disambiguator];
+      const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(
+        this.maxLatencyMetric,
+        LatencyType.MAX,
+        alarmProps,
+        disambiguator
+      );
+      this.latencyAnnotations.push(createdAlarm.annotation);
+      this.addAlarm(createdAlarm);
+    }
+
     for (const disambiguator in props.addFaultCountAlarm) {
       const alarmProps = props.addFaultCountAlarm[disambiguator];
       const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(


Test patch:
diff --git a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap
index 36a98e91..7c824eef 100644
--- a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap
+++ b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap
@@ -5227,15 +5227,15 @@ Object {
               Object {
                 "Ref": "DummyFunction3BB5AE03",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "DummyFunction3BB5AE03",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "DummyFunction3BB5AE03",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
@@ -5333,15 +5333,15 @@ Object {
               Object {
                 "Ref": "DummyFunction3BB5AE03",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "DummyFunction3BB5AE03",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "DummyFunction3BB5AE03",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
diff --git a/test/monitoring/aws-lambda/LambdaFunctionMonitoring.test.ts b/test/monitoring/aws-lambda/LambdaFunctionMonitoring.test.ts
index c969e477..b838c4d2 100644
--- a/test/monitoring/aws-lambda/LambdaFunctionMonitoring.test.ts
+++ b/test/monitoring/aws-lambda/LambdaFunctionMonitoring.test.ts
@@ -90,6 +90,11 @@ test("snapshot test: all alarms", () => {
         datapointsToAlarm: 33,
       },
     },
+    addMaxLatencyAlarm: {
+      Warning: {
+        maxLatency: Duration.seconds(60),
+      },
+    },
     addLowTpsAlarm: {
       Warning: {
         minTps: 0,
@@ -145,7 +150,7 @@ test("snapshot test: all alarms", () => {
   });
 
   addMonitoringDashboardsToStack(stack, monitoring);
-  expect(numAlarmsCreated).toStrictEqual(13);
+  expect(numAlarmsCreated).toStrictEqual(14);
   expect(Template.fromStack(stack)).toMatchSnapshot();
 });
 
@@ -241,6 +246,11 @@ test("snapshot test: all alarms, alarmPrefix on error dedupeString", () => {
         datapointsToAlarm: 33,
       },
     },
+    addMaxLatencyAlarm: {
+      Warning: {
+        maxLatency: Duration.seconds(60),
+      },
+    },
     addLowTpsAlarm: {
       Warning: {
         minTps: 0,
@@ -326,7 +336,7 @@ test("snapshot test: all alarms, alarmPrefix on error dedupeString", () => {
   });
 
   addMonitoringDashboardsToStack(stack, monitoring);
-  expect(numAlarmsCreated).toStrictEqual(19);
+  expect(numAlarmsCreated).toStrictEqual(20);
   expect(Template.fromStack(stack)).toMatchSnapshot();
 });
 
@@ -379,6 +389,11 @@ test("snapshot test: all alarms, alarmPrefix on latency dedupeString", () => {
         datapointsToAlarm: 33,
       },
     },
+    addMaxLatencyAlarm: {
+      Warning: {
+        maxLatency: Duration.seconds(60),
+      },
+    },
     addLowTpsAlarm: {
       Warning: {
         minTps: 0,
@@ -464,7 +479,7 @@ test("snapshot test: all alarms, alarmPrefix on latency dedupeString", () => {
   });
 
   addMonitoringDashboardsToStack(stack, monitoring);
-  expect(numAlarmsCreated).toStrictEqual(19);
+  expect(numAlarmsCreated).toStrictEqual(20);
   expect(Template.fromStack(stack)).toMatchSnapshot();
 });
 
diff --git a/test/monitoring/aws-lambda/__snapshots__/LambdaFunctionMonitoring.test.ts.snap b/test/monitoring/aws-lambda/__snapshots__/LambdaFunctionMonitoring.test.ts.snap
index 42a059ac..aa6ea412 100644
--- a/test/monitoring/aws-lambda/__snapshots__/LambdaFunctionMonitoring.test.ts.snap
+++ b/test/monitoring/aws-lambda/__snapshots__/LambdaFunctionMonitoring.test.ts.snap
@@ -56,7 +56,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaFaultCountWarning33B0A193",
+                  "ScopeTestDummyLambdaLatencyMaximumWarning4C9EF83C",
                   "Arn",
                 ],
               },
@@ -67,7 +67,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaFaultRateWarningE6A1BB2B",
+                  "ScopeTestDummyLambdaFaultCountWarning33B0A193",
                   "Arn",
                 ],
               },
@@ -78,7 +78,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaMinTPSWarning30EF1FB4",
+                  "ScopeTestDummyLambdaFaultRateWarningE6A1BB2B",
                   "Arn",
                 ],
               },
@@ -89,7 +89,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaMaxTPSWarning0EC2023E",
+                  "ScopeTestDummyLambdaMinTPSWarning30EF1FB4",
                   "Arn",
                 ],
               },
@@ -100,7 +100,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaThrottledCountWarning946A5E19",
+                  "ScopeTestDummyLambdaMaxTPSWarning0EC2023E",
                   "Arn",
                 ],
               },
@@ -111,7 +111,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaThrottledRateWarning6EB21772",
+                  "ScopeTestDummyLambdaThrottledCountWarning946A5E19",
                   "Arn",
                 ],
               },
@@ -122,7 +122,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaUsageCountWarningFB9A10FB",
+                  "ScopeTestDummyLambdaThrottledRateWarning6EB21772",
                   "Arn",
                 ],
               },
@@ -133,7 +133,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaRunningTasksHighWarning2A06F60A",
+                  "ScopeTestDummyLambdaUsageCountWarningFB9A10FB",
                   "Arn",
                 ],
               },
@@ -144,7 +144,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaRunningTasksHighCritical357223A5",
+                  "ScopeTestDummyLambdaRunningTasksHighWarning2A06F60A",
                   "Arn",
                 ],
               },
@@ -153,6 +153,17 @@ Object {
                 "Ref": "AWS::Region",
               },
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
+              Object {
+                "Fn::GetAtt": Array [
+                  "ScopeTestDummyLambdaRunningTasksHighCritical357223A5",
+                  "Arn",
+                ],
+              },
+              "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":6,\\"y\\":12,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
                   "ScopeTestDummyLambdaIteratorAgeMaxWarning2BC5030F",
@@ -243,15 +254,15 @@ Object {
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"Maximum > 60000 for 3 datapoints within 15 minutes\\",\\"value\\":60000,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
@@ -422,6 +433,42 @@ Object {
       },
       "Type": "AWS::CloudWatch::Alarm",
     },
+    "ScopeTestDummyLambdaLatencyMaximumWarning4C9EF83C": Object {
+      "Properties": Object {
+        "ActionsEnabled": true,
+        "AlarmDescription": "Maximum latency is too high.",
+        "AlarmName": "Test-DummyLambda-Latency-Maximum-Warning",
+        "ComparisonOperator": "GreaterThanThreshold",
+        "DatapointsToAlarm": 3,
+        "EvaluationPeriods": 3,
+        "Metrics": Array [
+          Object {
+            "Id": "m1",
+            "Label": "Maximum",
+            "MetricStat": Object {
+              "Metric": Object {
+                "Dimensions": Array [
+                  Object {
+                    "Name": "FunctionName",
+                    "Value": Object {
+                      "Ref": "Function76856677",
+                    },
+                  },
+                ],
+                "MetricName": "Duration",
+                "Namespace": "AWS/Lambda",
+              },
+              "Period": 300,
+              "Stat": "Maximum",
+            },
+            "ReturnData": true,
+          },
+        ],
+        "Threshold": 60000,
+        "TreatMissingData": "notBreaching",
+      },
+      "Type": "AWS::CloudWatch::Alarm",
+    },
     "ScopeTestDummyLambdaLatencyP50WarningE50DF463": Object {
       "Properties": Object {
         "ActionsEnabled": true,
@@ -818,15 +865,15 @@ Object {
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"Maximum > 60000 for 3 datapoints within 15 minutes\\",\\"value\\":60000,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
@@ -1115,7 +1162,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaFaultCountWarning33B0A193",
+                  "ScopeTestDummyLambdaLatencyMaximumWarning4C9EF83C",
                   "Arn",
                 ],
               },
@@ -1126,7 +1173,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaFaultRateWarningE6A1BB2B",
+                  "ScopeTestDummyLambdaFaultCountWarning33B0A193",
                   "Arn",
                 ],
               },
@@ -1137,7 +1184,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaMinTPSWarning30EF1FB4",
+                  "ScopeTestDummyLambdaFaultRateWarningE6A1BB2B",
                   "Arn",
                 ],
               },
@@ -1148,7 +1195,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaMaxTPSWarning0EC2023E",
+                  "ScopeTestDummyLambdaMinTPSWarning30EF1FB4",
                   "Arn",
                 ],
               },
@@ -1159,7 +1206,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaThrottledCountWarning946A5E19",
+                  "ScopeTestDummyLambdaMaxTPSWarning0EC2023E",
                   "Arn",
                 ],
               },
@@ -1170,7 +1217,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaThrottledRateWarning6EB21772",
+                  "ScopeTestDummyLambdaThrottledCountWarning946A5E19",
                   "Arn",
                 ],
               },
@@ -1181,7 +1228,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaUsageCountWarningFB9A10FB",
+                  "ScopeTestDummyLambdaThrottledRateWarning6EB21772",
                   "Arn",
                 ],
               },
@@ -1192,7 +1239,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaRunningTasksHighWarning2A06F60A",
+                  "ScopeTestDummyLambdaUsageCountWarningFB9A10FB",
                   "Arn",
                 ],
               },
@@ -1203,7 +1250,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaRunningTasksHighCritical357223A5",
+                  "ScopeTestDummyLambdaRunningTasksHighWarning2A06F60A",
                   "Arn",
                 ],
               },
@@ -1212,6 +1259,17 @@ Object {
                 "Ref": "AWS::Region",
               },
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
+              Object {
+                "Fn::GetAtt": Array [
+                  "ScopeTestDummyLambdaRunningTasksHighCritical357223A5",
+                  "Arn",
+                ],
+              },
+              "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":18,\\"y\\":16,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
                   "ScopeTestDummyLambdaIteratorAgeMaxWarning2BC5030F",
@@ -1302,15 +1360,15 @@ Object {
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"Maximum > 60000 for 3 datapoints within 15 minutes\\",\\"value\\":60000,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
@@ -1669,6 +1727,42 @@ Object {
       },
       "Type": "AWS::CloudWatch::Alarm",
     },
+    "ScopeTestDummyLambdaLatencyMaximumWarning4C9EF83C": Object {
+      "Properties": Object {
+        "ActionsEnabled": true,
+        "AlarmDescription": "Maximum latency is too high.",
+        "AlarmName": "Test-DummyLambda-Latency-Maximum-Warning",
+        "ComparisonOperator": "GreaterThanThreshold",
+        "DatapointsToAlarm": 3,
+        "EvaluationPeriods": 3,
+        "Metrics": Array [
+          Object {
+            "Id": "m1",
+            "Label": "Maximum",
+            "MetricStat": Object {
+              "Metric": Object {
+                "Dimensions": Array [
+                  Object {
+                    "Name": "FunctionName",
+                    "Value": Object {
+                      "Ref": "Function76856677",
+                    },
+                  },
+                ],
+                "MetricName": "Duration",
+                "Namespace": "AWS/Lambda",
+              },
+              "Period": 300,
+              "Stat": "Maximum",
+            },
+            "ReturnData": true,
+          },
+        ],
+        "Threshold": 60000,
+        "TreatMissingData": "notBreaching",
+      },
+      "Type": "AWS::CloudWatch::Alarm",
+    },
     "ScopeTestDummyLambdaLatencyP50WarningE50DF463": Object {
       "Properties": Object {
         "ActionsEnabled": true,
@@ -2137,15 +2231,15 @@ Object {
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"Maximum > 60000 for 3 datapoints within 15 minutes\\",\\"value\\":60000,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
@@ -2313,7 +2407,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaFaultCountWarning33B0A193",
+                  "ScopeTestDummyLambdaLatencyMaximumWarning4C9EF83C",
                   "Arn",
                 ],
               },
@@ -2324,7 +2418,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaFaultRateWarningE6A1BB2B",
+                  "ScopeTestDummyLambdaFaultCountWarning33B0A193",
                   "Arn",
                 ],
               },
@@ -2335,7 +2429,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaMinTPSWarning30EF1FB4",
+                  "ScopeTestDummyLambdaFaultRateWarningE6A1BB2B",
                   "Arn",
                 ],
               },
@@ -2346,7 +2440,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaMaxTPSWarning0EC2023E",
+                  "ScopeTestDummyLambdaMinTPSWarning30EF1FB4",
                   "Arn",
                 ],
               },
@@ -2357,7 +2451,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaThrottledCountWarning946A5E19",
+                  "ScopeTestDummyLambdaMaxTPSWarning0EC2023E",
                   "Arn",
                 ],
               },
@@ -2368,7 +2462,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaThrottledRateWarning6EB21772",
+                  "ScopeTestDummyLambdaThrottledCountWarning946A5E19",
                   "Arn",
                 ],
               },
@@ -2379,7 +2473,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaUsageCountWarningFB9A10FB",
+                  "ScopeTestDummyLambdaThrottledRateWarning6EB21772",
                   "Arn",
                 ],
               },
@@ -2390,7 +2484,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaRunningTasksHighWarning2A06F60A",
+                  "ScopeTestDummyLambdaUsageCountWarningFB9A10FB",
                   "Arn",
                 ],
               },
@@ -2401,7 +2495,7 @@ Object {
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
-                  "ScopeTestDummyLambdaRunningTasksHighCritical357223A5",
+                  "ScopeTestDummyLambdaRunningTasksHighWarning2A06F60A",
                   "Arn",
                 ],
               },
@@ -2410,6 +2504,17 @@ Object {
                 "Ref": "AWS::Region",
               },
               "\\",\\"annotations\\":{\\"alarms\\":[\\"",
+              Object {
+                "Fn::GetAtt": Array [
+                  "ScopeTestDummyLambdaRunningTasksHighCritical357223A5",
+                  "Arn",
+                ],
+              },
+              "\\"]},\\"yAxis\\":{}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":4,\\"x\\":18,\\"y\\":16,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"annotations\\":{\\"alarms\\":[\\"",
               Object {
                 "Fn::GetAtt": Array [
                   "ScopeTestDummyLambdaIteratorAgeMaxWarning2BC5030F",
@@ -2500,15 +2605,15 @@ Object {
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"Maximum > 60000 for 3 datapoints within 15 minutes\\",\\"value\\":60000,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },
@@ -2867,6 +2972,42 @@ Object {
       },
       "Type": "AWS::CloudWatch::Alarm",
     },
+    "ScopeTestDummyLambdaLatencyMaximumWarning4C9EF83C": Object {
+      "Properties": Object {
+        "ActionsEnabled": true,
+        "AlarmDescription": "Maximum latency is too high.",
+        "AlarmName": "Test-DummyLambda-Latency-Maximum-Warning",
+        "ComparisonOperator": "GreaterThanThreshold",
+        "DatapointsToAlarm": 3,
+        "EvaluationPeriods": 3,
+        "Metrics": Array [
+          Object {
+            "Id": "m1",
+            "Label": "Maximum",
+            "MetricStat": Object {
+              "Metric": Object {
+                "Dimensions": Array [
+                  Object {
+                    "Name": "FunctionName",
+                    "Value": Object {
+                      "Ref": "Function76856677",
+                    },
+                  },
+                ],
+                "MetricName": "Duration",
+                "Namespace": "AWS/Lambda",
+              },
+              "Period": 300,
+              "Stat": "Maximum",
+            },
+            "ReturnData": true,
+          },
+        ],
+        "Threshold": 60000,
+        "TreatMissingData": "notBreaching",
+      },
+      "Type": "AWS::CloudWatch::Alarm",
+    },
     "ScopeTestDummyLambdaLatencyP50WarningE50DF463": Object {
       "Properties": Object {
         "ActionsEnabled": true,
@@ -3335,15 +3476,15 @@ Object {
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P50\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P90\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
+              "\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/Lambda\\",\\"Duration\\",\\"FunctionName\\",\\"",
               Object {
                 "Ref": "Function76856677",
               },
-              "\\",{\\"label\\":\\"P99\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
+              "\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"P50 > 110 for 11 datapoints within 55 minutes\\",\\"value\\":110,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P90 > 220 for 22 datapoints within 110 minutes\\",\\"value\\":220,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"P99 > 330 for 33 datapoints within 165 minutes\\",\\"value\\":330,\\"yAxis\\":\\"left\\"},{\\"label\\":\\"Maximum > 60000 for 3 datapoints within 15 minutes\\",\\"value\\":60000,\\"yAxis\\":\\"left\\"}]},\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },