(motir-core) The code-graph refresh costs ~35 minutes to re-derive a graph that measures 32 seconds — index ONCE per repo, and reach `codegraph sync`
Opened by Zhu Yue ·
Repo · motir-core. One PR. Filed as the DEFERRAL card for the indexer's cost, which the engine-fairness story explicitly puts out of scope. It is related_to that story and blocked by nothing — the two are independent.
What is measured, and what is inferred
Measured, production, 2026-08-28 (job_run, read inside the Fly machine):
- Six consecutive
system.code-graph-refreshruns formoooon-B-V/motir-core: 2 058–2 116 s each, back to back 07:12→10:50. - Every run reports
output.projectsIndexed: 2. - The same job for
moooon-B-V/motir-aitook 226 s and formoooon-B-V/motir-meta60 s, both also atprojectsIndexed: 2.
Read in the code (origin/main):
lib/jobs/indexFleetSteps.ts:243—for (const projectId of target.projectIds), i.e. one container per (repo × project), supervised sequentially.- The per-project
dispatchInputdiffers in exactly ONE field,projectId.repoOwner,repoName,repoRef,defaultBranch,installationIdandworkspaceIdare identical, so the same tree is cloned and parsed twice. lib/jobs/definitions/codeGraphRefresh.tsstates a refresh is a full whole-tree rebuild and has always been one.
Measured on a developer box, 2026-08-20, codegraph CLI 1.1.6 — a reading with a subject and a date, NOT a property of the fleet container, and to be re-taken before it is relied on:
| operation | wall |
|---|---|
motir-core index --force (full) | 32.0 s |
motir-core sync, 10 changed files | 0.7 s |
motir-core sync, 2 481-file stale diff | 38.2 s |
The two questions, in order
1 — Why is the parse duplicated per project? The graph is a property of the repository at a ref, and the ledger already treats it that way: one job_run per repo with one output.repoRef. If the per-project fan-out exists for tenancy of the PUBLISHED index rather than of the parse, then parse once and publish per project — which halves the work by construction and makes the sequential-vs-parallel question disappear. Settle this before optimising anything, because the answer may remove the second question.
2 — Where does the rest of the time go? 32 s of measured parse against ~2 100 s of production wall clock leaves ~98% unaccounted for. Instrument before fixing: the admission backoff, the boot/provision, the tarball fetch, and the poll-to-detect lag (indexPollWaitMs backs off to a 15 s cap, so detection alone costs up to 15 s per container). Do not assume which dominates.
Only THEN, incremental indexing
codegraph sync exists and is dramatically cheaper on a near-current graph. It has no caller: motir-ai's diff path GraphIndexPublisher.refresh was deleted on 2026-08-05 (MOTIR-2145) and the container runs a whole-tree build. Reaching it needs the prior .codegraph/codegraph.db carried or fetched as a base, and a "changed > X% of tree ⇒ full rebuild" threshold for the measured crossover. Worth doing for the fleet CPU it stops burning — not for latency, since per the numbers above the parse is a small share of the wall clock.
Acceptance criteria
- The card records whether the per-project fan-out is required for the PARSE or only for the PUBLISH, with the evidence read from the code that consumes the published index.
- If the parse is repo-shaped, the fan-out is restructured to parse once per (repo, ref) and publish per project, and a production run's duration is read back from
job_runand quoted. - A phase breakdown of one real refresh is recorded — admission, boot, fetch, parse, detect — each with the instrument that measured it.
- Any change to the fan-out is checked against
codeGraphIndexAdmissionService's cap before it is made, and the card says what that cap permits. codegraph syncis either reached, with a stated full-rebuild threshold and a re-taken measurement on the CONTAINER rather than a developer box, or explicitly deferred to its own card with the reason.
Context refs
lib/jobs/indexFleetSteps.ts— the sequential per-project loop and the ledger contract.lib/jobs/definitions/codeGraphRefresh.ts— the whole-tree-rebuild statement and its history.lib/services/codeGraphIndexDispatchService.ts—indexPollWaitMs, the admission backoff,MAX_POLL_ITERATIONS.lib/services/codeGraphIndexAdmissionService.ts— the cap any parallelisation must respect.- MOTIR-3684 —
system.code-graph-refreshfailing ~32% on admission deferral; the same subsystem, a different symptom.
Discussion
No comments yet.
Adding to this discussion signs you in on app.motir.co and brings you back to this request.