---
id: "titan/modules/module-map"
title: "Module map"
description: "How the 16 modules relate, depend on one another, and combine."
---

# Module map

A bird's-eye view of every module in the Titan ecosystem — who
depends on whom, who can substitute for whom, and which
combinations show up in real backends.

## Dependency graph

```mermaid
flowchart TB
  subgraph Builtin["Built-in (ship with @omnitron-dev/titan)"]
    Config[config]
    Logger[logger]
  end

  subgraph Foundations["Foundation modules"]
    Redis[titan-redis]
    Events[titan-events]
    Database[titan-database]
  end

  subgraph Observability["Observability"]
    Health[titan-health]
    Metrics[titan-metrics]
    Telemetry[titan-telemetry-relay]
  end

  subgraph Coordination["Coordination & runtime"]
    Lock[titan-lock]
    Scheduler[titan-scheduler]
    PM[titan-pm]
    Discovery[titan-discovery]
  end

  subgraph Surface["Surface modules"]
    Auth[titan-auth]
    Cache[titan-cache]
    RateLimit[titan-ratelimit]
    Notifications[titan-notifications]
  end

  Lock --> Redis
  Discovery --> Redis
  Cache -. L2 tier .-> Redis
  RateLimit -. redis storage .-> Redis
  Notifications --> Redis
  Scheduler -. redis persistence .-> Redis

  Health -. db indicator .-> Database
  Health -. redis indicator .-> Redis

  Notifications -. preference store .-> Database
  Telemetry -. ships .-> Metrics

  Auth -. token cache .-> Cache

  classDef builtin    fill:#e8f5e9,stroke:#43a047,color:#1b5e20
  classDef found      fill:#e3f2fd,stroke:#1976d2,color:#0d47a1
  classDef obs        fill:#fff8e1,stroke:#fb8c00,color:#e65100
  classDef coord      fill:#f3e5f5,stroke:#8e24aa,color:#4a148c
  classDef surf       fill:#fce4ec,stroke:#d81b60,color:#880e4f

  class Config,Logger          builtin
  class Redis,Events,Database  found
  class Health,Metrics,Telemetry obs
  class Lock,Scheduler,PM,Discovery coord
  class Auth,Cache,RateLimit,Notifications surf
```

Solid arrows are **hard dependencies** — you can't run the
dependent module without the foundation. Dotted arrows are
**soft / optional** — feature flagged at config time
(`storageType: 'redis'`, `multiTier: true`, `enableDatabaseIndicator: true`).

## Install footprint

The numbers below count peer modules a typical adoption pulls in
(transitive Redis client, postgres driver, etc. are omitted):

| You install             | What else lights up                                       |
| ----------------------- | --------------------------------------------------------- |
| `titan-events`          | Standalone                                                |
| `titan-redis`           | Standalone                                                |
| `titan-database`        | Standalone (+ db driver)                                  |
| `titan-cache`           | Standalone (`+ titan-redis` if `multiTier: true`)         |
| `titan-lock`            | `+ titan-redis`                                           |
| `titan-discovery`       | `+ titan-redis`                                           |
| `titan-ratelimit`       | Standalone (`+ titan-redis` if `storageType: 'redis'`)    |
| `titan-notifications`   | `+ titan-redis` (`+ titan-database` for preference store) |
| `titan-scheduler`       | Standalone (`+ titan-redis` for distributed persistence)  |
| `titan-auth`            | Standalone (`+ titan-cache` for token cache)              |
| `titan-health`          | Standalone (indicators light up per `enableXxxIndicator`) |
| `titan-metrics`         | Standalone (`+` storage driver if persisting)             |
| `titan-telemetry-relay` | Standalone (paired with `titan-metrics` at remote end)    |
| `titan-pm`              | Standalone                                                |

The framework deliberately keeps modules independently versionable —
you only pull in what you actually use.

## Common stacks

### Web API service

<span class="module-badge">built-in · @omnitron-dev/titan · config + logger</span>
<span class="module-badge">official · titan-redis + titan-database + titan-cache + titan-auth + titan-health + titan-metrics</span>

```mermaid
flowchart LR
  C[config + logger] --> R[titan-redis]
  R --> Ca[titan-cache]
  R --> A[titan-auth]
  D[titan-database] --> H[titan-health]
  R --> H
  C --> M[titan-metrics]
```

Common starting set for any REST / RPC backend.

### Worker fleet

<span class="module-badge">built-in · @omnitron-dev/titan · config + logger</span>
<span class="module-badge">official · titan-redis + titan-database + titan-lock + titan-scheduler + titan-metrics + titan-health</span>

```mermaid
flowchart LR
  C[config + logger] --> R[titan-redis]
  R --> L[titan-lock]
  R --> S[titan-scheduler]
  D[titan-database] --> H[titan-health]
  C --> M[titan-metrics]
```

`titan-lock` is what stops two workers running the same job.

### Notification gateway

<span class="module-badge">built-in · @omnitron-dev/titan · config + logger</span>
<span class="module-badge">official · titan-redis + titan-notifications + titan-ratelimit + titan-metrics</span>

```mermaid
flowchart LR
  C[config + logger] --> R[titan-redis]
  R --> N[titan-notifications]
  R --> RL[titan-ratelimit]
  C --> M[titan-metrics]
```

`titan-ratelimit` shields the upstream provider; `titan-metrics`
records throughput / failures by channel.

### Multi-instance app

Add **`titan-discovery`** to any of the above when you have more
than one pod and want to address services without hard-coded URLs.

### Edge / offline node

<span class="module-badge">official · titan-telemetry-relay · stable</span>

Add `titan-telemetry-relay` when the node may be disconnected from
the central metrics endpoint — it buffers samples to SQLite and
flushes when connectivity returns.

## Similar modules — when which?

| Need                              | Reach for                                                      | Why                                               |
| --------------------------------- | -------------------------------------------------------------- | ------------------------------------------------- |
| Sync in-process pub/sub           | [`titan-events`](/docs/titan/modules/events)                   | Fire-and-forget, intra-process, typed channels    |
| Reliable cross-pod queue          | [`titan-notifications`](/docs/titan/modules/notifications)     | Built on rotif; survives crashes, has DLQ + retry |
| Periodic work (cron / interval)   | [`titan-scheduler`](/docs/titan/modules/scheduler)             | Per-job persistence + missed-fire handling        |
| Memoize a function call           | [`titan-cache`](/docs/titan/modules/cache)                     | `@Cacheable(...)` decorator; multi-tier (L1+L2)   |
| Talk to Redis directly            | [`titan-redis`](/docs/titan/modules/redis)                     | Just a typed client; no service abstraction       |
| Throttle calls                    | [`titan-ratelimit`](/docs/titan/modules/ratelimit)             | Token-bucket / sliding-window / fixed-window      |
| Coordinate across instances       | [`titan-lock`](/docs/titan/modules/lock)                       | Redis-backed mutex with UUID ownership            |
| Spawn / supervise child processes | [`titan-pm`](/docs/titan/modules/pm)                           | Worker pools, IPC, crash supervision              |
| Find sibling services             | [`titan-discovery`](/docs/titan/modules/discovery)             | Heartbeat-based service registry                  |
| Count / measure                   | [`titan-metrics`](/docs/titan/modules/metrics)                 | Counters, gauges, histograms; Prom exposition     |
| Ship metrics off-host             | [`titan-telemetry-relay`](/docs/titan/modules/telemetry-relay) | Store-and-forward; survives offline windows       |
| Check it's alive                  | [`titan-health`](/docs/titan/modules/health)                   | k8s probes + custom indicators                    |
| Authenticate RPC callers          | [`titan-auth`](/docs/titan/modules/auth)                       | JWT (HS256/RS256/ES256), JWKS, token cache        |
| Query a database                  | [`titan-database`](/docs/titan/modules/database)               | Kysely + migrations + RLS                         |
| Validated config                  | [`config`](/docs/titan/modules/config) (built-in)              | Layered, validated, hot-reloadable                |
| Structured logging                | [`logger`](/docs/titan/modules/logger) (built-in)              | pino under the hood; transports + processors      |

## Replacement / overlap matrix

| Module                  | Closest overlap                    | When to prefer                                    |
| ----------------------- | ---------------------------------- | ------------------------------------------------- |
| `titan-events`          | `titan-notifications`              | In-process / no persistence / lowest latency      |
| `titan-notifications`   | `titan-events` + `titan-scheduler` | Cross-process, retry, DLQ, channel templating     |
| `titan-cache`           | bare `titan-redis`                 | Caching semantics (`@Cacheable`, TTL, multi-tier) |
| `titan-scheduler`       | `setInterval` / `node-cron`        | Persistence, missed-fire, observability           |
| `titan-lock`            | bare `SETNX` on Redis              | Safe ownership (UUID) + Lua-script atomicity      |
| `titan-discovery`       | env-var URL config                 | Dynamic topology, autoscaling, rolling deploys    |
| `titan-metrics`         | `prom-client`                      | Native persistence + cross-pod aggregation        |
| `titan-telemetry-relay` | direct Prom scrape                 | Edge / offline / store-and-forward                |
| `titan-health`          | rolling-your-own `/healthz`        | Standard k8s probe shapes + indicator registry    |
| `titan-auth`            | manual JWT verification            | JWKS rotation, token cache, RBAC primitives       |

## Where Redis sits

Five official modules use Redis as their primary backend. They
share the same `Redis` client provided by `titan-redis`:

```mermaid
flowchart LR
  R[(Redis)]
  R --- L[titan-lock]
  R --- D[titan-discovery]
  R --- Ca[titan-cache L2]
  R --- RL[titan-ratelimit]
  R --- N[titan-notifications]
```

Register `TitanRedisModule.forRoot(...)` once at app boot; all
five pick up the connection automatically.

```typescript
@Module({
  imports: [
    TitanRedisModule.forRoot({ config: { url: env.REDIS_URL } }),
    TitanLockModule.forRoot(),
    DiscoveryModule.forRoot(),
    TitanCacheModule.forRoot({ multiTier: true, l2: { /* picked up */ } }),
    TitanRateLimitModule.forRoot({ storageType: 'redis' }),
    NotificationsModule.forRoot({ /* … */ }),
  ],
})
class AppModule {}
```

**Recommended Redis-DB split** (avoid keyspace collisions):

| DB | Purpose                                    |
| -- | ------------------------------------------ |
| 0  | App data (cache, sessions, business state) |
| 1  | Queues / pub-sub (notifications, events)   |
| 2  | Rate limits                                |
| 3  | Locks (`titan-lock`)                       |
| 4  | Discovery registry                         |

Configure per-module by passing a different `db:` index in the
options, or by registering multiple named Redis clients via
`TitanRedisModule.forFeature(['cache', 'queue', …])` (or the
`clients: [...]` option on `forRoot`).

## Lifecycle order — first to last

The container resolves lifecycle in dependency order:

```mermaid
flowchart TB
  Start([App start])
  Start --> Config[ConfigModule]
  Config --> Logger[LoggerModule]
  Logger --> Redis[TitanRedisModule]
  Logger --> Database[TitanDatabaseModule]
  Redis --> Lock[TitanLockModule]
  Redis --> Discovery[DiscoveryModule]
  Redis --> Cache[TitanCacheModule]
  Redis --> RateLimit[TitanRateLimitModule]
  Redis --> Notif[NotificationsModule]
  Database --> Health[TitanHealthModule]
  Redis --> Health
  Database --> Scheduler[TitanSchedulerModule]
  Cache --> Auth[TitanAuthModule]
  Logger --> Metrics[TitanMetricsModule]
  Metrics --> Telemetry[TelemetryRelay]
  Metrics --> User[Your services]
  Auth --> User
  Health --> Ready([App ready])
  User --> Ready
```

On shutdown, the reverse order is followed — user services drain
first, then surface modules, then foundations, then logger / config
last. The exact reverse ensures dependants always stop before
their dependencies.

## Picking the right tier

| Question                                         | Tier                                                               |
| ------------------------------------------------ | ------------------------------------------------------------------ |
| Always available, smallest install?              | **Built-in**                                                       |
| Battle-tested, official, individually versioned? | **Official**                                                       |
| Niche need, no official equivalent yet?          | **Community** (audit first)                                        |
| Want to publish your own?                        | [Authoring a module](/docs/titan/modules-system/authoring-modules) |

## See also

- [Modules index](/docs/titan/modules) — flat list by tier
- [Authoring a module](/docs/titan/modules-system/authoring-modules) —
  conventions every official module follows
- [Recipes](/docs/titan/recipes) — concrete combinations that solve
  real problems