Compile-Time Budget (@setEvalBranchQuota)
zmodu performs route table expansion, RouteMeta indexing, module dependency graph validation, Repository tenant-column checks, and bounded Mailbox(T, capacity) validation at compile time. To prevent large projects from hitting Zig’s default comptime branch limit (1000), framework comptime loops scale @setEvalBranchQuota proportionally to their input size.
1. Scaling Formula
src/core/EvalQuota.zig defines the scaling formula:
quota = base + per_unit * units
base = 1_000_000, per_unit = 20_000
unitsis the number of items being analyzed (modules, struct fields, graph nodes, routes).@setEvalBranchQuotais an upper bound; unused quota has zero cost.- In Zig, the innermost
@setEvalBranchQuotacall wins. A caller setting10_000_000cannot override a library function that hardcodes1000, so all internal comptime loops scale viaEvalQuota.forUnits.
If your own comptime code analyzes large types, call EvalQuota.forUnits:
const EvalQuota = @import("zmodu").core.EvalQuota;
comptime {
@setEvalBranchQuota(EvalQuota.forUnits(fields.len));
}
2. Verification Gate
src/test/ComptimeBudget.ziggenerates and mounts 256 routes into a full catalog at compile time. Any hardcoded quota or quadratic comptime regression fails the build immediately.scripts/check-comptime-budget.shcompiles the budget test and checks wall-clock time (COMPTIME_BUDGET_SECS, default300s) and peak RSS (COMPTIME_BUDGET_RSS_MB, default4096MiB).
3. Keeping Build Times Fast
Because every route handler and module is instantiated at compile time, build times grow with application size. If compilation slows down:
- Split oversized route tables across domain modules rather than registering hundreds of routes in a single struct.
- Avoid embedding large comptime strings inside
RouteMeta. - Link only the SQL drivers you need (
-Ddb=sqliteor-Ddb=none) during development.