Heuristic:Mlc ai Web llm Service Worker Keep Alive
| Knowledge Sources | |
|---|---|
| Domains | Chrome_Extension, Optimization, Deployment |
| Last Updated | 2026-02-14 22:00 GMT |
Overview
Keep-alive heartbeat pattern that prevents Chrome from terminating the Service Worker while an LLM model is loaded in memory.
Description
Chrome terminates idle Service Workers after approximately 30 seconds of inactivity. Since WebLLM loads model weights into GPU memory within the Service Worker, termination means losing the loaded model and requiring a full reload (which can take 10-60+ seconds depending on model size and cache state). WebLLM implements a heartbeat pattern where the client sends periodic `keepAlive` messages to the Service Worker, and the Service Worker responds with `heartbeat` messages. A `missedHeartbeat` counter tracks whether the Service Worker has crashed or been terminated.
Usage
Use this heuristic when deploying WebLLM in a Chrome Extension with a Service Worker background script. The keep-alive is built into `ServiceWorkerMLCEngine` and `ExtensionServiceWorkerMLCEngine` but understanding the pattern helps diagnose connectivity issues.
The Insight (Rule of Thumb)
- Action: Use the default `keepAliveMs = 10000` (10 seconds) for the heartbeat interval. This is well within Chrome's ~30 second idle timeout.
- Value: 10-second interval balances between keeping the worker alive and minimizing message overhead.
- Trade-off: More frequent heartbeats increase message traffic but reduce risk of accidental termination. Less frequent heartbeats risk the Service Worker being killed between beats.
- Monitoring: Watch the `missedHeartbeat` counter — if it increases continuously, the Service Worker has crashed and needs re-registration.
Reasoning
Chrome's Service Worker lifecycle is designed for event-driven tasks, not persistent background processes. An LLM loaded in a Service Worker is inherently a persistent background process (model stays in GPU VRAM). The heartbeat bridges this mismatch by generating periodic events. The 10-second default provides a 3x safety margin against the 30-second idle timeout.
Keep-alive implementation from `src/service_worker.ts:221-233`:
constructor(engineConfig?: MLCEngineConfig, keepAliveMs = 10000) {
if (!("serviceWorker" in navigator)) {
throw new NoServiceWorkerAPIError();
}
super(new ServiceWorker(), engineConfig);
// Keep alive through periodical heartbeat signals
setInterval(() => {
this.worker.postMessage({ kind: "keepAlive", uuid: crypto.randomUUID() });
this.missedHeartbeat += 1;
log.trace("missedHeartbeat", this.missedHeartbeat);
}, keepAliveMs);
}
Heartbeat response handler from `src/service_worker.ts:241-243`:
if (msg.kind === "heartbeat") {
this.missedHeartbeat = 0;
return;
}