Freshness and Refresh Cycles
How often AeroCopilot refreshes each upstream feed — from 5-minute METAR pulls to 28-day AIRAC cycles, with the exact cron schedules that drive ingest.
Freshness and Refresh Cycles
Every data source AeroCopilot ingests has a refresh cadence chosen to match how the upstream agency publishes. METAR observations move every five minutes; the FAA Digital Obstacle File moves every 56 days. Pulling either too slowly or too fast adds no value — and in the slow case, can mislead.
This page documents the actual cron schedules running in production. The source of truth is apps/cron-worker/index.ts, the Railway-deployed worker that triggers every refresh endpoint.
How the worker runs
The cron worker is a long-running Node process. Each entry has a name, an HTTP path on the Next.js app, and a standard five-field cron expression. When a schedule fires, the worker acquires a Postgres advisory lock (so multiple replicas don't double-trigger), calls the corresponding /api/cron/* endpoint with the CRON_SECRET bearer token, and retries with exponential backoff (1 s, 4 s, 16 s) on failure. Each run writes a row to the sync_job table and optionally pings a Healthchecks.io URL configured per job.
That gives every refresh four guarantees:
- Single-fire — one execution per scheduled tick, even with multiple worker replicas.
- Retried — three attempts before a failure is final.
- Audited — start time, completion time, duration, and error message persisted to
sync_job. - Externally watched — Healthchecks.io fires an alert if a job stops pinging.
Refresh cadences in production
The schedules below are taken directly from the cron worker. Cadence column is the human-readable interval; cron column is the literal expression in apps/cron-worker/index.ts.
| Job | Cadence | Cron expression |
|---|---|---|
| METAR observations | Every 5 minutes | */5 * * * * |
| FAA airport status (delays / ground stops) | Every 5 minutes | */5 * * * * |
| NWS public alerts | Every 5 minutes | */5 * * * * |
| NOTAM sync | Every 10 minutes | */10 * * * * |
| TFR sync | Every 10 minutes | */10 * * * * |
| D-ATIS | Every 10 minutes | */10 * * * * |
| PIREPs | Every 15 minutes | */15 * * * * |
| SIGMETs / domestic | Every 15 minutes | */15 * * * * |
| International SIGMETs | Every 15 minutes | */15 * * * * |
| Center Weather Advisories | Every 15 minutes | */15 * * * * |
| SPC watches & mesoscale | Every 15 minutes | */15 * * * * |
| TAF forecasts | Every 30 minutes | */30 * * * * |
| Met Impact Statements | Every 30 minutes | */30 * * * * |
| Nav Canada METAR/TAF | Every 30 minutes | */30 * * * * |
| Tile source health probe | Every 30 minutes | */30 * * * * |
| Status page health sweep | Every 2 minutes | */2 * * * * |
| AirNow AQI | Hourly | 0 * * * * |
| NOAA SWPC space weather | Hourly | 0 * * * * |
| AIRAC detector | Hourly | 0 * * * * |
| Convective forecasts | Every 2 hours | 0 */2 * * * |
| G-AIRMETs | Every 3 hours | 0 */3 * * * |
| NOAA HMS smoke plumes | Every 3 hours | 0 */3 * * * |
| NWS forecast discussions | Every 3 hours | 0 */3 * * * |
| NHC tropical cyclones | Every 3 hours | 0 */3 * * * |
| Winds and temperatures aloft | Every 6 hours | 0 */6 * * * |
| FAA weather cameras | Every 6 hours | 0 */6 * * * |
| MOS forecasts | Every 6 hours | 0 */6 * * * |
| NDBC ocean buoys | Every 6 hours | 0 */6 * * * |
| Airworthiness Directives | Daily 06:00 UTC | 0 6 * * * |
| Pilot alerts (AD / Medical / BFR) | Daily 08:00 UTC | 0 8 * * * |
| Email engagement campaigns | Daily 09:00 UTC | 0 9 * * * |
| Vermont post-trial confirm | Daily 09:00 UTC | 0 9 * * * |
| Compliance notifications | Daily 10:00 UTC | 0 10 * * * |
| Weather data cleanup | Daily 03:00 UTC | 0 3 * * * |
| OpsAuditLog 7-year retention purge | Daily 04:00 UTC | 0 4 * * * |
| Weather station metadata sync | Weekly Sunday 04:00 UTC | 0 4 * * 0 |
| Historic AD backfill | Weekly Sunday 02:00 UTC | 0 2 * * 0 |
| FAA obstacles (DOF) | Weekly Sunday 05:00 UTC | 0 5 * * 0 |
| Airspace boundaries | Weekly Sunday 05:00 UTC | 0 5 * * 0 |
| NTSB accident reports | Weekly Sunday 05:00 UTC | 0 5 * * 0 |
| Airways / routes | Weekly Sunday 06:00 UTC | 0 6 * * 0 |
| FAA chart tile cache | Weekly Sunday 06:00 UTC | 0 6 * * 0 |
| NASR 28-day airports | 1st & 15th of month, 02:00 UTC | 0 2 1,15 * * |
| CIFP procedures | 1st & 15th of month, 04:00 UTC | 0 4 1,15 * * |
| FAA aircraft registry | Monthly, 1st 03:00 UTC | 0 3 1 * * |
| FAA Part 141 flight schools | Monthly, 1st 07:00 UTC | 0 7 1 * * |
| FAA Part 145 repair stations | Monthly, 1st 08:00 UTC | 0 8 1 * * |
| FAA Part 135 operators | Monthly, 1st 09:00 UTC | 0 9 1 * * |
| UAS Facility Maps | Monthly, 1st 07:00 UTC | 0 7 1 * * |
| FAA Airman dataset | Monthly, 6th 06:00 UTC | 0 6 6 * * |
Why some jobs are every 5 minutes and some are every 56 days
Cadence follows the upstream publication rhythm. Pulling METAR more often than the 5-minute window the NWS publishes on would burn requests for no new data. Pulling sectional charts more often than the 56-day FAA AIRAC cycle would re-fetch identical bytes. The job schedule above respects the publisher in both directions.
The sub-minute exceptions — ADS-B traffic and the status-page health sweep — are streaming or probe workloads, not pulled refreshes; they appear in the worker for sweep-style monitoring rather than for ingest cadence.
What the AIRAC cycle is
Several entries above run on the 28-day or 56-day rhythm. These align with the FAA's Aeronautical Information Regulation And Control (AIRAC) cycle — the worldwide schedule on which charting, procedures, and airspace data are republished. The hourly airac-detector job watches for a new cycle becoming effective and triggers the dependent chart, CIFP, and procedure refreshes when one drops.
Where to see live freshness
- The
/data-sourcesdirectory shows the cadence badge per source. - The
/data-leaderboardpage ranks the catalog from freshest to slowest. - Authenticated admin users can inspect
sync_jobhistory via the internal admin tools.