<!-- llms-explorer concept facts · https://llms-explorer.com/tree/refresh-scheduling-on-atlas-scheduled-triggers-cron-secondary-or-analytics-reads/ · pack 2026-10-31 · ~1618 tokens -->

# Refresh scheduling on Atlas (Scheduled Triggers, cron, secondary or analytics reads)

> Source-anchored research for Refresh scheduling on Atlas (Scheduled Triggers, cron, secondary or analytics reads). Run status: COMPLETED.

Parent: [Read Offload via Caching and Precomputed Views ($merge/$out, Computed Pattern)](https://llms-explorer.com/tree/read-offload-via-caching-and-precomputed-views-merge-out-computed-pattern/) · 3 facets · 17 facts · page: https://llms-explorer.com/tree/refresh-scheduling-on-atlas-scheduled-triggers-cron-secondary-or-analytics-reads/

## How it works

- Starting in MongoDB 5.0, a refresh pipeline ending in $merge can execute reads on a replica-set secondary when every node has featureCompatibilityVersion 5.0 or higher, the read preference permits secondary reads, and the driver supports this behavior; output writes still go to the primary. (high confidence) — [source](https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge.md)
- Choosing secondaryPreferred does not guarantee isolation from the primary: when no eligible secondary is available, reads can fall back to the primary; secondary instead fails if no eligible secondary exists. (high confidence) — [source](https://www.mongodb.com/docs/manual/core/read-preference.md)
- Secondary reads may return stale data because replication is asynchronous; maxStalenessSeconds filters estimated replication lag and can be combined with tag sets, but it does not set the age of the last completed materialized-view refresh. (high confidence) — [source](https://www.mongodb.com/docs/manual/core/read-preference.md)
- Atlas Scheduled Triggers provide a managed scheduling alternative with five-field cron expressions interpreted in UTC, and their documented daily-report example runs an aggregation and stores its result in a reports collection. (low confidence) (verified as of 2026-10-31) — [source](https://www.mongodb.com/docs/atlas/atlas-ui/triggers/scheduled-triggers.md)
- Starting in MongoDB 5.0, pipelines ending in $merge or $out can execute on replica-set secondaries when all nodes have featureCompatibilityVersion 5.0 or higher and read preference permits secondary reads; driver support must also be checked. (medium confidence) (verified as of 2026-10-31) — [source](https://www.mongodb.com/docs/manual/core/read-preference.md)
- For strict Atlas analytics-read isolation, use readPreference=secondary with readPreferenceTags=nodeType:ANALYTICS. An empty fallback tag permits other eligible secondaries, and secondaryPreferred can fall back to the primary when no eligible secondary is available. (medium confidence) (verified as of 2026-10-31) — [source](https://www.mongodb.com/docs/atlas/reference/replica-set-tags.md)

## Comparisons and alternatives

- For an external refresh worker scheduled with Kubernetes CronJob, concurrencyPolicy:Forbid prevents overlap only among Jobs from that same CronJob; delayed or duplicate execution remains possible, so make the refresh idempotent and monitor completed runs rather than assuming every scheduled tick succeeds. (low confidence) — [source](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)
- Percona's January 14, 2026 workload study found almost no throughput gain from secondaryPreferred for its 54%-read/46%-write workload, while a read-only workload benefited; secondary read offload therefore needs workload-specific measurement rather than an assumed speedup. (low confidence) — [source](https://www.percona.com/blog/the-importance-of-realistic-benchmark-workloads/)
- Kubernetes CronJob scheduling is approximate: a scheduled execution can create two Jobs or no Job. Refresh workers should therefore be idempotent rather than assume exactly-once execution. (low confidence) — [source](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)
- Design inference: assess refresh freshness from completed runs and source replication lag, rather than equating the cron interval with a hard freshness bound; missed or overlapping jobs and stale secondary inputs can invalidate that bound. (medium confidence) — [source](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)

## Facts and statements

- Atlas exposes the predefined nodeType:ANALYTICS tag; combine it with secondary read preference to target analytics nodes for refresh reads, while an empty fallback tag permits other secondaries if analytics nodes are unavailable. (high confidence) — [source](https://www.mongodb.com/docs/atlas/reference/replica-set-tags.md)
- The manufacturing-mes-dashboard repository documents scheduled batch refresh through refresh_views.py and explicitly says automatic change-stream or Atlas Stream Processing refresh was not implemented in that demonstration; it is an implementation example, not production validation of a streaming refresh system. (low confidence) (verified as of 2026-10-31) — [source](https://github.com/pcleene/manufacturing-mes-dashboard)
- Executing a $merge or $out refresh pipeline on a secondary offloads eligible read execution, while output writes are sent to the primary; it does not remove refresh write load from the primary. (medium confidence) — [source](https://www.mongodb.com/docs/manual/core/read-preference.md)
- Read preference tags can direct reporting or refresh reads to selected secondary members. Atlas exposes nodeType:ANALYTICS for targeting its analytics nodes; Percona independently demonstrates purpose-based tagged read routing in a replica-set example. (medium confidence) — [source](https://www.mongodb.com/docs/atlas/reference/replica-set-tags.md)
- MongoDB secondary reads may return stale data. A scheduled refresh that reads a secondary therefore must tolerate stale inputs; completing a refresh does not by itself prove that it includes the latest source writes. (low confidence) — [source](https://www.mongodb.com/docs/manual/core/read-preference.md)
- Kubernetes concurrencyPolicy: Forbid skips a new run while a previous run remains active. Its concurrency policy applies only to Jobs created by that same CronJob, so separate refresh CronJobs can still overlap. (low confidence) — [source](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)
- Kubernetes CronJobs without spec.timeZone use the controller local time zone; spec.timeZone: Etc/UTC makes UTC interpretation explicit. (low confidence) — [source](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)
