---
icon: fontawesome/brands/aws
---

Lambda deploys the 10x Engine as an [AWS Lambda container image](https://docs.aws.amazon.com/lambda/latest/dg/images-create.html){target="\_blank"} that processes [CloudWatch Logs subscription filter](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html){target="\_blank"} events. A thin Python handler bridges the Lambda event format to 10x's [stdin input](https://doc.log10x.com/run/input/stdin/), and the built-in [Fluent Bit output](https://doc.log10x.com/run/output/event/fluentbit/) ships processed events to their destination (e.g., Datadog, Splunk, Elasticsearch).

:material-ice-cream: This launcher employs the [Compiler flavor](https://doc.log10x.com/engine/flavors/#compiler) (container image).

***Use-case***:

Replace log forwarder Lambdas (e.g., [Datadog Forwarder](https://docs.datadoghq.com/logs/guide/forwarder/){target="\_blank"}) with a 10x-powered Lambda that reports, regulates, or optimizes CloudWatch Logs events before shipping to analytics platforms.

## :material-lambda: Benefits

Lambda deployment provides several technical advantages for processing CloudWatch Logs with the 10x Engine:

### :material-package-variant-closed: Zero Infrastructure

No Kubernetes, no sidecars, no persistent forwarders. The Lambda container image includes the 10x Engine, symbol library, Fluent Bit, and Python handler -- everything needed to process and ship logs. CloudWatch's subscription filter delivers batched events; Lambda's built-in retry handles reliability.

### :material-swap-horizontal: Drop-in Replacement

Subscribes to the same CloudWatch Log Groups as existing forwarder Lambdas. No changes to your application logging, CloudWatch configuration, or analytics platform setup.

### :material-snowflake: Cold and Warm Starts

Lambda keeps the container warm across invocations. The 10x Engine loads once on cold start (JIT warms up over the first few invocations), then stays loaded for subsequent calls. Typical cold start overhead is comparable to any JVM-based Lambda.

### :material-server-network: Event-Driven Scaling

Lambda scales automatically with CloudWatch event volume -- no capacity planning or autoscaler tuning. Each invocation processes a batch of events independently, enabling parallel processing across log groups.

## :material-hexagon-multiple-outline: Architecture Flow

<div style="text-align: center;">

```mermaid
graph LR
    A["CloudWatch<br/>Log Group"] -->|"Subscription<br/>Filter"| B["Python Handler<br/>(Decode + Pipe)"]
    B -->|"1. Pipe events<br/>via stdin"| C["10x Engine<br/>(Report/Regulate/Optimize)"]
    C -->|"2. Processed<br/>events"| D["Fluent Bit<br/>(Output Plugin)"]
    D -->|"3. Ship to<br/>destination"| E["Analytics Platforms<br/>(Datadog, Splunk, etc.)"]

    classDef aws fill:#ff9900,stroke:#cc7a00,color:#ffffff,stroke-width:2px,rx:8,ry:8
    classDef tenx fill:#059669,stroke:#047857,color:#ffffff,stroke-width:2px,rx:8,ry:8
    classDef handler fill:#8b5cf6,stroke:#7c3aed,color:#ffffff,stroke-width:2px,rx:8,ry:8
    classDef forwarder fill:#3b82f6,stroke:#1d4ed8,color:#ffffff,stroke-width:2px,rx:8,ry:8
    classDef destination fill:#6b7280,stroke:#4b5563,color:#ffffff,stroke-width:2px,rx:8,ry:8

    class A aws
    class B handler
    class C tenx
    class D forwarder
    class E destination
```

</div>

<div class="diagram-controls">
    <button class="md-button md-button--primary enlarge-diagram"
            onclick="enlargeDiagram(this)"
            data-diagram="lambda"
            data-tooltip="Click to enlarge diagram">
        <span class="twemoji">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
                <path d="M10 2c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9L20.59 19l-1.41 1.41-4.09-4.09A7.84 7.84 0 0 1 10 18c-4.42 0-8-3.58-8-8s3.58-8 8-8m0 2a6 6 0 1 0 0 12 6 6 0 0 0 0-12m1 3h2v2h-2V7m-4 0h2v2H7V7m2 4h2v2H9v-2Z"/>
            </svg>
        </span>
        Enlarge Diagram
    </button>
</div>
<!-- Mermaid enhanced diagram functionality loaded via external files -->

**1. CloudWatch delivers** batched log events (~256KB compressed, hundreds to thousands of events per invocation) via subscription filter.

**2. Python handler decodes** the gzip+base64 payload and pipes raw log lines to the 10x Engine's stdin.

**3. 10x Engine processes** the stream -- reporting, regulating, or optimizing events based on the selected app.

**4. Fluent Bit ships** processed events to the configured analytics platform using its native [output plugins](https://doc.log10x.com/run/output/event/fluentbit/) (Datadog, Splunk, Elasticsearch, CloudWatch). CloudWatch metadata (log group, log stream) is preserved as tags.

## :material-rocket-launch: Deployment

??? tenx-bootstrap "Step 1: Prerequisites"

    | Requirement | Description |
    |-------------|-------------|
    | Log10x License | Your license key ([get one](https://doc.log10x.com/run/bootstrap/#apikey)) |
    | AWS CLI | [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html){target="\_blank"} installed and configured |
    | Docker | For building the container image |
    | ECR Repository | An [ECR repository](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html){target="\_blank"} to push the image to |
    | IAM Role | Lambda execution role with CloudWatch Logs read permissions |

??? tenx-helm "Step 2: Build Container Image"

    The Dockerfile extends the standard [10x Docker image](https://doc.log10x.com/install/docker/) with the AWS Lambda Runtime Interface Client:

    ``` { .console .copy }
    git clone https://github.com/log-10x/docker-images.git
    cd docker-images/lambda
    docker build -t 10x-lambda .
    ```

??? tenx-config "Step 3: Push to ECR"

    Replace `<account>` with your AWS account ID and `<region>` with your AWS region (e.g., `us-east-1`):

    ``` { .console .copy }
    aws ecr get-login-password | docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com
    docker tag 10x-lambda <account>.dkr.ecr.<region>.amazonaws.com/10x-lambda:latest
    docker push <account>.dkr.ecr.<region>.amazonaws.com/10x-lambda:latest
    ```

??? tenx-mainconfig "Step 4: Create Lambda Function"

    Replace the following values before running:

    - `<account>`, your AWS account ID
    - `<region>`, your AWS region (e.g., `us-east-1`)
    - `<lambda-execution-role>`, name of an IAM role with CloudWatch Logs read and ECR pull permissions
    - `<your-10x-key>`, your Log10x API key ([get one](https://doc.log10x.com/run/bootstrap/#apikey))
    - `<your-dd-key>`, your Datadog API key (or substitute with credentials for your destination)

    ``` { .console .copy }
    aws lambda create-function \
        --function-name 10x-lambda \
        --package-type Image \
        --code ImageUri=<account>.dkr.ecr.<region>.amazonaws.com/10x-lambda:latest \
        --role arn:aws:iam::<account>:role/<lambda-execution-role> \
        --memory-size 512 \
        --timeout 300 \
        --environment "Variables={TENX_LICENSE_KEY=<your-license-jwt>,DD_API_KEY=<your-dd-key>,TENX_APP=@apps/receiver}"
    ```

    **Environment Variables:**

    | Variable | Required | Description |
    |----------|----------|-------------|
    | `TENX_LICENSE_KEY` | No | Log10x license JWT ([licensing](https://doc.log10x.com/manage/license/)); unset, the engine runs on the built-in evaluation license |
    | `TENX_APP` | No | App to run: `@apps/reporter`, `@apps/receiver`, or `@apps/receiver` (default: reporter) |
    | `TENX_EXTRA_ARGS` | No | Additional CLI arguments for the 10x Engine |

    **Output destination** is controlled by the 10x pipeline configuration, which uses [Fluent Bit output plugins](https://doc.log10x.com/run/output/event/fluentbit/) to ship processed events. Set the appropriate environment variables for your destination:

    | Destination | Environment Variables |
    |-------------|----------------------|
    | Datadog | `DD_API_KEY`, `DD_SITE` (default: `datadoghq.com`) |
    | Splunk | `SPLUNK_HOST`, `SPLUNK_PORT`, `SPLUNK_HEC_TOKEN` |
    | Elasticsearch | `ELASTICSEARCH_HOST`, `ELASTICSEARCH_PORT`, `ELASTICSEARCH_USERNAME`, `ELASTICSEARCH_PASSWORD` |
    | CloudWatch | [AWS credentials](https://docs.fluentbit.io/manual/administration/aws-credentials){target="\_blank"} via IAM role or env vars |

    **Resource Recommendations:**

    | Setting | Recommended | Notes |
    |---------|-------------|-------|
    | Memory | 512 MB - 1 GB | 10x Engine + symbol library. 1 GB recommended for production |
    | Timeout | 300 seconds | Generous for large batches; most invocations complete in seconds |
    | Concurrency | Start with 10 | Scale up based on log group volume |

    **Performance Tuning:**

    Lambda processes finite batches of events (not continuous streams), so two defaults are worth overriding via `TENX_EXTRA_ARGS`:

    | Override | Value | Why |
    |----------|-------|-----|
    | [threadPoolSize](https://doc.log10x.com/run/transform/parallelize/#paralleleventthreadpoolsize) | `1` | Lambda has limited vCPUs (~0.6 per 1 GB memory). A single thread avoids contention overhead |
    | [groupFlushTimeout](https://doc.log10x.com/run/transform/group/#groupflushtimeout) | `200ms` | Default 5s adds unnecessary latency. Lambda batches are finite, so groups seal quickly |

    Set these via the `TENX_EXTRA_ARGS` environment variable:

    ```
    TENX_EXTRA_ARGS=overrideKey groupFlushTimeout overrideValue $=parseDuration("200ms") overrideKey threadPoolSize overrideValue 1
    ```

??? tenx-keyfiles "Step 5: Subscribe to CloudWatch Log Group"

    Replace the following values before running:

    - `<your-log-group>`, the CloudWatch Log Group to subscribe (e.g., `/aws/lambda/my-app`)
    - `<region>`, your AWS region
    - `<account>`, your AWS account ID

    ``` { .console .copy }
    aws logs put-subscription-filter \
        --log-group-name <your-log-group> \
        --filter-name 10x-optimizer \
        --filter-pattern "" \
        --destination-arn arn:aws:lambda:<region>:<account>:function:10x-lambda
    ```

    Repeat for each log group you want to optimize. Use `--filter-pattern` to target specific log events if needed.

??? tenx-checklist "Step 6: Verify"

    **Trigger a test invocation** using the sample event included in the `docker-images/lambda` repository:

    ``` { .console .copy }
    aws lambda invoke \
        --function-name 10x-lambda \
        --payload file://test-event.json \
        /tmp/response.json
    ```

    **Check CloudWatch Logs for the Lambda function itself:**

    ``` { .console .copy }
    aws logs tail /aws/lambda/10x-lambda --follow
    ```

    Verify no errors appear. Processed events should appear in your analytics platform shortly after invocation.

??? tenx-run "App Selection"

    The same edge apps work in Lambda -- choose based on your goal:

    - **[Reporter](https://doc.log10x.com/apps/reporter/)** (`@apps/reporter`): Visibility into log costs by event type. Start here
    - **[Receiver, Filter mode](https://doc.log10x.com/apps/receiver/)** (`@apps/receiver`): Cap noisy events with rate-based policies
    - **[Receiver, Compact mode](https://doc.log10x.com/apps/receiver/compact/)** (`@apps/receiver`): Lossless volume reduction where the destination supports it
