> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Infrastructure Backends

> Pluggable backend adapters for interaction storage, event bus, search, caching, and logging — choose the right stack for your scale.

KaireonAI separates business logic from infrastructure through a set of TypeScript interfaces (`lib/infra/interfaces.ts`) and a dependency injection container (`lib/infra/container.ts`). Each infrastructure concern — interaction storage, event publishing, search, caching, and logging — has a default implementation that works out of the box and one or more alternatives that you can activate with a single environment variable.

No code changes are required to switch backends. Set the env var, restart, and the container instantiates the correct adapter as a singleton.

```ts theme={null}
// Business logic imports are always the same — the container handles the rest
import { getCache, getEventPublisher, getInteractionStore, getSearchIndex } from "@/lib/infra/container";

const cache = getCache();
const events = getEventPublisher();
const interactions = getInteractionStore();
const search = getSearchIndex();
```

<Info>
  All infrastructure backends support graceful shutdown. On a termination signal, the platform closes connections cleanly so in-flight requests finish. Switching a backend takes effect on restart — set the environment variable and roll the deployment.
</Info>

***

## Interaction Store

The interaction store persists decision history, customer interactions, impressions, outcomes, and conversion data. It powers the Customer Viewer 360, attribution, and analytics.

<Tabs>
  <Tab title="PostgreSQL (default)">
    **Adapter:** `pg-interaction-store.ts`

    The default. Stores interactions in the same PostgreSQL database as the rest of the platform. Zero additional infrastructure.

    |              |                                                             |
    | ------------ | ----------------------------------------------------------- |
    | **Best for** | Development, small deployments, less than 10K decisions/day |
    | **Config**   | No additional config — uses `DATABASE_URL`                  |
    | **Cost**     | Included with your existing database                        |

    ```bash theme={null}
    # Default — no env var needed
    # INTERACTION_STORE=pg  (implicit)
    ```

    <Warning>
      At high volumes, interaction rows grow fast. Consider moving to DynamoDB or Scylla when you exceed 10K decisions/day or when interaction queries start affecting OLTP performance.
    </Warning>
  </Tab>

  <Tab title="DynamoDB">
    **Adapter:** `dynamodb-interaction-store.ts`

    Serverless, auto-scaling key-value store on AWS. Pay-per-request pricing makes it cost-effective for bursty workloads.

    |                   |                                                             |
    | ----------------- | ----------------------------------------------------------- |
    | **Best for**      | Serverless deployments, auto-scaling on AWS, bursty traffic |
    | **Cost estimate** | \~\$1.25 per million writes (on-demand mode)                |

    ```bash theme={null}
    INTERACTION_STORE=dynamodb
    DYNAMODB_TABLE_NAME=kaireon-interactions   # default
    DYNAMODB_REGION=us-east-1                  # default
    DYNAMODB_AUTH_MODE=iam_role                # default (recommended)
    # OR explicit credentials:
    # DYNAMODB_AUTH_MODE=access_key
    # DYNAMODB_ACCESS_KEY_ID=AKIA...
    # DYNAMODB_SECRET_ACCESS_KEY=...
    # DYNAMODB_ROLE_ARN=arn:aws:iam::...       # for cross-account access
    ```
  </Tab>

  <Tab title="Scylla / Cassandra">
    **Adapter:** `scylla-interaction-store.ts`

    Purpose-built for high-throughput time-series workloads. ScyllaDB is a Cassandra-compatible database written in C++ with significantly lower tail latencies.

    |                   |                                                                |
    | ----------------- | -------------------------------------------------------------- |
    | **Best for**      | Over 100K TPS, time-series interaction workloads, multi-region |
    | **Cost estimate** | \~\$500/mo for a managed 3-node cluster                        |

    ```bash theme={null}
    INTERACTION_STORE=scylla
    SCYLLA_CONTACT_POINTS=node1.example.com,node2.example.com
    SCYLLA_LOCAL_DATACENTER=datacenter1        # default
    SCYLLA_KEYSPACE=kaireon                    # default
    SCYLLA_USERNAME=...
    SCYLLA_PASSWORD=...
    SCYLLA_TLS_ENABLED=true
    SCYLLA_REPLICATION_FACTOR=3
    SCYLLA_CONSISTENCY_LEVEL=LOCAL_QUORUM
    SCYLLA_POOL_SIZE=10
    SCYLLA_REQUEST_TIMEOUT_MS=5000
    ```

    <Info>
      Use `INTERACTION_STORE=cassandra` as an alias — the same adapter works with Apache Cassandra clusters.
    </Info>
  </Tab>

  <Tab title="AWS Keyspaces">
    **Adapter:** `keyspaces-interaction-store.ts`

    Managed Cassandra-compatible service on AWS. No cluster management, automatic scaling, pay-per-request pricing.

    |                   |                                                       |
    | ----------------- | ----------------------------------------------------- |
    | **Best for**      | Managed Cassandra on AWS without operational overhead |
    | **Cost estimate** | \~\$0.30 per million writes                           |

    ```bash theme={null}
    INTERACTION_STORE=keyspaces
    KEYSPACES_KEYSPACE=kaireon                 # default
    KEYSPACES_REGION=us-east-1                 # default
    KEYSPACES_AUTH_MODE=access_key             # default
    KEYSPACES_USERNAME=...
    KEYSPACES_PASSWORD=...
    KEYSPACES_REQUEST_TIMEOUT_MS=10000
    ```
  </Tab>
</Tabs>

***

## Event Bus

The event bus handles asynchronous event routing for decision events, model update notifications, pipeline triggers, and real-time streaming. Every backend supports the same operations: publishing events to a topic, subscribing consumers to receive them, and shutting down cleanly on termination.

<Tabs>
  <Tab title="Redis Pub/Sub (default)">
    **Adapter:** `redis-events.ts`

    Uses your existing Redis instance for lightweight pub/sub messaging. Simple, no additional infrastructure.

    |              |                                                |
    | ------------ | ---------------------------------------------- |
    | **Best for** | Development, staging, low-to-medium throughput |
    | **Config**   | Uses `REDIS_URL` — no additional env vars      |
    | **Cost**     | Included with your Redis instance              |

    ```bash theme={null}
    # Default — no env var needed
    # EVENT_PUBLISHER=redis  (implicit)
    ```

    <Warning>
      Redis Pub/Sub is fire-and-forget — messages are lost if no subscriber is connected. For production workloads requiring durability and replay, use Kafka, MSK, or Kinesis.
    </Warning>
  </Tab>

  <Tab title="Kafka / Redpanda">
    **Adapter:** `kafka-events.ts`

    Apache Kafka or Redpanda for high-throughput, ordered, durable event streaming with consumer groups.

    |                   |                                                              |
    | ----------------- | ------------------------------------------------------------ |
    | **Best for**      | High-throughput, ordering guarantees, event replay           |
    | **Cost estimate** | \~\$200/mo for managed Kafka (Confluent Cloud or equivalent) |

    ```bash theme={null}
    EVENT_PUBLISHER=kafka
    KAFKA_BROKERS=broker1:9092,broker2:9092
    KAFKA_CLIENT_ID=kaireon-platform
    KAFKA_TLS_ENABLED=true
    KAFKA_SASL_MECHANISM=scram-sha-256
    KAFKA_SASL_USERNAME=...
    KAFKA_SASL_PASSWORD=...
    KAFKA_CONSUMER_GROUP_ID=kaireon-consumers
    ```

    <Info>
      Use `EVENT_PUBLISHER=redpanda` as an alias — the same adapter works with Redpanda clusters.
    </Info>
  </Tab>

  <Tab title="AWS MSK">
    **Adapter:** `msk-events.ts`

    Amazon Managed Streaming for Apache Kafka. Fully managed Kafka with IAM authentication and VPC integration.

    |                   |                                          |
    | ----------------- | ---------------------------------------- |
    | **Best for**      | Managed Kafka on AWS with IAM-based auth |
    | **Cost estimate** | \~\$300/mo for a 3-broker cluster        |

    ```bash theme={null}
    EVENT_PUBLISHER=msk
    MSK_BROKERS=b-1.msk.us-east-1.amazonaws.com:9098,b-2.msk.us-east-1.amazonaws.com:9098
    MSK_REGION=us-east-1                       # default
    MSK_AUTH_MODE=iam_role                     # default (recommended)
    MSK_ROLE_ARN=arn:aws:iam::123456:role/msk-access
    MSK_CONSUMER_GROUP_ID=kaireon-consumers
    MSK_TOPIC_PREFIX=kaireon-
    # OR SASL/SCRAM auth:
    # MSK_AUTH_MODE=sasl_scram
    # MSK_SASL_USERNAME=...
    # MSK_SASL_PASSWORD=...
    ```
  </Tab>

  <Tab title="Kinesis">
    **Adapter:** `kinesis-events.ts`

    AWS Kinesis Data Streams for serverless, auto-scaling event ingestion with shard-based parallelism.

    |                   |                                                    |
    | ----------------- | -------------------------------------------------- |
    | **Best for**      | AWS-native, serverless scaling, Lambda integration |
    | **Cost estimate** | \~$0.04 per shard-hour (~$29/mo per shard)         |

    ```bash theme={null}
    EVENT_PUBLISHER=kinesis
    KINESIS_STREAM_NAME=kaireon-events         # default
    KINESIS_REGION=us-east-1                   # default
    KINESIS_AUTH_MODE=iam_role                 # default
    KINESIS_ROLE_ARN=arn:aws:iam::123456:role/kinesis-access
    KINESIS_PARTITION_KEY=tenantId
    # OR explicit credentials:
    # KINESIS_AUTH_MODE=access_key
    # KINESIS_ACCESS_KEY_ID=...
    # KINESIS_SECRET_ACCESS_KEY=...
    ```
  </Tab>

  <Tab title="EventBridge">
    **Adapter:** `eventbridge-events.ts`

    AWS EventBridge for rule-based event routing with native integrations to Lambda, SQS, Step Functions, and more.

    |                   |                                                             |
    | ----------------- | ----------------------------------------------------------- |
    | **Best for**      | AWS-native, rule-based routing, fan-out to multiple targets |
    | **Cost estimate** | \~\$1 per million events                                    |

    ```bash theme={null}
    EVENT_PUBLISHER=eventbridge
    EVENTBRIDGE_BUS_NAME=kaireon-events
    EVENTBRIDGE_REGION=us-east-1               # default
    EVENTBRIDGE_AUTH_MODE=iam_role             # default
    EVENTBRIDGE_ROLE_ARN=arn:aws:iam::123456:role/eb-access
    EVENTBRIDGE_DETAIL_TYPE_PREFIX=kaireon.
    # OR explicit credentials:
    # EVENTBRIDGE_AUTH_MODE=access_key
    # EVENTBRIDGE_ACCESS_KEY_ID=...
    # EVENTBRIDGE_SECRET_ACCESS_KEY=...
    ```
  </Tab>
</Tabs>

***

## Search Index

The search index powers full-text search across offers, categories, decision flows, and other platform entities. It also drives the global search bar and analytics queries.

<Tabs>
  <Tab title="PostgreSQL FTS (default)">
    **Adapter:** `pg-search.ts`

    Uses PostgreSQL's built-in `tsvector` full-text search. No additional infrastructure needed.

    |              |                                              |
    | ------------ | -------------------------------------------- |
    | **Best for** | Under 1M records, simple search queries      |
    | **Config**   | Uses `DATABASE_URL` — no additional env vars |
    | **Cost**     | Included with your existing database         |

    ```bash theme={null}
    # Default — no env var needed
    # SEARCH_INDEX=pg  (implicit)
    ```
  </Tab>

  <Tab title="OpenSearch">
    **Adapter:** `opensearch-search.ts`

    Full-text search and analytics at scale. Supports fuzzy matching, aggregations, and dashboards.

    |                   |                                                           |
    | ----------------- | --------------------------------------------------------- |
    | **Best for**      | Large catalogs, analytics dashboards, fuzzy search        |
    | **Cost estimate** | \~\$200/mo for a managed cluster (AWS OpenSearch Service) |

    ```bash theme={null}
    SEARCH_INDEX=opensearch
    OPENSEARCH_NODE_URL=https://search.example.com:9200
    OPENSEARCH_INDEX_PREFIX=kaireon-            # default
    OPENSEARCH_TLS_ENABLED=true                # default
    OPENSEARCH_TLS_REJECT_UNAUTHORIZED=true    # default
    OPENSEARCH_REQUEST_TIMEOUT_MS=30000
    OPENSEARCH_MAX_RETRIES=3

    # Basic auth:
    OPENSEARCH_AUTH_MODE=basic                  # default
    OPENSEARCH_USERNAME=admin
    OPENSEARCH_PASSWORD=...

    # OR AWS IAM auth:
    # OPENSEARCH_AUTH_MODE=iam
    # OPENSEARCH_REGION=us-east-1
    # OPENSEARCH_ROLE_ARN=arn:aws:iam::123456:role/opensearch-access
    ```
  </Tab>
</Tabs>

***

## Cache

Redis is used for caching enrichment data, sliding-window rate limiting, session storage, circuit breaker state, and background job queues. The cache layer supports standard read, write, and delete operations plus a cache-aside helper that fetches and stores a value in one call when the key is missing.

```bash theme={null}
REDIS_URL=redis://localhost:6379
```

The cache adapter works with any Redis-compatible endpoint:

* **Redis OSS** — local development or self-hosted
* **Amazon ElastiCache** — managed Redis on AWS
* **Upstash Redis** — serverless Redis with per-request pricing
* **Dragonfly** — Redis-compatible, multi-threaded drop-in replacement

<Info>
  Redis is optional in development (the platform falls back to in-process defaults), but **required for production**. Without Redis, rate limiting, enrichment caching, and background job processing will not function correctly.
</Info>

***

## Logging

KaireonAI uses Winston for structured JSON logging. The default console transport works for development and containerized deployments where log aggregation happens at the orchestrator level (e.g., CloudWatch Container Insights, Datadog Agent).

<Tabs>
  <Tab title="Console (default)">
    Structured JSON logs written to stdout/stderr. Works with any log aggregation system that reads container output.

    ```bash theme={null}
    LOG_LEVEL=info  # debug | info | warn | error
    ```
  </Tab>

  <Tab title="CloudWatch">
    **Adapter:** `cloudwatch-logger.ts`

    Adds a Winston transport that batches and sends log events directly to CloudWatch Logs via the AWS SDK. Configured through platform settings (Settings > Observability) rather than environment variables.

    | Setting                        | Description                            |
    | ------------------------------ | -------------------------------------- |
    | `observability_provider`       | Set to `aws_cloudwatch` or `both`      |
    | `cloudwatch_log_group`         | CloudWatch Logs group name             |
    | `cloudwatch_region`            | AWS region (default: `us-east-1`)      |
    | `cloudwatch_auth_mode`         | `iam_role` or `access_key`             |
    | `cloudwatch_role_arn`          | IAM role ARN (for `iam_role` auth)     |
    | `cloudwatch_access_key_id`     | AWS access key (for `access_key` auth) |
    | `cloudwatch_secret_access_key` | AWS secret key (for `access_key` auth) |

    <Info>
      The CloudWatch transport is additive — console logging continues to work alongside it. Use `observability_provider=both` to send logs to CloudWatch and keep console output.
    </Info>
  </Tab>
</Tabs>

***

## Choosing Your Stack

Use these reference architectures as a starting point. Every backend is independently swappable, so you can mix and match based on your requirements.

<AccordionGroup>
  <Accordion title="Development (zero config)" icon="laptop" defaultOpen>
    All defaults. No additional services beyond PostgreSQL and optionally Redis.

    | Concern            | Backend         | Config      |
    | ------------------ | --------------- | ----------- |
    | Interactions       | PostgreSQL      | Default     |
    | Events             | Redis Pub/Sub   | `REDIS_URL` |
    | Search             | PostgreSQL FTS  | Default     |
    | Cache              | Redis           | `REDIS_URL` |
    | Logging            | Console         | Default     |
    | **Estimated cost** | **\$0** (local) |             |
  </Accordion>

  <Accordion title="Startup on AWS (~$50-100/mo)" icon="rocket">
    Lean AWS deployment using managed services with pay-per-use pricing.

    | Concern            | Backend         | Config                        |
    | ------------------ | --------------- | ----------------------------- |
    | Interactions       | PostgreSQL      | Default                       |
    | Events             | EventBridge     | `EVENT_PUBLISHER=eventbridge` |
    | Search             | PostgreSQL FTS  | Default                       |
    | Cache              | Upstash Redis   | `REDIS_URL=rediss://...`      |
    | Logging            | CloudWatch      | Via platform settings         |
    | **Estimated cost** | **\$50-100/mo** |                               |
  </Accordion>

  <Accordion title="Growth on AWS (~$500-1K/mo)" icon="chart-line">
    Higher throughput with dedicated event streaming and search infrastructure.

    | Concern            | Backend         | Config                       |
    | ------------------ | --------------- | ---------------------------- |
    | Interactions       | DynamoDB        | `INTERACTION_STORE=dynamodb` |
    | Events             | MSK or Kafka    | `EVENT_PUBLISHER=msk`        |
    | Search             | OpenSearch      | `SEARCH_INDEX=opensearch`    |
    | Cache              | ElastiCache     | `REDIS_URL=rediss://...`     |
    | Logging            | CloudWatch      | Via platform settings        |
    | **Estimated cost** | **\$500-1K/mo** |                              |
  </Accordion>

  <Accordion title="Enterprise (>$2K/mo)" icon="building">
    Maximum throughput with dedicated high-performance backends.

    | Concern            | Backend                    | Config                     |
    | ------------------ | -------------------------- | -------------------------- |
    | Interactions       | Scylla                     | `INTERACTION_STORE=scylla` |
    | Events             | MSK                        | `EVENT_PUBLISHER=msk`      |
    | Search             | OpenSearch                 | `SEARCH_INDEX=opensearch`  |
    | Cache              | ElastiCache (cluster mode) | `REDIS_URL=rediss://...`   |
    | Logging            | CloudWatch                 | Via platform settings      |
    | **Estimated cost** | **\$2K+/mo**               |                            |
  </Accordion>
</AccordionGroup>

***

## Adding a Custom Backend

Every infrastructure concern is behind a TypeScript interface. To add your own implementation:

<Steps>
  <Step title="Implement the backend contract">
    Add a new adapter alongside the existing infrastructure adapters. Each backend type has a small contract to satisfy:

    * **Interaction store** — record an event, fetch interaction summaries, and shut down cleanly.
    * **Event bus** — publish events to a topic, subscribe consumers, and shut down cleanly.
    * **Search index** — run a search query, index a document, and shut down cleanly.
    * **Cache** — get, set, and delete keys, fetch-or-populate in one call, health-check the connection, and shut down cleanly.
  </Step>

  <Step title="Register in the container">
    Add a new `case` to the corresponding factory function in `container.ts`:

    ```ts theme={null}
    case "my_custom_store": {
      const { MyCustomStore } = require("./my-custom-store");
      interactionStoreInstance = new MyCustomStore({ /* config from env */ });
      break;
    }
    ```
  </Step>

  <Step title="Set the environment variable">
    ```bash theme={null}
    INTERACTION_STORE=my_custom_store
    ```
  </Step>

  <Step title="Deploy">
    Restart the application. The container picks up the new env var and instantiates your implementation. Zero changes in business logic, API routes, or decision flow engine.
  </Step>
</Steps>
