---
icon: fontawesome/brands/aws
title: "CloudWatch"
---

Hold [CloudWatch](https://www.log10x.com/?siem=cloudwatch){target="_blank"} Logs Standard ingestion at a daily volume the account sets. The lines of a statement over its limit are routed on the forwarder to a log group in the Essentials class (formerly Infrequent Access), where Logs Insights still queries them, or to an S3 bucket the team owns, chosen per service.

<div class="grid cards" markdown>

- [:material-check-circle-outline: **Compatibility**](#compatibility)
- [:material-currency-usd: **Cost Optimization**](#cost-optimization)
- [:material-wrench-outline: **Operations**](#operations)
- [:material-rocket-launch-outline: **Getting Started**](#getting-started)

</div>

### :material-check-circle-outline: Compatibility

??? tenx-compat "Does 10x work with CloudWatch Agent"

    **Through a file relay.** [Fluent Bit with 10x](https://doc.log10x.com/run/input/forwarder/fluentbit/){target="_blank"} reads the logs, processes them and writes them to a second folder, and the CloudWatch agent tails that folder as it would any log file, the same relay the [Datadog Agent](https://doc.log10x.com/run/input/forwarder/datadogAgent/){target="_blank"} uses. Fluent Bit can also send to CloudWatch Logs directly with its `cloudwatch_logs` output, in place of the agent.

    The [MCP server](https://github.com/log-10x/log10x-mcp){target="_blank"}'s SIEM-sample tool and [Retriever](https://log10x.com/retriever.html){target="_blank"} are agentless, working via CloudWatch API and S3 regardless of your forwarder. Also supported: [Fluent Bit](https://doc.log10x.com/run/input/forwarder/fluentbit/){target="_blank"}, [Fluentd](https://doc.log10x.com/run/input/forwarder/fluentd/){target="_blank"}, [Filebeat](https://doc.log10x.com/run/input/forwarder/filebeat/){target="_blank"}, and [Logstash](https://doc.log10x.com/run/input/forwarder/logstash/){target="_blank"}.

??? tenx-compat "How does 10x integrate with AWS CloudWatch"

    10x integrates at the [forwarder](https://doc.log10x.com/run/input/forwarder/){target="_blank"} level before logs reach CloudWatch.

    **Supported forwarders:** [Fluent Bit](https://doc.log10x.com/run/input/forwarder/fluentbit/){target="_blank"}, [Fluentd](https://doc.log10x.com/run/input/forwarder/fluentd/){target="_blank"}, [Filebeat](https://doc.log10x.com/run/input/forwarder/filebeat/){target="_blank"}, [Logstash](https://doc.log10x.com/run/input/forwarder/logstash/){target="_blank"}, and [OpenTelemetry Collector](https://doc.log10x.com/run/input/forwarder/otel-collector/){target="_blank"}.

    10x reduces ingestion volume with two levers that keep every line reachable (tier_down to a cheaper log group, offload to your own S3), plus sampling and drop, which keep a share of a statement's lines or none. Application code and SDKs stay as they are. For tier_down, one new log group is created in the Essentials class and the forwarder sends the low-value slice there; AWS fixes a group's class when the group is created, so the existing groups stay as they are.

??? tenx-compat "Will my existing CloudWatch Logs Insights queries still work"

    **Yes.** The 10x Engine operates pre-ingestion, and the events the [Receiver](https://doc.log10x.com/apps/receiver/) passes through arrive in standard CloudWatch format. On a Standard group, Logs Insights queries, the dashboards built on them, metric filters, subscription filters and the alarms built on them work unchanged. An Essentials group runs Logs Insights queries and their dashboards with every command but `pattern`, `diff`, `filterIndex` and `unmask`; metric filters, subscription filters and Live Tail read Standard groups only, so the patterns they read stay there.

    Events offloaded to S3 stay in your own bucket, outside CloudWatch, until [Retriever](https://doc.log10x.com/apps/retriever/) fetches them back by pattern identity.

??? tenx-compat "Does the 10x Engine work with ECS, EKS, and Lambda"

    Yes. The 10x Engine works with these AWS compute services that send logs to CloudWatch:

    - **ECS (including Fargate):** the Receiver deploys as a sidecar container alongside your log forwarder; the Reporter deploys as a daemonized task for cost visibility before logs reach CloudWatch
    - **EKS:** the Receiver runs as a sidecar container alongside Fluent Bit or OTel Collector; the Reporter deploys as a separate DaemonSet alongside them (logs never pass through it)
    - **EC2:** Process-level deployment alongside your log forwarder (Receiver) or independent process (Reporter)
    - **Lambda:** the [Extension](https://doc.log10x.com/engine/launcher/extension/) runs the engine inside each function's execution environment from the published `tenx-receive` layer, paired with the OTel collector extension, and regulates events before the collector exports them. Events already written to a CloudWatch log group have been billed as CloudWatch ingest, and the [MCP server](https://github.com/log-10x/log10x-mcp){target="_blank"}'s SIEM-sample tool analyzes them agentlessly from the CloudWatch side.

### :material-currency-usd: Cost Optimization

??? tenx-costopt "What's the typical cost reduction for CloudWatch Logs"

    **CloudWatch charges $0.50/GB for log ingestion** (us-east-1, list prices as read on 2026-11-08). A 10TB/month environment pays $5,000/month just to ingest.

    **Down-tier to a cheaper log group:** route the low-value slice to a [CloudWatch Logs Essentials](https://aws.amazon.com/cloudwatch/pricing/){target="_blank"} log group (formerly Infrequent Access) at $0.25/GB ingest, 50% off the $0.50 standard, still queryable in Logs Insights. The saving is ingest-side only: AWS bills storage ($0.03/GB-month) and Logs Insights queries at the same rate in both log classes. Down-tiering half of a 10TB/month volume saves ~$1,250/month (5TB x $0.25 saved).

    Before down-tiering a pattern, check what reads its log group. An Essentials group serves Logs Insights; subscription filters, metric filters, Live Tail, field indexing, and the `GetLogEvents` and `FilterLogEvents` APIs work on Standard groups only. A consumer of any of those sees only the events left in the Standard group, with no error. The log class is fixed when the group is created, so the slice moves to a new Essentials group and the group already in place keeps its class.

    **Offload to your own S3:** route the bulk slice to customer-owned S3 at $0.023/GB-month and fetch it back with [Retriever](https://log10x.com/retriever.html){target="_blank"} only when you query. The offloaded slice pays S3 storage instead of CloudWatch ingest and storage; what Retriever fetches back bills as CloudWatch ingest.

    Down-tiering and offload keep the data reachable. Sampling and drop keep a share of a statement's lines or none. The combined cut depends on how much volume each lever moves: down-tiering halves the ingest rate on the moved slice and leaves its storage charge as it was, and offload keeps the slice out of CloudWatch until Retriever fetches it back.

    *[CloudWatch prices](https://aws.amazon.com/cloudwatch/pricing/){target="_blank"} for us-east-1 from the AWS price list, read 2026-10-10.*

??? tenx-costopt "Can I prevent CloudWatch billing spikes"

    **Yes.** [Receiver](https://doc.log10x.com/apps/receiver/){target="_blank"} reports the cost of each event type (bytes x $/GB) and, once a limit is set, each statement over its limit takes its service's action: its lines over the limit go to the Essentials group, or to the bucket, and every one is kept. The first five lines of every statement in each 4-minute window on each node reach the Standard group whatever the limit, and once a service is past its total, at most 50 such lines per service reach it in each window. Up to 50 lines over the limit of each ERROR, CRITICAL or FATAL statement in each window on each node reach it too, released in four slices across the window, and at most 500 such lines per service in each window once the service is past its total. The Receiver reports cost and enforces each limit in bytes. The daily volume is held by the [scheduled run](https://doc.log10x.com/apps/mcp/tools/install/setup-recurring/){target="_blank"} with `budget_gb_monthly`: each run scales the monthly byte budget to its window, reads each statement's bytes from the Reporter's metrics and rewrites the limits so only the overage takes the action.

    For K8s environments, per-app budgets hold each service to its limit on each node, however many pods it runs there. For per-pattern rates, commit a [mute file](https://doc.log10x.com/run/receive/rate/#protection-list){target="_blank"} to git and let GitOps push it to every receiver.

??? tenx-costopt "How does offload reduce CloudWatch costs"

    [Retriever](https://log10x.com/retriever.html){target="_blank"} reads the logs the Receiver offloads to your own S3, where they are stored at a fraction of CloudWatch costs, and returns selected events on demand to a results location in that bucket. Your own forwarder or script ships them into CloudWatch when they are needed there, so the path runs only through your bucket and your forwarder.

    - **Logs stay reachable in S3,** fetched back by pattern identity when you query
    - **Pay CloudWatch ingestion only** for the events you ship back

### :material-key-variant: Routing Key

??? tenx-costopt "What does 10x add to CloudWatch's own routing"

    An Essentials log group or your own S3 stores the cheaper slice, and today a person writes the rules that choose it: each producer names the log group it writes to, and the group's [log class](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch_Logs_Log_Classes.html){target="_blank"} is fixed when the group is created. The OpenTelemetry Collector's [routing connector](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/connector/routingconnector/README.md){target="_blank"} sends a record to a pipeline on a condition over its attributes, such as `log.severity_text == "ERROR"`; the condition cannot name the log statement a line came from or count one statement's bytes against a number, so its routing table stays as written while each statement's volume changes. 10x keeps those rules current per pattern: the rules key on the pattern, which is the same on every pod from its first line, whatever lines that pod has seen and whenever it started. A template miner at the edge, such as Drain3, names a line by what it has seen: two Drain3 instances that each see half of one stream give a line seen 2 to 10 times different names 39.78% of the time ([pattern-identity benchmark](https://github.com/log-10x/benchmarks/tree/main/pattern-identity){target="_blank"}).

    The [compiler](https://doc.log10x.com/compile/deploy/) runs in CI or on a schedule, so new log statements, including ones a coding agent wrote, are named as the code ships; a [scheduled check](https://doc.log10x.com/apps/mcp/tools/install/setup-recurring/) (`tenx-recur`) costs each pattern, routing changes arrive as pull requests to the [policy repo](https://doc.log10x.com/apps/mcp/tools/install/set-gitops-repo/), and [caps](https://doc.log10x.com/run/receive/rate/) act on their own.

    A moved byte costs $0.25 instead of $0.50 per GB ingested to Essentials, computed at list price from the released engine's counts on a public capture in [benchmarks/cloudwatch-ia-accounting](https://github.com/log-10x/benchmarks/tree/main/cloudwatch-ia-accounting){target="_blank"}.

### :material-wrench-outline: Operations

??? tenx-ops "How does optimization affect log data"

    The levers that move the CloudWatch bill handle data differently. Tier_down and offload keep every line reachable. Sampling and drop keep a share of a statement's lines or none:

    - **[Receiver](https://doc.log10x.com/apps/receiver/){target="_blank"} (tier_down):** Routes the low-value slice to a cheaper Essentials log group, preserving every field and keeping it Logs-Insights queryable
    - **Retriever (offload):** Keeps full data in your own S3 bucket and controls what reaches CloudWatch
    - **[Receiver](https://doc.log10x.com/apps/receiver/){target="_blank"} (sampling and drop):** You choose which event types to sample or discard; these are lossy by design

??? tenx-ops "What is the processing overhead"

    Events arrive in standard CloudWatch format, and Logs Insights searches them as written, with no search-time overhead. On events that stay in a Standard log group, Logs Insights queries, dashboards, metric filters, and alarms work unchanged.

    Memory is capped by the container limit, CPU via `threadPoolSize`. For resource requirements and Kubernetes resource specs, see [Node counting](https://doc.log10x.com/faq/pricing/node-counting/).

??? tenx-ops "What about real-time alerting and monitoring"

    Your CloudWatch alarms and metric filters keep working on every pattern that stays in a Standard group; metric filters run on Standard groups only, so keep patterns that feed a metric filter or alarm there. For alerting on events over a limit, [Receiver](https://doc.log10x.com/apps/receiver/){target="_blank"} can be configured to always pass through error-level logs.

### :material-rocket-launch-outline: Getting Started

??? tenx-start "How do I test this on my CloudWatch logs"

    1. **[Cost POC](../../apps/mcp/tools/poc/)**, install the 10x MCP and ask it for a cost POC on your CloudWatch logs. The MCP reads a sample through the CloudWatch API, or from a Kubernetes cluster through `kubectl`, runs the engine on your own machine, and reports the events and GB per pattern a plan would move to Essentials or your S3, with no account or credit card.
    2. **[Reporter](../../apps/reporter/)**, Deploy as a DaemonSet for cost visibility before logs reach CloudWatch. Alternatively, use the [MCP server](https://github.com/log-10x/log10x-mcp){target="_blank"}'s SIEM-sample tool for agentless analysis via CloudWatch API.
    3. **[Receiver](../../apps/receiver/deploy/)**, Deploy via Helm chart alongside your forwarder. Limits hold each service at its daily volume; the lines over a limit take the service's action, tier_down to an Essentials log group (still Logs-Insights queryable) or offload to the bucket.
    4. **[Retriever](../../apps/retriever/)**, Offload events to your own S3 bucket and fetch selected events back on demand to a results location there, for your own forwarder to ship into CloudWatch.

    Each step is independent: start with the cost POC to see what a plan would move, then move to production when ready.

??? tenx-start "Is the deployment reversible? Can I roll back"

    **Yes.** Rolling back takes minutes:

    - **Configuration change:** point the CloudWatch agent's input back at the application's own log folder
    - **No data migration:** Your existing CloudWatch log groups are unchanged, same structure, same metric filters
    - **No downtime:** Switch traffic with a config reload (no restart required)

    **What stays in place:** The 10x Engine sits between your applications and CloudWatch. Your existing log groups, metric filters and Insights queries stay as they were.

    We recommend keeping a bypass route configured during initial deployment, so the forwarder can send logs straight to CloudWatch and roll back instantly.
