---
title: "Database Adapters"
description: "Understanding PGLite and PostgreSQL adapters in the SQL plugin"
---


The SQL plugin provides two database adapters that extend a common `BaseDrizzleAdapter`:

- **PGLite Adapter** - Embedded PostgreSQL for development and testing
- **PostgreSQL Adapter** - Full PostgreSQL for production environments

## Architecture Overview

Both adapters share the same base functionality through `BaseDrizzleAdapter`, which implements the `IDatabaseAdapter` interface from `@elizaos/core`. The adapters handle:

- Connection management through dedicated managers
- Automatic retry logic for database operations
- Schema introspection and dynamic migrations
- Embedding dimension configuration (default: 384 dimensions)

## PGLite Adapter

The `PgliteDatabaseAdapter` uses an embedded PostgreSQL instance that runs entirely in Node.js.

### Key Features

- **Zero external dependencies** - No PostgreSQL installation required
- **File-based persistence** - Data stored in local filesystem
- **Singleton connection manager** - Ensures single database instance per process
- **Automatic initialization** - Database created on first use

### Implementation Details

```typescript
export class PgliteDatabaseAdapter extends BaseDrizzleAdapter {
  private manager: PGliteClientManager;
  protected embeddingDimension: EmbeddingDimensionColumn = DIMENSION_MAP[384];

  constructor(agentId: UUID, manager: PGliteClientManager) {
    super(agentId);
    this.manager = manager;
    this.db = drizzle(this.manager.getConnection());
  }
}
```

### Connection Management

The `PGliteClientManager` handles:
- Singleton PGLite instance creation
- Data directory resolution and creation
- Connection persistence across adapter instances

## PostgreSQL Adapter

The `PgDatabaseAdapter` connects to a full PostgreSQL database using connection pooling.

### Key Features

- **Connection pooling** - Efficient resource management
- **Automatic retry logic** - Built-in resilience for transient failures
- **Production-ready** - Designed for scalable deployments
- **SSL support** - Secure connections when configured
- **Cloud compatibility** - Works with Supabase, Neon, and other PostgreSQL providers

### Implementation Details

```typescript
export class PgDatabaseAdapter extends BaseDrizzleAdapter {
  protected embeddingDimension: EmbeddingDimensionColumn = DIMENSION_MAP[384];
  private manager: PostgresConnectionManager;

  constructor(agentId: UUID, manager: PostgresConnectionManager, _schema?: any) {
    super(agentId);
    this.manager = manager;
    this.db = manager.getDatabase();
  }

  protected async withDatabase<T>(operation: () => Promise<T>): Promise<T> {
    return await this.withRetry(async () => {
      const client = await this.manager.getClient();
      try {
        const db = drizzle(client);
        this.db = db;
        return await operation();
      } finally {
        client.release();
      }
    });
  }
}
```

### Connection Management

The `PostgresConnectionManager` provides:
- Connection pool management (default size: 20)
- SSL configuration based on environment
- Singleton pattern to prevent multiple pools
- Graceful shutdown handling

## Adapter Selection

The adapter is automatically selected based on environment configuration:

```typescript
export function createDatabaseAdapter(
  config: {
    dataDir?: string;
    postgresUrl?: string;
  },
  agentId: UUID
): IDatabaseAdapter {
  if (config.postgresUrl) {
    // PostgreSQL adapter for production
    if (!globalSingletons.postgresConnectionManager) {
      globalSingletons.postgresConnectionManager = new PostgresConnectionManager(
        config.postgresUrl
      );
    }
    return new PgDatabaseAdapter(agentId, globalSingletons.postgresConnectionManager);
  } else {
    // PGLite adapter for development
    const resolvedDataDir = resolvePgliteDir(config.dataDir);
    if (!globalSingletons.pgLiteClientManager) {
      globalSingletons.pgLiteClientManager = new PGliteClientManager(resolvedDataDir);
    }
    return new PgliteDatabaseAdapter(agentId, globalSingletons.pgLiteClientManager);
  }
}
```

## Migration Handling

**Important**: Both adapters delegate migration handling to the `DatabaseMigrationService`. The adapters themselves do not run migrations directly.

```typescript
// In both adapters:
async runMigrations(): Promise<void> {
  logger.debug('Migrations are handled by the migration service');
  // Migrations are handled by the migration service, not the adapter
}
```

The migration service handles:
- Plugin schema discovery and registration
- Dynamic table creation and updates
- Schema introspection for existing tables
- Dependency resolution for table creation order

## Best Practices

### Development (PGLite)

1. Use default data directory for consistency
2. Clear data directory between test runs if needed
3. Be aware of file system limitations
4. Suitable for single-instance development

### Production (PostgreSQL)

1. Always use connection pooling
2. Configure SSL for secure connections
3. Monitor connection pool usage
4. Use environment variables for configuration
5. Implement proper backup strategies

## Configuration

The SQL plugin automatically selects the appropriate adapter based on environment variables.

### Environment Variables

```bash
# .env file

# For PostgreSQL (production)
POSTGRES_URL=postgresql://user:password@host:5432/database

# For custom PGLite directory (optional)
# If not set, defaults to ./.eliza/.elizadb
PGLITE_DATA_DIR=/path/to/custom/db
```

### Configuration Priority

1. **If `POSTGRES_URL` is set** → Uses PostgreSQL adapter
2. **If `POSTGRES_URL` is not set** → Uses PGLite adapter
   - With `PGLITE_DATA_DIR` if specified
   - Otherwise uses default path: `./.eliza/.elizadb`

### PostgreSQL Configuration

The PostgreSQL adapter supports any PostgreSQL-compatible database:

- **Supabase** - Use the connection string from your project settings
- **Neon** - Use the connection string from your Neon console  
- **Amazon RDS PostgreSQL**
- **Google Cloud SQL PostgreSQL**
- **Self-hosted PostgreSQL** (v12+)

Example connection strings:
```bash
# Supabase
POSTGRES_URL=postgresql://postgres:[password]@[project].supabase.co:5432/postgres

# Neon
POSTGRES_URL=postgresql://[user]:[password]@[project].neon.tech/[database]?sslmode=require

# Standard PostgreSQL
POSTGRES_URL=postgresql://user:password@localhost:5432/mydb
```

## Error Handling

Both adapters include:
- Automatic retry logic (3 attempts by default)
- Exponential backoff between retries
- Detailed error logging
- Graceful degradation

The adapters handle common scenarios like:
- Connection timeouts
- Transient network failures
- Pool exhaustion (PostgreSQL)
- File system errors (PGLite)