How Fallback Chain Configuration Works in the FreeLLMAPI Dashboard
The fallback chain configuration in FreeLLMAPI is managed through a SQLite-backed Express API that serves an ordered list of models with dynamic penalties, allowing admins to reorder, enable/disable, and apply routing presets via REST endpoints consumed by a React dashboard.
The tashfeenahmed/freellmapi repository provides an open-source LLM routing platform that intelligently distributes requests across multiple providers. At the heart of this system lies the fallback chain configuration, which defines the ordered sequence of models the platform attempts when primary requests fail or require rerouting.
SQLite Data Model and the Primary Endpoint
The fallback chain persists in the fallback_config table, which stores static priority rankings and enabled states for each model. In server/src/routes/fallback.ts (lines 58‑71), the GET /api/fallback endpoint executes a SQL join between fallback_config and the models table to construct a comprehensive response:
SELECT fc.model_db_id, fc.priority, fc.enabled,
m.platform, m.model_id, m.display_name, …
FROM fallback_config fc
JOIN models m ON m.id = fc.model_db_id
WHERE m.enabled = 1
ORDER BY fc.priority ASC
The response enriches raw database fields with runtime metrics. Each entry includes:
priority– The static order set by the administratoreffectivePriority– Calculated aspriority + penalty(lines 99‑105)penaltyandrateLimitHits– Sourced fromgetAllPenalties()inserver/src/services/router.tskeyCount– Number of enabled API keys for the model’s platform (lines 73‑80)monthlyTokenBudgetTokens– Parsed from budget strings viaparseBudget()inserver/src/lib/budget.ts(lines 122‑125)groupKey,canonicalId,groupLabel– Logical grouping metadata fromgetModelGroups()(lines 88‑94)
Because the server supplies all derived fields in a single JSON payload, the client renders the table without additional lookups.
Updating and Reordering the Chain
Administrators modify the fallback chain configuration through two primary mechanisms.
Full Chain Replacement
The PUT /api/fallback endpoint accepts a complete array of objects containing modelDbId, priority, and enabled boolean. The server executes a database transaction that updates each corresponding row in fallback_config, ensuring atomic consistency when reordering or toggling model availability.
// Send the whole edited chain back to the server
await apiFetch('/api/fallback', {
method: 'PUT',
body: JSON.stringify(editedEntries), // [{modelDbId, priority, enabled}, …]
});
Preset-Based Sorting
For automated optimization, POST /api/fallback/sort/:preset (lines 99‑126) applies algorithmic sorting based on strategic criteria:
intelligence– Sorts by model size-tier thenintelligence_rankspeed– Orders byspeed_rankbudget– Calculates a budget score frommonthly_token_budgetortpd_limitusinggetBudgetScore(lines 76‑96)
// server/src/routes/fallback.ts
fallbackRouter.post('/sort/:preset', (req, res) => {
const preset = String(req.params.preset);
// … compute `models` array based on preset …
const update = db.prepare('UPDATE fallback_config SET priority = ? WHERE model_db_id = ?');
db.transaction(() => models.forEach((m, i) => update.run(i + 1, m.id)))();
res.json({ success: true, preset });
});
Routing Strategy Configuration
Beyond static ordering, the dashboard manages dynamic routing behavior through the bandit strategy system. The GET /api/fallback/routing endpoint (lines 18‑22) returns the active strategy, preset weights, and per-model scores.
Administrators switch strategies via PUT /api/fallback/routing (lines 24‑56), selecting from priority, balanced, smartest, fastest, reliable, or custom. When selecting custom, the system persists a weight vector (reliability, speed, intelligence) through setCustomWeights.
await apiFetch('/api/fallback/routing', {
method: 'PUT',
body: JSON.stringify({
strategy: 'custom',
weights: { reliability: 0.5, speed: 0.3, intelligence: 0.2 }
}),
});
The preset weights and scoring logic reside in server/src/services/scoring.ts, which exports BANDIT_PRESETS defining how each strategy balances competing objectives.
Token Budget Visualization
The dashboard renders token consumption through GET /api/fallback/token-usage (lines 28‑107). This endpoint aggregates:
totalBudget– Combined token budget across all modelstotalUsed– Tokens consumed during the current month- Per-model breakdowns including limits and enabled flags
When an active profile exists, the endpoint intelligently pulls chain data from profile_models rather than the global fallback_config.
React Frontend Integration
The client implementation in client/src/pages/FallbackPage.tsx consumes these endpoints using the apiFetch helper with React Query’s useQuery(['fallback']) for caching.
// client/src/pages/FallbackPage.tsx
const { data: fallbackEntries = [] } = useQuery<FallbackEntry[]>({
queryKey: ['fallback'],
queryFn: () => apiFetch('/api/fallback'),
});
The UI renders each model’s display name, static priority, effective priority, and fallback attempt badges from the X-Fallback-Attempts response header. Drag-and-drop reordering and enable toggles trigger the PUT /api/fallback endpoint, while routing strategy changes invoke PUT /api/fallback/routing. Because server/src/routes/fallback.ts pre-calculates all business logic, the client remains a thin presentation layer.
Summary
- The fallback chain configuration resides in the SQLite
fallback_configtable, joined withmodelsto provide rich metadata - The
GET /api/fallbackendpoint supplies static priorities, dynamic penalties fromgetAllPenalties(), and budget calculations fromparseBudget() - Chain updates occur atomically via
PUT /api/fallback, whilePOST /api/fallback/sort/:presetenables algorithmic reordering byintelligence,speed, orbudget - Routing strategies (
priority,balanced,smartest,fastest,reliable,custom) control how penalties affect request distribution - The React dashboard in
FallbackPage.tsxconsumes these endpoints throughreact-query, displayingeffectivePriorityand token usage without client-side business logic
Frequently Asked Questions
Where is the fallback chain data physically stored?
The configuration persists in a SQLite table named fallback_config, which contains model_db_id, priority, and enabled columns. This table joins against the models table in server/src/routes/fallback.ts to enrich entries with platform details, capabilities, and display names.
How does the dashboard calculate effectivePriority?
The effectivePriority field equals the static priority value plus a dynamic penalty score. The penalty derives from getAllPenalties() in server/src/services/router.ts, which factors in rateLimitHits and other runtime metrics to deprioritize struggling models automatically.
Can I automate the ordering based on model performance or cost?
Yes. The POST /api/fallback/sort/:preset endpoint supports three automated presets: intelligence (ranks by capability), speed (ranks by latency), and budget (ranks by token cost). Each preset recalculates priorities and updates the fallback_config table atomically.
What happens when I switch routing strategies?
When you PUT to /api/fallback/routing with a new strategy, the system updates how penalties are applied to the fallback chain. Strategies like smartest or fastest use predefined weights from BANDIT_PRESETS in server/src/services/scoring.ts, while custom allows you to specify exact weights for reliability, speed, and intelligence via setCustomWeights.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →