SemiLayerDocs

Source assignments

A runner serves the sources it's assigned to — no more, no less. Assignments are managed in the Console's Runners page; each row shows which sources it covers and lets you add or remove them.

What happens on query

When a query resolves to a lens backed by source S:

  1. Service gathers runner_assignments WHERE source_id = S.
  2. If there are zero assignments, the service executes the query inline — same as life before runners. No routing change.
  3. If there are ≥1 assignments, the service picks a live runner (connected, within heartbeat window) and dispatches over the gateway. If none of the assigned runners are online, the query fails with no_runners_online and a 503.

This means assigning a source to a runner is the switch that flips it from SaaS handles this to you do. No env vars, no deploy — one click in the Console.

Good patterns

  • One runner per network. Most teams run a single runner per customer deployment (typically per-VPC or per-cluster). Assign every source in that network to it.
  • Redundant pair. Want no-single-point-of-failure? Run two runners with identical assignments. See multiple runners.
  • Migration. Leave a source unassigned for the SaaS path while you stand up the runner. Assign it once the runner is online — no query disruption.

Bad patterns

  • Different assignments per replica. Runners serve what's assigned to them. Three runners each assigned to one distinct source = three single-runner dependencies. If you want redundancy, assign everything to everything.
  • Assigning a source to a runner whose network can't reach the DB. The dispatch will succeed, the runner will get the job, and then connection refused — surfaced as a SOURCE_UNREACHABLE to the caller. Use the source row's Test connection button after assignment; the runner proves it can actually reach the DB.

Changing assignments at runtime

Safe. Runners pick up the new set on their next heartbeat (≤25 s). In-flight jobs complete on whichever runner already accepted them.