How the FreeLLMAPI Catalog Sync Service Updates Model Information

The FreeLLMAPI catalog sync service performs an idempotent full-snapshot merge via the applyCatalog function in server/src/services/catalog-sync.ts, synchronizing the local router database with the authoritative catalog by inserting new models, updating metadata while preserving local enable flags, re-applying user overrides, and tombstoning deleted entries to ensure user preferences survive refreshes.

The catalog sync service acts as the bridge between the published model catalog fetched from the FreeLLMAPI back-end and the local router database used at runtime. According to the tashfeenahmed/freellmapi source code, this service ensures the router database always reflects the latest authoritative catalog while honoring user-specific customizations through a strictly defined merge algorithm.

The Full-Snapshot Merge Algorithm

The core logic resides in the applyCatalog routine, which executes a transaction-driven merge that follows eight distinct phases.

Inserting New Models

When the catalog contains models absent from the local database, the service inserts them together with fallback-configuration rows so the router can immediately default to these models. This phase increments an inserted count, as verified in the test suite at server/src/__tests__/services/catalog-sync.test.ts lines 103–116.

Updating Existing Metadata

For catalog-managed rows, the service overwrites metadata fields—including display name, context window, token limits, speed and intelligence rankings, and modality—while deliberately preserving the local enabled flag unless the catalog explicitly disables the model. This "updates metadata in place and respects the enabled policy" according to tests at lines 32–50.

Re-applying User Overrides

After metadata refreshes, the upsertModelOverrides routine re-applies locally stored custom values (such as custom display names or higher token budgets), ensuring user configurations take precedence over fresh catalog data. The test suite confirms this behavior at lines 89–20.

Handling Deletions and Tombstones

Models removed from the catalog are deleted from the local database—cascading to associated fallback-config rows—unless they are custom-provider models or marked as tombstoned. When a user explicitly deletes a catalog model, the service writes a tombstone entry to catalog_model_tombstones, and subsequent syncs keep the model deleted, as documented in tests at lines 22–31.

Platform Awareness

The sync skips models for unknown platforms (those lacking runtime adapters) rather than inserting them, incrementing a skippedUnknownPlatform counter to track omissions. This prevents the database from accumulating unusable entries, verified in tests at lines 36–42.

Quirks and Media Registries

The service synchronizes catalog quirks (UI warnings) and specialized registries for transcription, video, and image models into dedicated tables (quirks, media_models, and embedding_models). This process respects enable-merge, priority ordering, and modality-scoping rules defined in the catalog.

Cache Re-application

On startup, the service may invoke reapplyCachedCatalog to validate a cached snapshot against MIN_CATALOG_VERSION and apply it without a network round-trip. This keeps the catalog authoritative across restarts while avoiding unnecessary fetches.

Implementation Example

The following TypeScript demonstrates how to fetch, validate, and apply a catalog using the core functions exported from server/src/services/catalog-sync.ts:

import {
  applyCatalog,
  reapplyCachedCatalog,
  MIN_CATALOG_VERSION,
} from './services/catalog-sync.js';
import { getDb } from './db/index.js';

// ------------------------------------------------------------------
// 1. Load a catalog (normally fetched via HTTP)
// ------------------------------------------------------------------
async function fetchCatalog(): Promise<any> {
  const res = await fetch('https://api.freellmapi.com/v1/catalog');
  return await res.json();
}

// ------------------------------------------------------------------
// 2. Apply the catalog to the local DB
// ------------------------------------------------------------------
async function syncNow() {
  const catalog = await fetchCatalog();

  // Guard against very old catalog versions
  if (catalog.version < MIN_CATALOG_VERSION) {
    throw new Error('Catalog version too old');
  }

  const counts = applyCatalog(getDb(), catalog);
  console.log('Catalog sync results:', counts);
}

// ------------------------------------------------------------------
// 3. Re-apply a cached catalog after a process restart (no network)
// ------------------------------------------------------------------
function reapplyIfCached() {
  const result = reapplyCachedCatalog();
  if (result.reapplied) {
    console.log(`Re-applied cached catalog v${result.version}`);
  } else {
    console.log('No valid catalog cache – fresh fetch required');
  }
}

Summary

  • The FreeLLMAPI catalog sync service uses a full-snapshot merge to synchronize the local router database with the authoritative catalog.
  • The applyCatalog function in server/src/services/catalog-sync.ts handles inserts, updates, deletions, and override re-application in a single transaction.
  • User overrides and tombstones are preserved across catalog refreshes, ensuring user preferences persist.
  • Platform-aware filtering prevents insertion of models for unsupported providers.
  • Cache re-application via reapplyCachedCatalog minimizes network traffic on restarts while maintaining MIN_CATALOG_VERSION safety checks.

Frequently Asked Questions

What happens if the catalog version is too old?

The service compares the incoming catalog's version against the constant MIN_CATALOG_VERSION before processing. If the catalog is older than this threshold, the sync aborts to prevent applying outdated schema or stale model definitions, as implemented in server/src/services/catalog-sync.ts.

Does the sync overwrite my custom model settings?

No. While the sync updates catalog-managed metadata (display names, limits, rankings), it preserves the local enabled flag and explicitly re-applies user overrides via upsertModelOverrides after the merge, ensuring your custom configurations take precedence.

How does the service handle models I manually deleted?

When you delete a catalog model, the service writes a tombstone entry to catalog_model_tombstones. Subsequent syncs check this table and keep tombstoned models deleted, preventing them from reappearing during the next catalog refresh unless you explicitly clear the tombstone.

Is the catalog sync safe to run multiple times?

Yes. The applyCatalog routine is idempotent—running it repeatedly with the same catalog payload produces no further changes after the initial sync. This design allows the scheduled background job to run frequently without risking database inconsistencies or duplicate entries.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →