MongoDB
Back the cache with MongoDB: collections, write concern, timeouts, and what the change-streams flag is for.
Who this is for: anyone who already operates MongoDB. What you'll have at the end: a Mongo-backed CAS behind a local fast tier. Time: twenty-five minutes.
Before you start
A config file you can edit (see Configuration), and a reachable MongoDB deployment.
Mongo lands between Redis and object storage: durable, shared across machines, single-digit milliseconds away, and priced by the cluster you run rather than per gigabyte stored. Storage backends compares all of them on the same axes.
The recipe
stores: [
{
name: "CAS_MAIN_STORE",
fast_slow: {
fast: {
memory: {
eviction_policy: { max_bytes: "1gb" },
},
},
slow: {
experimental_mongo: {
connection_string: "${MONGO_URI}",
database: "nativelink",
cas_collection: "cas",
key_prefix: "prod:",
},
},
},
},
],connection_string is the only required field and takes either form Mongo
accepts, mongodb://localhost:27017 or
mongodb+srv://cluster.mongodb.net for Atlas. It carries the credentials, so
keep it in the environment and reference it with ${VAR}; see
The config file.
Everything else has a default: database is nativelink, cas_collection is
cas, scheduler_collection is scheduler, and key_prefix is empty.
Change streams and the scheduler
The Mongo store implements the scheduler-store interface, and
enable_change_streams: true is what that interface needs: the store refuses
to hand out scheduler subscriptions without it. In v1.6.5, though, the simple
scheduler's experimental_backend accepts only memory and redis, so there
is no config path that puts a Mongo store behind the scheduler. Treat this
store as a CAS and Action Cache backend, and see
Redis for a shared scheduler.
Leave enable_change_streams off for a store used as a CAS. It buys nothing
there.
Change streams require a replica set
Mongo only offers change streams on a replica set or sharded cluster; a
standalone mongod cannot serve them, no matter what this flag says. Atlas
is always a replica set; a local single-node deployment needs
--replSet and an initiated set.
Options worth setting
| Field | Default | What it decides |
|---|---|---|
database | nativelink | Database name |
cas_collection | cas | Collection holding CAS objects |
scheduler_collection | scheduler | Collection holding scheduler state |
key_prefix | empty | Namespacing when several deployments share one database |
read_chunk_size | 64 KB | Bytes pulled per chunk when streaming a blob out |
max_requests | unlimited | Ceiling on concurrent requests to the deployment |
connection_timeout_ms | 3000 | Applied as both the driver's connect timeout and its server-selection timeout |
command_timeout_ms | 10000 | Accepted and defaulted, but not applied to any driver option in v1.6.5 |
enable_change_streams | false | Required for scheduler subscriptions, which nothing uses yet (see above) |
Write concern is exposed as three separate fields mirroring Mongo's own:
write_concern_w (a number like 1, or the string "majority"),
write_concern_j (whether to wait for the journal), and
write_concern_timeout_ms. All three are optional and unset means the
deployment's own default applies, but write_concern_j or
write_concern_timeout_ms without write_concern_w is rejected at startup.
For a CAS, "majority" is the honest
setting, because a cache entry acknowledged by one node and then lost to a failover is
a cache entry a client believes exists.
max_requests is the equivalent of Redis's permit ceiling and is unlimited by
default. Set it if bursts are overwhelming the deployment; queuing in
NativeLink beats timing out at Mongo. Zero is rejected at startup.
`max_concurrent_uploads` is deprecated and unused
It survives in the schema for compatibility. Setting it only logs a warning;
use max_requests to bound concurrency.
Steps
Provision the deployment: a replica set if you want writes to survive a failover with
"majority"write concern.Create a user with read and write on the database, and put the full connection string in the environment rather than the config file.
Add the store, choosing a
key_prefixif this database is shared with another NativeLink deployment.Set write concern to
"majority"for anything you intend to trust.Run a build twice, the second time from a different machine, to confirm the store is genuinely shared.
You did it right if
- Documents appear in the CAS collection during the first build.
- A second machine pointed at the same deployment gets cache hits for objects the first one uploaded.
- No connection or server-selection timeouts in the logs at your normal peak load.
When it doesn't work
Putting a local fast tier in front of this one, and the rest of the composition vocabulary.
SidewaysRedisThe backend that can hold scheduler state in v1.6.5, if you need several schedulers to share one queue.
Redis
Back the cache with Redis (standalone, sentinel or cluster) and the concurrency, chunking and timeout settings that keep it from timing out under a real build.
Oracle Cloud (OCI) Object Storage
Back the cache with OCI Object Storage through its S3 Compatibility API: Customer Secret Keys, the two adjustments the store makes for you, and what has actually been verified.