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:
- Proactive incident response: Alarms notify you before users experience slowdowns—CPU spikes, memory pressure, or elevated 5xx error rates trigger alerts so your team can intervene early.
- Auto-scaling decisions: Elastic Beanstalk's scaling policies rely on CloudWatch metrics. Tuning these requires understanding which metrics (CPU, network, request count) actually correlate with your workload.
- Cost optimization: Idle instances, over-provisioned resources, and inefficient scaling configurations become visible through long-term metric trends.
- Compliance and auditing: Historical metric data and alarm state changes provide an audit trail for troubleshooting and post-mortem analysis.
- Health visibility: Enhanced health monitoring catches issues that raw metrics miss—like failed application deployments, exhausted instance profiles, or impaired load balancer targets.
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:
CPUUtilization– Average CPU percentage across instancesNetworkIn/NetworkOut– Bytes received and sentDiskReadBytes/DiskWriteBytes– Disk I/O volumeHTTPCode_ELB_5XX– Count of 5xx errors from the load balancerHTTPCode_ELB_4XX– Count of 4xx errors from the load balancerApplicationRequestsTotal– Total request count served by the applicationApplicationLatencyP10,P50,P90,P99– Latency percentiles in millisecondsTargetResponseTime– Response time percentiles from target groups (ALB environments)
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:
- Ok – All instances pass health checks
- Warning – Some instances show elevated resource usage or intermittent issues
- Degraded – Instances are failing health checks consistently
- Severe – The environment is at risk of becoming unavailable
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:
- High CPU utilization (default threshold: 90% for 1 evaluation period)
- Elevated request latency (p90 exceeding a configured threshold)
- Increased 5xx error rates
- Load balancer unhealthy host count
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:
- period – The granularity of evaluation (60, 300, 900 seconds). Shorter periods catch spikes faster but are noisier.
- evaluation-periods – How many consecutive periods must breach before the alarm fires. More periods reduce false positives.
- treat-missing-data – Options:
missing,breaching,notBreaching,ignore.breachingis aggressive—it fires if data stops arriving, which can indicate a downed instance.
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 Dashboards → Create dashboard. Add widgets by selecting metric sources. For Elastic Beanstalk metrics, choose:
- Metrics → AWS/ElasticBeanstalk → EnvironmentName
- Select individual metrics like
CPUUtilization,ApplicationLatencyP90,HTTPCode_ELB_5XX - Configure each widget's period, statistic, and visualization (line, stacked area, number)
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
- Define SLO-based thresholds. Don't use generic CPU or latency thresholds—derive alarm thresholds from your Service Level Objectives. If your SLO is p90 latency under 500ms, set the alarm at 500ms, not the default 2000ms.
- Use composite alarms for high-signal alerting. Combine multiple metrics into a single composite alarm to reduce noise. For example, alert only when both high CPU and elevated latency occur simultaneously, indicating genuine overload rather than a background cron spike.
- Separate severity levels with distinct SNS topics. Create different SNS topics for
critical,warning, andinfoalarms. Route critical alarms to PagerDuty or OpsGenie, warnings to a Slack channel, and info to a log group. - Version-control your monitoring configuration. Keep dashboards, alarms, and metric configurations in
.ebextensionsor a dedicated infrastructure repo. This ensures monitoring parity across staging, production, and disaster-recovery environments. - Monitor health status separately from metrics. Enhanced health can catch issues that metric-based alarms miss—like a deployment failing halfway through, leaving some instances on an old version. Set up notifications for
DegradedandSeverehealth transitions. - Include custom business metrics. Infrastructure metrics tell you about resource health; business metrics tell you about user experience. Publish order completion rates, signup funnel progression, or API call volumes as custom metrics and alarm on anomalies.
- Test alarms regularly. Simulate threshold breaches in a staging environment to verify that alarm routing, SNS delivery, and downstream incident management workflows function end-to-end. A silent alarm is worse than no alarm.
- Document your dashboard layout. A well-organized dashboard groups metrics logically: infrastructure health (CPU, memory, disk) on the top row, application performance (latency, error rates, request counts) in the middle, and alarm status at the bottom. Add text widgets explaining what each section represents for on-call engineers.
- Use anomaly detection for irregular workloads. If your traffic patterns are highly variable (e.g., batch processing, event-driven spikes), CloudWatch anomaly detection can learn baselines and alert on deviations without manual threshold tuning. Enable it via the
AnomalyDetectionconfiguration when callingput-metric-alarm. - Monitor alarm states themselves. Use CloudWatch metric filters on alarm state changes (
AWS/CloudWatchnamespace,AlarmStatemetric) to track how often alarms fire. Frequent transient alarms indicate threshold tuning is needed.
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.