Build Caching
SynDB uses multiple layers of caching to keep compile times short across local development, CI pipelines, and production deploys.
Cargo compiler flags
Configured in .cargo/config.toml, these flags speed up every local cargo
invocation:
| Flag | Effect |
|---|---|
-C link-arg=-fuse-ld=mold | Mold linker — significantly faster than the default ld or lld (Linux only) |
-Zshare-generics=y | Share monomorphized generics between crates, reducing codegen work |
-Zthreads=8 | Parallel compiler frontend (parsing, macro expansion, type checking) |
codegen-backend = "cranelift" | Dev profile uses Cranelift instead of LLVM for faster debug builds |
codegen-backend = "llvm" (for deps) | Dependencies still use LLVM for better optimization |
CI caching (GitHub Actions)
In CI, syndb-ci runs tests and builds directly on the host (no Docker for
the ci subcommand). Cargo artifacts are cached between runs via
Swatinem/rust-cache@v2, which
persists target/ and the cargo registry keyed by branch and Cargo.lock
hash.
For integration tests (local-stack-test, e2e-test), syndb-ci uses
bollard to start ephemeral Docker containers (PostgreSQL, ClickHouse, MinIO)
on a shared Docker network. Test binaries run on the host with environment
variables pointing at localhost:<port>. No cargo cache volumes are needed
inside containers — the host target/ is used directly.
Nix OCI cache
Local stack images (just stack-prepare) for the API and ETL are built with
Nix and cached using syndb-ci nix-oci-cache. This command uses Nix
store paths as content-addressed fingerprints to skip unnecessary rebuilds:
nix build .#oci-syndb-apiproduces a store path (a hash of all inputs)- The script compares the current store path against a stamp file
(
/tmp/.oci-syndb-api.storepath) - If unchanged, the build is skipped entirely
- If changed, the new tarball is copied to
/tmp/and loaded into Docker
This means just stack-prepare is near-instant when source hasn’t changed.
Nix Crane dependency caching
For nix flake check (CI) and Nix-based OCI image builds, the project uses
Crane with a split dependency build:
# nix/rust.nix
mkCargoArtifacts = system:
craneLib.buildDepsOnly (mkCommonArgs system);
buildDepsOnly compiles all workspace dependencies into a cached Nix
derivation. Subsequent builds of workspace crates reuse these artifacts,
so only the project’s own code is recompiled. Since Nix derivations are
content-addressed, the dependency cache is automatically invalidated when
Cargo.lock changes.
UI source-hash cache
The UI image (just _stack-prepare-ui) uses a source-hash stamp to skip
rebuilds when Python source files haven’t changed:
- SHA-256 of all files in
packages/ui/src/,packages/syndb-ql/python/,pyproject.toml,uv.lock, andsyndb-ql-python/Cargo.toml - Compared against
/tmp/.syndb-ui.srchash - If the hash matches and
syndb-ui:devexists in Docker, the build is skipped
Summary
| Layer | Scope | Mechanism | Invalidation |
|---|---|---|---|
| Cargo flags | Local dev | Mold, Cranelift, parallel frontend | N/A (always active) |
| GitHub Actions cache | CI pipelines | Swatinem/rust-cache@v2 | Branch + Cargo.lock hash |
| Nix OCI cache | stack-prepare (API, ETL) | Nix store-path stamps | Content-addressed (any input change) |
| Crane deps | nix flake check, OCI images | buildDepsOnly derivation | Cargo.lock changes |
| UI source hash | stack-prepare (UI) | SHA-256 file stamp | Source file changes |