serve_fast = True opt-in. Bypass bazel build entirely for serve-mode rebuilds when only .tex source files changed; invoke tectonic_compile.py directly via the worker channel. Falls back to bazel build when structural files change. |
150-400 ms per warm rebuild (~50% of remaining latency) |
Sandbox/CI parity loss: a fast-path rebuild that diverges from bazel build produces "works in serve, fails in CI" surprises. Want this opt-in with prominent docs, not the default. |
Multiplex persistent workers. Today's worker is single-request-at-a-time; supports-multiplex-workers lets one Python process handle N parallel requests. |
100-400 ms when building multiple documents in parallel |
Requires re-entrancy audit of tectonic_compile.py (currently safe but not guaranteed; os.environ and sys.stderr redirection would need scope tightening). |
Share the persistent serve cache across documents in the same workspace. Two docs that pull the same 50 packages each pay a separate ~60 s prime today. Refactor derive_cache_layout so multiple documents share a TECTONIC_CACHE_DIR and tar per-doc subsets. |
30-90 s once per extra document, on first prime |
Single-doc workspaces gain nothing; refactor of tools/serve_cache.py for the multi-doc case. |
Look-aside between bazel build's implicit-cache action and serve_cache.py. A user who already ran bazel build //:doc should not pay the prime cost when they then run bazel run //:doc_serve (and vice versa). |
30-90 s once per workspace, when both paths get used |
Look-aside is safe (tectonic's content-addressing prevents stale reads), but the read-from-bazel-bin direction is brittle (bazel-bin contents are mode-dependent). |
| Ship a "common LaTeX prelude" prebuilt cache snapshot in the toolchain. A small (~30 MB) curated cache covering the top ~50 packages — article, amsmath, hyperref, geometry, etc. Most first primes become "extract + a few online fetches" instead of "all online". |
30-90 s → ~5 s for typical first prime |
~500 LOC, maintenance burden, repo bloat. Only worth doing if first-prime cost becomes a top complaint. |
Key the implicit-pipeline populate action on the \usepackage set, not full sources. The serve-cache override already sidesteps this for serve mode; this would help bazel build outside serve mode for users who don't set cache=. |
30-90 s per edit (non-serve) |
Architectural change; requires a Starlark-time scan of .tex files for \usepackage directives, then keying the populate action on that fingerprint. |
Drop pack_cache compression from level 6 to level 1. Snapshot grows ~1.5× but pack speed doubles. |
0.5-1 s per prime |
Cold-path only; not worth the disk bloat for most users. |
Async / "server-first" prime on serve startup. Currently the HTTP server doesn't bind until the prime is complete (~60 s on cold checkout). Bind first, prime in a background thread, report progress via /status. |
UX, not wall-clock |
Worth doing as a polish pass; not strictly performance. |
Collapse the three Python sh_tests into one python3 -m unittest tests.py.test_*. Three Python startups → one per bazel test. |
200-300 ms per cold bazel test run |
Cosmetic; tests are cached by Bazel anyway. |
Switch _serve_cache_override from string_flag to action_env. Eliminates the analysis-cache flush when alternating between bazel build and bazel run :serve. |
50-200 ms on serve↔build transitions |
Marginally less hermetic; the existing flag-based wiring is also easier to reason about. |