← Back to DevBytes

Monitoring Elastic Beanstalk: Metrics, Alarms, and Dashboards

What Is Elastic Beanstalk Monitoring

Elastic Beanstalk monitoring refers to the collection, visualization, and alerting mechanisms available for tracking the health, performance, and resource utilization of your Elastic Beanstalk environments and the underlying AWS infrastructure. It encompasses Amazon CloudWatch metrics, CloudWatch alarms, and CloudWatch dashboards working together to give you a comprehensive view of how your application is behaving in near real-time.

Elastic Beanstalk automatically publishes a rich set of metrics to CloudWatch for every environment you create. These metrics cover instance-level data (CPU utilization, network traffic, disk reads/writes), environment-level aggregates (average request latency, HTTP status codes), and Elastic Load Balancer metrics when a load balancer is in use. Additionally, the Enhanced Health Monitoring system tracks internal health checks and operational issues at a granular level, reporting statuses like Ok, Warning, Degraded, or Severe.

Why Monitoring Matters

Without proper monitoring, an Elastic Beanstalk environment is a black box. You lose visibility into performance degradation, resource exhaustion, cost anomalies, and silent failures that can escalate into full outages. Effective monitoring matters because:

Understanding Elastic Beanstalk Metrics

Default CloudWatch Metrics

When you create an Elastic Beanstalk environment, the service automatically starts publishing metrics to CloudWatch under the namespace AWS/ElasticBeanstalk. These metrics are aggregated across all instances in the environment and pushed at one-minute intervals. The key metrics include:

You can retrieve these metrics using the AWS CLI. The following command fetches CPU utilization for the past hour at 5-minute intervals:

aws cloudwatch get-metric-statistics \
    --namespace AWS/ElasticBeanstalk \
    --metric-name CPUUtilization \
    --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
    --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
    --period 300 \
    --statistics Average \
    --dimensions Name=EnvironmentName,Value=my-app-production

Instance-Level Metrics and Custom Metrics

Default Elastic Beanstalk metrics are environment-scoped. To get per-instance granularity, you need to query the AWS/EC2 namespace with instance IDs as dimensions. Even more powerful is publishing your own custom metrics directly from your application code. You can push business-specific data—order processing rate, signup conversions, queue depth—as CloudWatch custom metrics with dimensions that match your domain model.

To publish custom metrics from an EC2 instance within Elastic Beanstalk, you can use the AWS SDK or the aws cloudwatch put-metric-data CLI command. Here's an example using Python with boto3 inside your application:

import boto3
import time

cloudwatch = boto3.client('cloudwatch', region_name='us-east-1')

def publish_order_metric(order_count, status):
    cloudwatch.put_metric_data(
        Namespace='MyApplication/Orders',
        MetricData=[
            {
                'MetricName': 'OrdersProcessed',
                'Value': order_count,
                'Unit': 'Count',
                'Timestamp': time.time(),
                'Dimensions': [
                    {'Name': 'Environment', 'Value': 'production'},
                    {'Name': 'Status', 'Value': status}
                ]
            }
        ]
    )

# Call this after processing a batch of orders
publish_order_metric(42, 'completed')

Custom metrics appear under your chosen namespace and can be graphed, alarmed, and included in dashboards just like built-in metrics. This unlocks full-stack observability beyond infrastructure metrics.

Enhanced Health Metrics

Elastic Beanstalk's Enhanced Health Monitoring system operates separately from standard CloudWatch metrics. It tracks instance and environment health status through a dedicated agent running on each instance. The health status reflects multiple checks: application responsiveness, resource exhaustion (CPU/memory), and instance profile validity. Health data flows to the Elastic Beanstalk console and can be streamed to CloudWatch Logs or processed via the DescribeEvents API.

Health statuses cascade from instance-level to environment-level:

You can query health status through the Elastic Beanstalk API:

aws elasticbeanstalk describe-environment-health \
    --environment-name my-app-production \
    --attributes All

The response includes detailed instance health, including causes like ELBHealthCheckFailed, HighCPU, or OutOfMemory.

Setting Up CloudWatch Alarms

Built-in Elastic Beanstalk Alarms

When you create an environment with Elastic Beanstalk, it automatically provisions several CloudWatch alarms for the Auto Scaling group and load balancer. These include alarms for:

You can view these alarms in the CloudWatch console under Alarms or through the Elastic Beanstalk console under the Monitoring tab of your environment. However, the defaults are often too coarse for production workloads—you should refine them based on your actual traffic patterns and SLOs.

Creating Custom Alarms via AWS CLI

To create an alarm that fits your specific needs, use the CloudWatch API. The following example creates an alarm that triggers when the p90 latency exceeds 2 seconds for 3 consecutive 5-minute periods, and sends a notification to an SNS topic:

aws cloudwatch put-metric-alarm \
    --alarm-name "HighP90Latency-Production" \
    --alarm-description "Triggers when p90 latency exceeds 2s for 15 minutes" \
    --namespace "AWS/ElasticBeanstalk" \
    --metric-name "ApplicationLatencyP90" \
    --statistic "Average" \
    --period 300 \
    --evaluation-periods 3 \
    --threshold 2000 \
    --comparison-operator "GreaterThanThreshold" \
    --dimensions Name=EnvironmentName,Value=my-app-production \
    --alarm-actions "arn:aws:sns:us-east-1:123456789012:ops-critical" \
    --treat-missing-data "breaching"

Key parameters to consider:

Creating Alarms with .ebextensions

The best practice for production environments is to define alarms as infrastructure-as-code using Elastic Beanstalk configuration files. Place a YAML or JSON file in the .ebextensions directory of your application source bundle. Here's an example that creates an alarm for elevated 5xx error counts along with the corresponding SNS topic:

# .ebextensions/cloudwatch-alarms.config
Resources:
  CriticalSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: "Critical Alerts"
      Subscription:
        - Endpoint: "ops-team@example.com"
          Protocol: "email"

  High5xxAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName:
        Fn::Join:
          - "-"
          - - Ref: "AWSEBEnvironmentName"
            - "High5xxAlarm"
      AlarmDescription: "Triggers when 5xx errors exceed 10 in 5 minutes"
      Namespace: "AWS/ElasticBeanstalk"
      MetricName: "HTTPCode_ELB_5XX"
      Statistic: "Sum"
      Period: 300
      EvaluationPeriods: 2
      Threshold: 10
      ComparisonOperator: "GreaterThanThreshold"
      Dimensions:
        - Name: "EnvironmentName"
          Value: 
            Ref: "AWSEBEnvironmentName"
      AlarmActions:
        - Ref: "CriticalSNSTopic"
      TreatMissingData: "notBreaching"

This approach ensures alarms are versioned alongside your application code and consistently deployed across environment rebuilds. Use Ref: AWSEBEnvironmentName to dynamically reference the environment name, keeping the configuration portable.

Building Dashboards

CloudWatch Dashboards Overview

CloudWatch dashboards provide customizable, shareable views of your metrics and alarms. A dashboard is a JSON document defining widgets—graphs, text blocks, alarm status tables—arranged in a grid layout. Dashboards persist across browser sessions and can be viewed by anyone with appropriate IAM permissions in your AWS account. For Elastic Beanstalk environments, dashboards let you correlate application metrics with infrastructure metrics in a single pane of glass.

Creating a Dashboard via AWS Console

In the CloudWatch console, navigate to DashboardsCreate dashboard. Add widgets by selecting metric sources. For Elastic Beanstalk metrics, choose:

While the console is great for ad-hoc exploration, production teams should script dashboard creation for repeatability.

Dashboard as Code via AWS CLI

You can create or update a dashboard programmatically using the put-dashboard command, passing a JSON body that defines all widgets. The following example creates a production monitoring dashboard with CPU, latency, and error widgets:

aws cloudwatch put-dashboard \
    --dashboard-name "ElasticBeanstalk-Production-Overview" \
    --dashboard-body '{
  "widgets": [
    {
      "type": "metric",
      "x": 0,
      "y": 0,
      "width": 8,
      "height": 6,
      "properties": {
        "view": "timeSeries",
        "stacked": false,
        "metrics": [
          ["AWS/ElasticBeanstalk", "CPUUtilization", { "stat": "Average", "period": 60 }]
        ],
        "region": "us-east-1",
        "title": "CPU Utilization (Average)",
        "period": 300
      }
    },
    {
      "type": "metric",
      "x": 8,
      "y": 0,
      "width": 8,
      "height": 6,
      "properties": {
        "view": "timeSeries",
        "stacked": false,
        "metrics": [
          ["AWS/ElasticBeanstalk", "ApplicationLatencyP90", { "stat": "Average", "period": 300 }],
          ["AWS/ElasticBeanstalk", "ApplicationLatencyP50", { "stat": "Average", "period": 300 }]
        ],
        "region": "us-east-1",
        "title": "Response Latency (ms)",
        "period": 300
      }
    },
    {
      "type": "metric",
      "x": 16,
      "y": 0,
      "width": 8,
      "height": 6,
      "properties": {
        "view": "timeSeries",
        "stacked": true,
        "metrics": [
          ["AWS/ElasticBeanstalk", "HTTPCode_ELB_5XX", { "stat": "Sum", "period": 300 }],
          ["AWS/ElasticBeanstalk", "HTTPCode_ELB_4XX", { "stat": "Sum", "period": 300 }]
        ],
        "region": "us-east-1",
        "title": "HTTP Errors (5xx / 4xx)",
        "period": 300
      }
    },
    {
      "type": "metric",
      "x": 0,
      "y": 6,
      "width": 24,
      "height": 6,
      "properties": {
        "view": "timeSeries",
        "stacked": false,
        "metrics": [
          ["AWS/ElasticBeanstalk", "ApplicationRequestsTotal", { "stat": "Sum", "period": 60 }]
        ],
        "region": "us-east-1",
        "title": "Total Request Count",
        "period": 60
      }
    },
    {
      "type": "alarm",
      "x": 0,
      "y": 12,
      "width": 24,
      "height": 4,
      "properties": {
        "title": "Active Alarms",
        "region": "us-east-1",
        "alarms": [
          "HighP90Latency-Production",
          "High5xxAlarm-my-app-production"
        ]
      }
    }
  ]
}'

The alarm widget type displays alarm status visually—green for OK, red for ALARM. This is incredibly useful for at-a-glance health assessment.

Dashboard via CloudFormation / .ebextensions

For full infrastructure-as-code coverage, embed dashboard definitions in your .ebextensions files. The AWS::CloudWatch::Dashboard resource creates a dashboard alongside your environment:

# .ebextensions/dashboard.config
Resources:
  MonitoringDashboard:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardName:
        Fn::Join:
          - "-"
          - - Ref: "AWSEBEnvironmentName"
            - "Overview"
      DashboardBody:
        Fn::Join:
          - ""
          - - '{"widgets":['
            - '{"type":"metric","x":0,"y":0,"width":12,"height":6,'
            - '"properties":{"view":"timeSeries","stacked":false,'
            - '"metrics":[["AWS/ElasticBeanstalk","CPUUtilization",'
            - '{"stat":"Average","period":60}]],"region":"'
            - Ref: "AWS::Region"
            - '","title":"CPU %","period":300}},'
            - '{"type":"metric","x":12,"y":0,"width":12,"height":6,'
            - '"properties":{"view":"timeSeries","stacked":false,'
            - '"metrics":[["AWS/ElasticBeanstalk","ApplicationLatencyP90",'
            - '{"stat":"Average","period":300}]],"region":"'
            - Ref: "AWS::Region"
            - '","title":"p90 Latency","period":300}}]}'

Note the use of Fn::Join to construct the JSON string with dynamic references. This dashboard deploys automatically whenever the environment is rebuilt or updated, eliminating manual setup steps.

Best Practices

Bringing It All Together

Effective monitoring of Elastic Beanstalk environments is a layered discipline. It begins with understanding the default metrics the platform provides for free—CPU, network, disk, and request-level data aggregated at the environment level. From there, you enrich the signal with custom application metrics that capture what actually matters to your users: successful checkouts, fast API responses, low error rates on critical paths. Alarms convert these metrics into actionable notifications, and dashboards give your team a real-time window into system health. By codifying alarms and dashboards as .ebextensions resources, you ensure monitoring is not a one-off setup task but an integral, versioned component of your application infrastructure. When built thoughtfully—with SLO-aligned thresholds, tiered severity routing, and regular testing—your Elastic Beanstalk monitoring stack transforms from a reactive troubleshooting tool into a proactive reliability platform that keeps your application running smoothly and your users happy.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles