Chat History

SMG supports multiple storage backends for persisting the conversations, conversation items, and stored responses behind the Responses and Conversations APIs, for analytics, debugging, and compliance.


Overview

Multiple Backends

Choose from in-memory, PostgreSQL, Redis, or Oracle based on your requirements.

Conversation Tracking

Store complete conversation history including messages, tool calls, and reasoning.

Configurable Retention

Redis entries expire after --redis-retention-days (default 30 days). The other backends keep data until it's deleted (the in-memory backend, until the gateway restarts).


Backend Comparison

Backend Use Case Persistence Scalability
memory Development, testing Process lifetime Single instance
none Stateless deployments None N/A
postgres Production, self-hosted Durable High
redis Caching, ephemeral storage Configurable TTL High
oracle Enterprise, OCI deployments Durable High

Configuration

Backend Selection

smg --history-backend <backend> [backend-specific options]
Option Default Description
--history-backend memory Storage backend: memory, none, oracle, postgres, redis

Memory Backend

The default in-process storage. Suitable for development and testing.

smg --history-backend memory

✓ Advantages

  • Zero configuration
  • Fast access
  • No external dependencies

✗ Limitations

  • Data lost on restart
  • Not shared across instances
  • Memory grows with conversations

None Backend

Disables history storage entirely. Use for stateless deployments where persistence isn't needed.

smg --history-backend none

Use when: Privacy requirements prohibit storing conversations, or external systems handle logging.


PostgreSQL Backend

Production-ready storage with PostgreSQL.

Configuration Options

Option Default Description
--postgres-db-url - PostgreSQL connection URL
--postgres-pool-max-size 16 Maximum connection pool size

Connection URL Format

postgres://[user[:password]@]host[:port]/database[?param=value]

The scheme can also be postgresql://. SMG requires a host and a database name.

Examples

Basic Connection

smg --history-backend postgres \
  --postgres-db-url "postgres://user:password@localhost:5432/smg"

With a Connect Timeout

smg --history-backend postgres \
  --postgres-db-url "postgres://user:password@db.example.com:5432/smg?connect_timeout=30"

Redis Backend

High-performance caching with optional persistence and TTL-based retention.

Configuration Options

Option Default Description
--redis-url - Redis connection URL
--redis-pool-max-size 16 Maximum connection pool size
--redis-retention-days 30 Data retention in days (-1 for persistent; write it as --redis-retention-days=-1, since the Rust CLI rejects a separate -1 argument)

Connection URL Format

redis://[:password@]host[:port][/db]

Examples

Basic Connection

smg --history-backend redis \
  --redis-url "redis://localhost:6379"

With a Password

smg --history-backend redis \
  --redis-url "redis://:password@redis.example.com:6379"

Persistent Storage

smg --history-backend redis \
  --redis-url "redis://localhost:6379" \
  --redis-retention-days=-1

Oracle Backend

Enterprise-grade storage using Oracle Autonomous Database.

Configuration Options

Option Environment Variable Default Description
--oracle-wallet-path ATP_WALLET_PATH - Path to ATP wallet directory
--oracle-tns-alias ATP_TNS_ALIAS - TNS alias from tnsnames.ora
--oracle-dsn ATP_DSN - Direct connection descriptor
--oracle-user ATP_USER - Database username
--oracle-password ATP_PASSWORD - Database password
--oracle-external-auth ATP_EXTERNAL_AUTH false Use external (OS) authentication instead of username/password; leave --oracle-user and --oracle-password unset
--oracle-pool-min ATP_POOL_MIN 1 Must be at least 1 and at most --oracle-pool-max. The pool opens connections on demand and doesn't hold a minimum open
--oracle-pool-max ATP_POOL_MAX 16 Maximum connection pool size
--oracle-pool-timeout-secs ATP_POOL_TIMEOUT_SECS 30 How long a request waits for a free pooled connection, in seconds. Must be greater than 0

--oracle-dsn takes precedence: with a DSN, SMG ignores the wallet and TNS alias. The Python launcher (smg launch from pip, and the container image) names two of these flags differently, --oracle-username and --oracle-connect-descriptor, and uses the TNS alias when both an alias and a DSN are given. See Python Launcher Differences.

Examples

Using ATP Wallet

smg --history-backend oracle \
  --oracle-wallet-path /path/to/wallet \
  --oracle-tns-alias mydb_high \
  --oracle-user admin \
  --oracle-password "$ORACLE_PASSWORD"

Using Direct DSN

smg --history-backend oracle \
  --oracle-dsn "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db.example.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=myservice)))" \
  --oracle-user admin \
  --oracle-password "$ORACLE_PASSWORD"

Schema Migrations

At startup, the PostgreSQL and Oracle backends create their tables if they don't exist, then compare the database's recorded schema version (the _schema_versions table) with the migrations SMG ships. SMG applies pending migrations only when auto-migration is on. Otherwise it refuses to start and prints the SQL to apply by hand. A new, empty database has pending migrations too, so turn auto-migration on for the first start:

DB_AUTO_MIGRATE=true smg launch --history-backend postgres \
  --postgres-db-url "postgres://user:password@localhost:5432/smg"

DB_AUTO_MIGRATE=true (or 1) turns it on when no --schema-config file sets auto_migrate. In a schema config file, auto_migrate: true turns it on, and version: <n> marks migrations up to <n> as already applied. Redis and the in-memory backend have no migrations. See Schema Migrations.


What Gets Stored

Conversations

Container for a sequence of interactions:

  • Conversation ID
  • Creation timestamp
  • Metadata (the key-value object the client attaches)

Conversation Items

Individual items within a conversation:

Type Description
Messages User and assistant messages with content
Reasoning Model reasoning/thinking steps
Tool Calls Tool invocations and results
MCP Calls MCP server interactions
Function Calls Function calling results

Responses

Complete response records including:

  • Input items
  • Output (model response)
  • Tool calls executed
  • Model information
  • Timestamps and metadata
  • Token usage

Development

In-memory for fast iteration.

smg --history-backend memory

Production (Self-Hosted)

PostgreSQL for durable storage.

smg --history-backend postgres \
  --postgres-db-url "postgres://smg:$DB_PASSWORD@postgres:5432/smg" \
  --postgres-pool-max-size 32

Enterprise (OCI)

Oracle for enterprise deployments.

smg --history-backend oracle \
  --oracle-wallet-path /etc/smg/wallet \
  --oracle-tns-alias smg_high \
  --oracle-user smg_app \
  --oracle-password "$ATP_PASSWORD" \
  --oracle-pool-max 32

Caching Layer

Redis for high-performance ephemeral storage.

smg --history-backend redis \
  --redis-url "redis://:$REDIS_PASSWORD@redis.example.com:6379" \
  --redis-retention-days 7 \
  --redis-pool-max-size 64

Troubleshooting

Symptom Cause Solution
Connection timeouts Slow network Increase pool timeout
Pool exhaustion High concurrency Increase pool size
Data not persisting Wrong backend Verify --history-backend setting
Redis data expiring TTL too short Increase --redis-retention-days

Pool Configuration

# PostgreSQL
--postgres-db-url "postgres://...?connect_timeout=30"
--postgres-pool-max-size 64

# Oracle
--oracle-pool-timeout-secs 60
--oracle-pool-max 64

# Redis
--redis-pool-max-size 64

What's Next?

Authentication

Secure access to your SMG deployment.

Authentication →

Metrics Reference

Monitor storage backend performance.

Metrics Reference →

High Availability

Deploy SMG in a highly available configuration.

High Availability →