Kiln watches your task graph, fingerprints inputs, and skips packages that didn't change since the last green main. The average PR in a 47-package monorepo touches 3 — so 44 should be a cache hit.
Kiln reads your pnpm-workspace.yaml, your Bazel BUILD files, or your Nx project graph — and turns it into a fingerprinted DAG. Cache anywhere. Run anywhere.
A task declares what it reads and what it writes. Kiln fingerprints the input set, looks up the cache, and either skips the task or runs it on the next free runner.
# task graph for acme/web tasks: build: depends_on: [typecheck, lint] inputs: - "src/**/*.{ts,tsx}" - "package.json" - "!**/*.test.ts" outputs: - ".next/standalone" - ".next/static" command: pnpm next build cache: remote container: depends_on: [build] command: docker buildx --cache-to=kiln runner: "oci-builder-xl"
Remote cache, content-addressed by input fingerprint, scoped per branch and per package.
A gantt of the current build. Bars colored by package, grayed if pulled from cache.
Computed from the dependency graph + file fingerprints in the diff. We never run downstream what wasn't actually touched.
Promotions reuse the exact OCI digest that passed CI. No "deploy will recompile" surprises.
Kiln walks your dependency graph from the diff, fingerprints the inputs of every reachable task, and only schedules the work that actually changed. The graph is signed — you can prove which packages a release contains.
Cache hits are free. We bill per minute of actual compute, plus a flat platform fee.
For OSS and weekend projects.
For teams shipping every weekday.
For platform teams with their own runner farm.
"We had an 18-minute build that the team had stopped trying to fix. Kiln got it to 2m 41s in the first week, just by being honest about which packages a PR actually touched."
"Cache hit ratio sat at 30% under our old setup. After moving to Kiln's RBE-compatible cache it's been 89% for the last 28 days, and our CI bill dropped 64%."
"Migration from Nx Cloud took an afternoon. The promotion model — same OCI digest from canary to prod — is the part our SRE team actually cared about."
Most of our team is ex-Bazel and ex-Buck. If you have a deeper question, ping [email protected].
Turbo's caching is filename-shaped — you tell it "if these files change, rerun this task." Kiln resolves the actual import graph, so renaming a file or moving an export still hits the cache. Versus Nx Cloud: Kiln's cache speaks Bazel's gRPC RBE protocol, which means you can also bring Bazel rules and our cache will hit them. Most teams migrating tell us they keep Turbo for hot reload locally and run Kiln in CI.
Yes. Self-hosted runners are a first-class deployment target. The runner is a single static binary that registers with our control plane over outbound HTTPS — no inbound port. Most customers run a Karpenter-managed pool on EC2 spot, with auto-scaling driven by Kiln queue depth. Egress between your runners and our cache is free.
Both. The native protocol is gRPC Remote Execution v2 (the Bazel RBE wire format) over HTTP/2 with mTLS. We also expose a HTTP/1.1 fallback for environments without gRPC support — tested with Turborepo, Nx, and a homegrown CLI. Content addressing is SHA-256, max blob 4 GB, no compression on the wire (we rely on TLS-layer compression where available).
Yes — both rules_oci and rules_docker. The OCI artifact lands in our content-addressed store, which means a downstream oci_push action is a pointer move rather than a re-pack. Container builds that used to take 7 minutes drop to about 12 seconds end-to-end once cached.
Secrets are scoped per task in kiln.yaml, fetched from Vault / AWS Secrets Manager / GCP Secret Manager at runner startup, and exposed via tmpfs file paths — never as env vars unless you explicitly opt in. Secret-bearing tasks are excluded from the remote cache by default so a malicious PR can't exfiltrate them via a poisoned cache key.
Connect your monorepo in 5 minutes. The free tier covers 100 minutes a month — enough to feel the difference on day one.