# Configuration

ioredis provides comprehensive configuration options for customizing connection behavior, performance characteristics, and operational features. Configuration applies to both standalone Redis connections and cluster deployments.

## Capabilities

### Redis Options

Core configuration interface for Redis connections with extensive customization capabilities.

```typescript { .api }
interface RedisOptions {
  // Connection settings
  host?: string;                    // default: "localhost"
  port?: number;                   // default: 6379
  path?: string;                   // Unix socket path
  username?: string;               // Redis 6+ ACL username
  password?: string;               // Authentication password
  db?: number;                     // Database index (default: 0)
  
  // Network configuration
  family?: 4 | 6;                  // IP version (default: 4)
  keepAlive?: number;              // TCP keep-alive (default: 0)
  noDelay?: boolean;               // Disable Nagle's algorithm (default: true)
  connectTimeout?: number;         // Connection timeout ms (default: 10000)
  commandTimeout?: number;         // Command timeout ms
  socketTimeout?: number;          // Socket timeout ms
  
  // Retry and reconnection
  retryStrategy?: (times: number) => number | void | null;
  reconnectOnError?: (err: Error) => boolean | 1 | 2 | null;
  lazyConnect?: boolean;           // Delay connection (default: false)
  maxRetriesPerRequest?: number | null; // Max retries per command (default: 20)
  
  // Queue and performance
  enableOfflineQueue?: boolean;    // Queue when disconnected (default: true)
  enableReadyCheck?: boolean;      // Wait for server ready (default: true)
  enableAutoPipelining?: boolean;  // Auto batch commands (default: false)
  autoPipeliningIgnoredCommands?: string[]; // Commands to exclude from autopipelining
  
  // Pub/Sub behavior
  autoResubscribe?: boolean;       // Resubscribe on reconnect (default: true)
  autoResendUnfulfilledCommands?: boolean; // Resend pending commands (default: true)
  
  // Data handling
  stringNumbers?: boolean;         // Return numbers as strings (default: false)
  
  // Advanced options
  connectionName?: string;         // Connection identifier
  readOnly?: boolean;              // Read-only mode (default: false)
  monitor?: boolean;               // Monitor mode (default: false)
  
  // Custom commands and connectors
  scripts?: Record<string, ScriptDefinition>;
  Connector?: ConnectorConstructor;
}

interface ScriptDefinition {
  lua: string;
  numberOfKeys?: number;
  readOnly?: boolean;
}
```

**Usage Examples:**

```typescript
import Redis from "ioredis";

// Basic configuration
const redis = new Redis({
  host: "redis.example.com",
  port: 6380,
  password: "secret",
  db: 1
});

// Advanced configuration
const redis2 = new Redis({
  host: "redis.example.com",  
  port: 6379,
  username: "app-user",
  password: "secure-password",
  
  // Network settings
  connectTimeout: 5000,
  commandTimeout: 2000,
  keepAlive: 30000,
  
  // Retry strategy
  retryStrategy: (times) => {
    const delay = Math.min(times * 50, 2000);
    console.log(`Retrying connection in ${delay}ms (attempt ${times})`);
    return delay;
  },
  
  // Performance optimization
  enableAutoPipelining: true,
  autoPipeliningIgnoredCommands: ["subscribe", "psubscribe"],
  
  // Connection behavior
  lazyConnect: true,
  enableOfflineQueue: false,
  maxRetriesPerRequest: 3
});
```

### Sentinel Configuration

Configuration options for Redis Sentinel deployments with high availability features.

```typescript { .api }
interface SentinelConnectionOptions extends RedisOptions {
  sentinels: SentinelAddress[];
  name: string;                    // Master name in Sentinel
  role?: "master" | "slave";       // Preferred role (default: "master")
  sentinelRetryStrategy?: (times: number) => number | void | null;
  enableTLSForSentinelMode?: boolean; // TLS for Sentinel (default: false)
  updateSentinels?: boolean;       // Update Sentinel list (default: true)
  failoverDetector?: boolean;      // Active failover detection (default: false)
  sentinelCommandTimeout?: number; // Sentinel command timeout
}

interface SentinelAddress {
  host: string;
  port: number;
  username?: string;
  password?: string;
}
```

**Usage Examples:**

```typescript
// Sentinel configuration
const redis = new Redis({
  sentinels: [
    { host: "sentinel1.example.com", port: 26379 },
    { host: "sentinel2.example.com", port: 26379 },
    { host: "sentinel3.example.com", port: 26379 }
  ],
  name: "mymaster",
  role: "master",
  
  // Sentinel-specific retry strategy
  sentinelRetryStrategy: (times) => {
    return times < 5 ? times * 1000 : null;
  },
  
  // Regular Redis options also apply
  password: "redis-password",
  db: 0,
  connectTimeout: 10000
});
```

### TLS Configuration

Secure connections using TLS/SSL encryption for Redis and Sentinel connections.

```typescript { .api }
interface TLSOptions {
  host?: string;
  port?: number;
  ca?: string | Buffer | Array<string | Buffer>;
  cert?: string | Buffer;
  key?: string | Buffer;
  passphrase?: string;
  servername?: string;
  rejectUnauthorized?: boolean;
  checkServerIdentity?: (servername: string, cert: any) => Error | undefined;
}

interface RedisOptions {
  // ... other options
  tls?: TLSOptions;
  enableTLSForSentinelMode?: boolean;
}
```

**Usage Examples:**

```typescript
import * as fs from 'fs';

// TLS configuration
const redis = new Redis({
  host: "redis.example.com",
  port: 6380,
  tls: {
    ca: fs.readFileSync('/path/to/ca.crt'),
    cert: fs.readFileSync('/path/to/client.crt'),
    key: fs.readFileSync('/path/to/client.key'),
    passphrase: 'key-passphrase',
    rejectUnauthorized: true
  }
});

// TLS with Sentinel
const redis2 = new Redis({
  sentinels: [
    { host: "sentinel.example.com", port: 26379 }
  ],
  name: "mymaster",
  enableTLSForSentinelMode: true,
  tls: {
    rejectUnauthorized: false  // For self-signed certificates
  }
});
```

## Retry Strategies

### Connection Retry Strategy

Customize reconnection behavior when the connection is lost.

```typescript { .api }
type RetryStrategy = (times: number) => number | void | null;

interface RedisOptions {
  retryStrategy?: RetryStrategy;
}
```

**Usage Examples:**

```typescript
const redis = new Redis({
  host: "redis.example.com",
  retryStrategy: (times) => {
    // Exponential backoff with jitter
    const delay = Math.min(times * 50, 2000) + Math.random() * 100;
    
    // Give up after 10 attempts
    if (times > 10) {
      return null;
    }
    
    console.log(`Retrying connection in ${delay}ms (attempt ${times})`);
    return delay;
  }
});

// Fixed delay retry
const redis2 = new Redis({
  retryStrategy: (times) => times < 5 ? 1000 : null
});

// No retry
const redis3 = new Redis({
  retryStrategy: () => null
});
```

### Reconnect on Error Strategy

Control reconnection behavior for specific error conditions.

```typescript { .api }
type ReconnectOnError = (err: Error) => boolean | 1 | 2 | null;

interface RedisOptions {
  reconnectOnError?: ReconnectOnError;
}
```

**Usage Examples:**

```typescript
const redis = new Redis({
  reconnectOnError: (err) => {
    const targetErrors = [
      'READONLY',
      'ECONNRESET', 
      'ETIMEDOUT'
    ];
    
    // Reconnect for specific errors
    return targetErrors.some(targetError => 
      err.message.includes(targetErrors)
    );
  }
});

// Always reconnect on error (return 1 or 2)
const redis2 = new Redis({
  reconnectOnError: () => 1  // 1 = reconnect, 2 = reconnect and resend
});
```

## Performance Configuration

### Auto Pipelining

Enable automatic command batching for improved performance.

```typescript { .api }
interface RedisOptions {
  enableAutoPipelining?: boolean;
  autoPipeliningIgnoredCommands?: string[];
}
```

**Usage Examples:**

```typescript
const redis = new Redis({
  enableAutoPipelining: true,
  
  // Commands that should not be auto-pipelined
  autoPipeliningIgnoredCommands: [
    'subscribe',
    'psubscribe', 
    'monitor',
    'ping'
  ]
});

// Check auto-pipeline queue size
console.log(`Queue size: ${redis.autoPipelineQueueSize}`);
```

### Command Timeouts

Configure timeouts for different operations.

```typescript { .api }
interface RedisOptions {
  connectTimeout?: number;         // Connection establishment timeout
  commandTimeout?: number;         // Individual command timeout  
  socketTimeout?: number;          // Socket inactivity timeout
}
```

**Usage Examples:**

```typescript
const redis = new Redis({
  connectTimeout: 5000,    // 5 seconds to establish connection
  commandTimeout: 2000,    // 2 seconds per command
  socketTimeout: 30000     // 30 seconds socket inactivity
});
```

## Custom Scripts

Define Lua scripts as custom Redis commands with proper typing support.

```typescript { .api }
interface RedisOptions {
  scripts?: Record<string, ScriptDefinition>;
}

interface ScriptDefinition {
  lua: string;               // Lua script content
  numberOfKeys?: number;     // Number of Redis keys in script
  readOnly?: boolean;        // Script only reads data
}
```

**Usage Examples:**

```typescript
const redis = new Redis({
  scripts: {
    // Custom increment with limit script
    incrementWithLimit: {
      lua: `
        local key = KEYS[1]
        local limit = tonumber(ARGV[1])
        local current = tonumber(redis.call('GET', key) or 0)
        
        if current < limit then
          return redis.call('INCR', key)
        else
          return current
        end
      `,
      numberOfKeys: 1,
      readOnly: false
    },
    
    // Read-only aggregation script
    sumHash: {
      lua: `
        local key = KEYS[1]
        local hash = redis.call('HGETALL', key)
        local sum = 0
        
        for i = 2, #hash, 2 do
          sum = sum + tonumber(hash[i])
        end
        
        return sum
      `,
      numberOfKeys: 1,
      readOnly: true
    }
  }
});

// Use custom scripts (TypeScript will provide typing)
const result = await redis.incrementWithLimit("counter", 100);
const sum = await redis.sumHash("stats");
```

## Types

```typescript { .api }
type Callback<T> = (err?: Error | null, result?: T) => void;
type ConnectorConstructor = new (options: any) => any;

interface StandaloneConnectionOptions {
  host?: string;
  port?: number;
  path?: string;
}

interface CommonRedisOptions {
  username?: string;
  password?: string;
  db?: number;
  connectionName?: string;
  readOnly?: boolean;
}
```