How the Self-Updating Model Catalog Sync Mechanism Works in FreeLLMAPI
FreeLLMAPI maintains its model catalog through an automated sync process that fetches a signed, version-gated remote feed twice daily, verifies it with Ed25519 signatures, and atomically reconciles it with a local SQLite database while preserving user overrides.
The self-updating model catalog sync mechanism in FreeLLMAPI ensures that local provider configurations stay current without manual intervention. This system operates through a cryptographically verified, scheduled pipeline that balances network efficiency with offline resilience. Understanding this architecture is essential for operators who need to troubleshoot sync failures or customize model behavior.
Architecture Overview
The mechanism operates through three coordinated phases defined in server/src/services/catalog-sync.ts:
- Boot Rehydration – On startup, the server restores the last verified catalog from disk so the SQLite database remains functional even without network connectivity.
- Scheduled Synchronization – A background scheduler initiates sync cycles twice daily, fetching remote updates, verifying signatures, and atomically applying changes.
- State Persistence – The system tracks applied versions, tiers, timestamps, and error states in the
settingstable, enabling observability and crash recovery.
This pipeline is initialized in server/src/index.ts at lines 77‑78, where startCatalogSync is invoked after the HTTP server begins accepting connections.
The Sync Lifecycle
Boot Sequence and Cache Rehydration
When the server starts, startCatalogSync immediately calls reapplyCachedCatalog() to restore the previous state. This function retrieves the cached JSON from the settings table under keys like SETTING_APPLIED_JSON, validates it again using isCatalog(), and executes applyCatalog() to ensure the database reflects the last known good configuration.
A deliberate BOOT_DELAY_MS of 10 seconds prevents the first live sync from interfering with other initialization routines. After this interval, the scheduler triggers the initial remote fetch.
Fetching and Signature Verification
The syncCatalog() function constructs a request to /v1/latest, injecting an Authorization: Bearer <key> header when a premium license is configured. To optimize bandwidth, it appends a since=<applied> query parameter, allowing the server to return 304 Not Modified responses when the catalog version remains unchanged.
Upon receiving a payload, the system extracts the x-catalog-signature header and verifies the Ed25519 signature against the hard-coded PINNED_CATALOG_PUBKEY or an environment override. This cryptographic validation ensures that only authentic, untampered catalogs are processed.
Validation and Version Gating
Before application, isCatalog() performs structural validation against the JSON schema, checking required fields, array shapes, and nested object types. The system then compares the catalog's version property against MIN_CATALOG_VERSION (the baseline bundled with the binary). If the remote version is older, the sync aborts to prevent regression of database migrations.
Atomic Database Application
The applyCatalog() function executes within a single SQLite transaction, ensuring consistency during updates. This process:
- Inserts or updates chat models, media models, embeddings, transcription, and video models
- Preserves user-added rows marked with
source='user'and respects tombstone records managed byserver/src/services/model-state.ts - Applies per-model overrides via
applyModelOverrides(referenced inserver/src/services/model-weight-overrides.ts) - Prunes entries that have disappeared from the upstream catalog
- Replaces quirks definitions wholesale
After successful application, the system persists the new version, tier, and raw JSON to the settings table under SETTING_APPLIED_VERSION, SETTING_APPLIED_TIER, and SETTING_APPLIED_JSON, along with timestamps for observability.
Scheduler Configuration and License Integration
The scheduler runs every SYNC_INTERVAL_MS (12 hours) as configured in catalog-sync.ts at lines 445‑447. Independently, refreshLicenseStatus() probes /v1/license/check during each cycle to validate premium entitlement, ensuring that license state and catalog tier remain synchronized.
Manual Sync and Debugging
Developers can trigger on-demand synchronization programmatically:
import { syncCatalog, getSyncState } from './services/catalog-sync.js';
async function forceRefresh() {
const result = await syncCatalog(true);
console.log('Catalog sync result:', result);
console.log('Current sync state:', getSyncState());
}
forceRefresh().catch(console.error);
Passing true to syncCatalog() bypasses the since parameter optimization, forcing a full download regardless of the cached version. This is useful for debugging or immediate updates.
Graceful Shutdown and Error Handling
The stopCatalogSync() function clears the boot timer and interval handles, preventing stray network calls during process termination. Error states are captured in the settings table, making sync failures observable through the getSyncState() API.
Summary
- The self-updating model catalog sync mechanism relies on Ed25519 signature verification to ensure catalog authenticity before any database modifications occur.
- The system operates on a twice-daily schedule with a 10-second boot delay, while supporting immediate manual triggers via
syncCatalog(true). - All database applications are atomic transactions that preserve user overrides, tombstones, and platform-specific rules defined in files like
server/src/services/model-state.ts. - Offline resilience is maintained through cached catalog rehydration during server startup, ensuring continuous operation without network connectivity.
- Version gating prevents rollback to older catalogs than
MIN_CATALOG_VERSION, protecting database schema integrity.
Frequently Asked Questions
How does FreeLLMAPI handle catalog updates when the server is offline?
During boot, reapplyCachedCatalog() loads the last verified catalog from the SQLite settings table using SETTING_APPLIED_JSON. This allows the server to function with stale but valid model metadata until network connectivity returns and the next scheduled sync succeeds.
What prevents malicious or corrupted catalogs from modifying the database?
Every catalog payload must carry a valid x-catalog-signature header that cryptographically verifies against the PINNED_CATALOG_PUBKEY using Ed25519. Additionally, isCatalog() validates JSON structure, and version gating ensures the catalog is not older than the binary's baseline.
Can I force an immediate catalog update outside the 12-hour schedule?
Yes. Import syncCatalog from server/src/services/catalog-sync.ts and invoke it with syncCatalog(true) to bypass the since parameter optimization. This forces a fresh download and application of the latest catalog regardless of the cached version.
Where does the system store the current catalog version and tier?
The applied version, tier, and raw JSON are stored in the SQLite settings table under the keys SETTING_APPLIED_VERSION, SETTING_APPLIED_TIER, and SETTING_APPLIED_JSON. These values persist across restarts and enable the boot-time cache rehydration mechanism.
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 →