# How to Configure a Custom Strategy in FreeLLMAPI: Complete Guide

> Learn how to configure a custom strategy in FreeLLMAPI by setting the routing strategy and supplying your own weight vector. Follow this complete guide for efficient setup.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: how-to-guide
- Published: 2026-08-26

---

**To configure a Custom Strategy in FreeLLMAPI, set the active routing strategy to `'custom'` via `setRoutingStrategy()` and supply your own weight vector through `setCustomWeights()`, which persists normalized values to the `routing_custom_weights` key in the settings store.**

FreeLLMAPI routes every LLM request through a configurable strategy that determines how models are scored and selected. While the platform provides built-in strategies like `priority`, `balanced`, and `fastest`, the **Custom Strategy** allows operators to define precise weight distributions across ranking axes such as speed, cost, reliability, and quality. This implementation is handled primarily in [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts) and [`server/src/services/scoring.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/scoring.ts).

## Understanding the Routing Strategy Architecture

The routing system uses a strategy enum to determine which scoring algorithm applies to incoming requests. When you configure a Custom Strategy, you bypass the built-in heuristics and provide a deterministic weight vector that the router applies without peak-time adjustments.

### The RoutingStrategy Enum

In [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts), the `RoutingStrategy` type includes `'custom'` as a valid option alongside built-in strategies. The system validates any strategy change against `VALID_STRATEGIES` before persisting. The active strategy is stored under the constant `STRATEGY_KEY = 'routing_strategy'`, accessible via `getRoutingStrategy()` and modifiable via `setRoutingStrategy()`.

### How Custom Strategy Differs from Built-ins

Built-in strategies like `balanced` or `fastest` use hardcoded weight vectors that may adjust during peak hours. When the active strategy is `'custom'`, the `weightsWithPeak()` function in [`server/src/services/scoring.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/scoring.ts) returns `{ weights: getCustomWeights(), adjusted: false }`, ensuring the router uses your exact vector without dynamic modifications.

## Configuration Keys and Storage

Before implementing, understand the persistence layer defined in the router service:

- **`STRATEGY_KEY = 'routing_strategy'`**: Stores the active strategy identifier (e.g., `'custom'`).
- **`CUSTOM_WEIGHTS_KEY = 'routing_custom_weights'`**: Stores your normalized weight object as JSON.

The `getCustomWeights()` getter retrieves these values from the settings table, defaulting to the `balanced` strategy weights if none exist. The `setCustomWeights()` setter validates, normalizes the vector to sum to 1, and writes to `CUSTOM_WEIGHTS_KEY`.

## Step-by-Step Configuration

Follow these steps to enable and tune a Custom Strategy in your FreeLLMAPI instance.

### Step 1: Activate the Custom Strategy

Import the router service and switch from any built-in strategy to `'custom'`:

```typescript
import { setRoutingStrategy } from '@/services/router';

// Valid options: 'priority', 'balanced', 'smartest', 'fastest', 'reliable', 'custom'
setRoutingStrategy('custom');

```

This updates the `routing_strategy` setting in your database. The function throws if you provide an invalid strategy name.

### Step 2: Define Your Weight Vector

Construct a weight object mapping each ranking axis to a numeric priority. The system accepts four axes: `speed`, `cost`, `reliability`, and `quality`.

```typescript
const myWeights = {
  speed: 0.5,
  cost: 0.1,
  reliability: 0.3,
  quality: 0.1,
};

```

Values need not sum to 1 initially; `setCustomWeights()` automatically normalizes the vector.

### Step 3: Persist Custom Weights

Call the setter to persist your vector to `routing_custom_weights`:

```typescript
import { setCustomWeights } from '@/services/router';

setCustomWeights(myWeights);

```

This writes the normalized JSON to the settings store immediately, making it available for subsequent routing decisions.

### Step 4: Verify the Configuration

Confirm your changes using `getRoutingScores()`, which exposes the current strategy and custom weight values:

```typescript
import { getRoutingScores } from '@/services/router';

const { strategy, customWeights } = getRoutingScores();
console.log('Active strategy:', strategy);           // → 'custom'
console.log('Current weights:', customWeights);       // → { speed: 0.5, cost: 0.1, ... }

```

## Implementation Details and Weight Application

When processing requests with the Custom Strategy active, the scoring pipeline behaves differently than with built-in options. The `orderChain()` function in the router receives your exact weights from `getCustomWeights()` because `weightsWithPeak()` detects the `'custom'` strategy and disables peak-time adjustments.

This ensures **deterministic model ordering** based solely on your preferences, regardless of system load. The weights are applied in [`server/src/services/scoring.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/scoring.ts) during the chain ordering phase, where each candidate model receives a composite score calculated as the weighted sum of its normalized axis metrics.

## Programmatic API and Dashboard Integration

For administrative endpoints or automation scripts, combine the configuration steps into a single transaction:

```typescript
import { setRoutingStrategy, setCustomWeights, getRoutingScores } from '@/services/router';
import { Router } from 'express';

const admin = Router();

admin.post('/admin/set-custom-strategy', (req, res) => {
  const { weights } = req.body;  // Expected: { speed, cost, reliability, quality }
  
  try {
    setRoutingStrategy('custom');
    setCustomWeights(weights);
    const config = getRoutingScores();
    res.json({ 
      ok: true, 
      strategy: config.strategy, 
      customWeights: config.customWeights 
    });
  } catch (e) {
    res.status(400).json({ ok: false, error: e.message });
  }
});

```

The dashboard UI consumes these same primitives via the `/api/settings` endpoint, which exposes `getRoutingScores()` for reading and `POST /api/settings/custom_weights` for updates, ensuring the frontend sliders remain synchronized with the persisted vector.

## Summary

- **Custom Strategy** allows fine-grained control over model selection by accepting user-defined weight vectors in FreeLLMAPI.
- The implementation resides in [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts), with weight application logic in [`server/src/services/scoring.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/scoring.ts).
- Use `setRoutingStrategy('custom')` to activate the mode and `setCustomWeights()` to persist your normalized vector to `routing_custom_weights`.
- Unlike built-in strategies, the custom mode bypasses peak-time adjustments via `weightsWithPeak()`, ensuring deterministic routing.
- Verify configurations programmatically using `getRoutingScores()` or through the `/api/settings` REST endpoint.

## Frequently Asked Questions

### What happens if I provide weights that do not sum to 1?

The `setCustomWeights()` function automatically normalizes your input vector so that all values sum to 1 before persisting to `routing_custom_weights`. You do not need to pre-normalize the values in your application code.

### Can I switch back to a built-in strategy after using Custom Strategy?

Yes. Call `setRoutingStrategy()` with any valid built-in identifier such as `'balanced'` or `'fastest'`. The persisted custom weights remain in storage but are ignored until you reactivate `'custom'` mode.

### Does the Custom Strategy affect all requests immediately after configuration?

Configuration changes take effect immediately for new requests because `getRoutingStrategy()` and `getCustomWeights()` query the settings store on each routing decision. However, in-flight requests use the strategy state that existed when they entered the router queue.

### Where does FreeLLMAPI store the custom weight configuration?

The system persists custom weights in the settings table under the key `routing_custom_weights`, as defined by the `CUSTOM_WEIGHTS_KEY` constant in [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts). The active strategy identifier is stored separately under `routing_strategy`.