2.1.5. Monitoring AI and Container Workloads: Amazon Bedrock and Amazon Managed Service for Prometheus
💡 First Principle: A generative AI call is an API call with three extra dimensions: a cost measured in tokens, a quota measured in tokens per minute, and a payload (the prompt and the response) that is exactly what you need when an answer goes wrong. Monitoring an AI workload means watching all three, and each one lives in a different place.
Exam guide v1.1 (June 2026) adds AI workloads to skill 1.1.1 next to serverless and compute, and names Amazon Managed Service for Prometheus alongside CloudWatch and CloudTrail. The operational question is always the same: which tool holds the signal I need, and is it switched on?
The Three Bedrock Signals:
| Signal | Where It Lives | On by Default? | Answers |
|---|---|---|---|
| Runtime metrics | CloudWatch, AWS/Bedrock namespace, ModelId dimension | ✅ Yes | How many calls, how fast, how many tokens, how often throttled |
| API activity | CloudTrail | ✅ Yes (model invocations are management events) | Who called what, when, and from where |
| Model invocation logging | CloudWatch Logs and/or Amazon S3 | ❌ No, disabled by default | What was asked and answered, token counts per call, the caller's ARN |
Bedrock Runtime Metrics Worth Alarming On:
| Metric | What It Measures | Typical Use |
|---|---|---|
Invocations | Successful Converse, ConverseStream, InvokeModel and InvokeModelWithResponseStream requests | Traffic baseline |
InvocationLatency | Request sent → last token received | "Answers take too long to finish" |
TimeToFirstToken | Request sent → first token received (streaming APIs only) | "Answers take too long to start" |
InvocationClientErrors / InvocationServerErrors | Client-side vs. AWS server-side failures | Error-rate alarms |
InvocationThrottles | Throttled invocations | Quota pressure |
InputTokenCount / OutputTokenCount | Tokens in and out | Cost and quota tracking |
EstimatedTPMQuotaUsage | Approximate tokens-per-minute quota consumption | Capacity awareness (an estimate, not the throttling source of truth) |
Throttled requests are counted neither as Invocations nor as errors, and how many throttles you see depends on your SDK's retry settings. A client that retries aggressively can hide a quota problem.
Why Bedrock Throttles "Early": When a request starts, Bedrock deducts input tokens + max_tokens from your tokens-per-minute (TPM) quota. It adjusts the charge during processing and gives back the unused reservation at the end. Some models also apply an output-token burndown rate (for example, one output token consuming five tokens of quota). An application that sets max_tokens far above its real reply size uses up its quota in reservations while its actual usage looks modest. Fix it in this order:
- Compare
OutputTokenCountwith themax_tokensthe application sends, and right-sizemax_tokens. - If actual consumption is genuinely near the quota, request a quota increase.
- For sustained high throughput on a model, consider Provisioned Throughput.
Model Invocation Logging: This is the only Bedrock source that holds the content: the full request, the full response, and metadata including identity.arn and the input and output token counts. Key operating rules:
- Disabled by default. Enable it in the Bedrock console under Settings, or with
PutModelInvocationLoggingConfiguration. It applies to the account in one Region. - Destinations: CloudWatch Logs, Amazon S3, or both, and they must be in the same account and Region as the logging configuration. To centralize logs in another account, deliver locally and replicate or forward from there.
- Size split: input and output JSON bodies up to 100 KB go inline. Larger bodies and binary image output go only to Amazon S3, so a CloudWatch-Logs-only configuration also needs an S3 location for large data.
- Delivery health: Bedrock emits
ModelInvocationLogsCloudWatchDeliveryFailure,ModelInvocationLogsS3DeliveryFailureandModelInvocationLargeDataS3DeliveryFailure(with matching…Successmetrics) inAWS/Bedrock. Alarm on the failures. - Scope: calls through the
bedrock-runtimeendpoint. Calls through the separatebedrock-mantleendpoint are not captured by invocation logging.
Because every record carries the caller's ARN and token counts, Logs Insights can attribute usage to principals:
fields identity.arn as principal, input.inputTokenCount as inTokens
| stats sum(inTokens) as totalInput, count() as calls by principal
| sort totalInput desc
CloudTrail for Bedrock:
| Event Category | Bedrock Operations | Logged by Default? |
|---|---|---|
| Management events | InvokeModel, InvokeModelWithResponseStream, Converse, ConverseStream, plus configuration APIs such as StopModelCustomizationJob or PutModelInvocationLoggingConfiguration | ✅ Yes |
| Data events | InvokeAgent (AWS::Bedrock::AgentAlias), Retrieve / RetrieveAndGenerate (AWS::Bedrock::KnowledgeBase), InvokeFlow (AWS::Bedrock::FlowAlias), ApplyGuardrail (AWS::Bedrock::Guardrail) | ❌ No: needs advanced event selectors (extra charge) |
CloudTrail tells you who invoked a model, from which IP and when. It does not store the prompt or the response.
CloudWatch Generative AI Observability: CloudWatch provides pre-built views for AI workloads. The Model Invocations view charts invocation count, latency, token counts by model, throttles and errors, and includes a table where you open a request ID to read that call's input and output. That table needs model invocation logging delivered to CloudWatch Logs. A second view covers Amazon Bedrock AgentCore agents. Alarms, dashboards and Logs Insights work on these signals as on any other.
Amazon Managed Service for Prometheus (AMP): Many container teams already standardize on Prometheus. AMP is a serverless, Prometheus-compatible metrics service. You keep the Prometheus data model and PromQL, and AWS runs the ingestion, storage, querying and availability.
| Concept | What to Know |
|---|---|
| Workspace | The logical store for your metrics. Data is replicated across three AZs in the Region |
| AWS managed collector | A fully managed, agentless scraper for Amazon EKS (also Amazon MSK and OpenSearch Service). It creates an ENI per subnet you specify and remote-writes to the workspace through a VPC endpoint |
| Customer-managed collector | Prometheus in agent mode, or AWS Distro for OpenTelemetry (ADOT), sending with Prometheus remote_write. Requests are SigV4-signed by a principal allowed to write (for example, the AmazonPrometheusRemoteWriteAccess managed policy) |
| Query | PromQL, the same query language as open-source Prometheus |
| Alerting | Alerting rules run in the workspace. Alert manager de-duplicates, groups and routes alerts, and supports only Amazon SNS as a receiver (same account). Silences mute alerts for a window; inhibition mutes alerts while another alert fires |
| Visualization | Add the workspace as a data source in Amazon Managed Grafana (or open-source Grafana) |
| Retention | 150 days by default, configurable up to 1,095 days (three years) |
CloudWatch or AMP?
| Requirement | Choose |
|---|---|
| Existing Prometheus exporters, PromQL dashboards and recording rules must carry over unchanged | AMP |
| Metrics from AWS services (EC2, Lambda, Bedrock) with zero collection setup | CloudWatch |
| An alarm that directly triggers Auto Scaling, EC2 or Systems Manager actions | CloudWatch |
| Queryable metric history beyond CloudWatch's 15 months | AMP (up to three years) |
| Notify on-call through SNS | Either: CloudWatch alarm actions, or AMP alert manager's SNS receiver |
⚠️ Exam Trap: Two traps show up together. First, CloudTrail is not where prompt text lives. If a scenario needs the content of model calls, the answer is model invocation logging, which is off until someone enables it. Second, AMP's alert manager is not open-source Alertmanager with every receiver. It sends only to an Amazon SNS topic in the same account, so email, Lambda and ticketing hang off that topic.
Reflection Question: A chatbot's users report intermittent failures at peak hours. InvocationThrottles spikes, InvocationServerErrors stays at zero, and a teammate wants to raise the SDK's retry count. What do you check before agreeing, and which signal tells you whether the account actually needs a larger quota?