flintstackbuild-cache daemon · a hosted project
Project status: activeLicense: Apache-2.0Latest: 0.11.3 (2026-09-28)releases feed

Flintstack › Project summary

A build cache that sits in front of your compiler

Flintstack keeps compiler output in a content-addressed store and hands it back when the same inputs show up again - on the same machine, or on any other machine that can reach the shared store. One static binary, one config file, no scheduler.

Quick start

Three commands, under a minute on a box that already has a toolchain:

# 1. unpack the static binary (11 MB, no runtime deps)
tar -xf flintstack-0.11.3-linux-x86_64.tar.zst -C /usr/local

# 2. start the daemon with its store on a fast disk
flintd --root /var/lib/flint

# 3. put the wrapper in front of the compiler
CC="flint wrap -- cc" CXX="flint wrap -- c++" make -j8

The second build of the same tree is the interesting one. Ask the daemon how it went:

$ flint stats
entries   18402
store     21.4 GiB / 80 GiB
hits      94.1 %   (rolling 7 days)
misses    1087
evicted   312      (lru)
uptime    11d 4h

No daemon, no cache. The wrapper talks to flintd over a unix socket at /run/flint/flintd.sock. If nothing is listening, flint wrap execs the real compiler and returns its exit status unchanged, so a dead cache never breaks a build - it only makes it slow.

What it does

For every compiler invocation the wrapper builds a cache key out of four things: the toolchain identity, the normalized argument vector, the digests of every input file after preprocessing, and the values of a small allowlist of environment variables. Those are hashed with SHA-256, and the first 128 bits of that digest name the entry.

On a hit, the daemon writes the stored object to the output path and the compiler is never started. On a miss, the compiler runs, the result is captured, and the entry is stored under the key that was computed before the run - so the miss costs one extra stat of each input, not a second compile.

Three storage backends can be stacked, nearest first:

BackendWhat it isTypical place
fsa directory on local diskalways on, the first tier
objsobject storage over signed HTTPshared between CI runners
peeranother flintd over TCP port 7914a cache box on the same rack

What it is not

  • Not a build system. It has no dependency graph, no targets and no scheduler; your existing tool keeps deciding what to build and in what order.
  • Not a distributed compiler. Work is never farmed out to other machines - only results are shared.
  • Not a package registry. Entries are keyed by inputs, not by name and version, and they expire.
  • Not a sandbox. If a build reads a file nobody declared, Flintstack will happily cache the wrong answer. That is the single sharpest edge in the whole design, and the design notes are blunt about it.
  • Not portable to Windows. The code assumes POSIX file semantics in places where the fix would be a rewrite rather than a port.

Numbers

10.3×warm build speedup
94.1 %hit rate, rolling week
11 MBsingle static binary

Measured on a corpus of 2310 compile targets: 708 s with an empty store, 69 s with a full one. The full method, the incremental case and the honest caveats live on the benchmark page - including the part where the shared backend adds latency instead of removing it.

Where to go next

  • Install - tarball with checksums, or build from source.
  • CLI reference - every command and flag, with exit codes.
  • Configuration - the flint.toml keys and defaults.
  • Security - tokens, mTLS and what the threat model excludes.
  • FAQ - the questions that arrive by mail most often.

Patches go to dev@flintstack.dev as plain git format-patch output. The source tree is self-hosted:

git clone https://code.flintstack.dev/flint.git

Last updated: 2026-09-29