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 sectional chart cycle 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/cron-jobs.ts, the schedule registry the Railway-deployed worker reads to trigger 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/cron-jobs.ts. An automated repository check diffs every row of this table against that registry, so a schedule change that does not reach this page fails the build.
| 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 | 5,15,25,35,45,55 * * * * |
| D-ATIS | Every 10 minutes | */10 * * * * |
| TAF forecasts | Every 10 minutes | 3,13,23,33,43,53 * * * * |
| PIREPs | Every 15 minutes | */15 * * * * |
| SIGMETs / domestic | Every 15 minutes | 0,15,30,45,57 * * * * |
| International SIGMETs | Every 15 minutes | */15 * * * * |
| Center Weather Advisories | Every 15 minutes | */15 * * * * |
| SPC watches & mesoscale | Every 15 minutes | 6,21,36,51 * * * * |
| 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 at :37 | 37 * * * * |
| NOAA SWPC space weather | Hourly | 0 * * * * |
| AIRAC detector | Hourly | 0 * * * * |
| Convective forecasts | Every 2 hours | 0 */2 * * * |
| G-AIRMETs | Every 15 minutes | */15 * * * * |
| 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, at cycle+4h20m | 20 4,10,16,22 * * * |
| NDBC ocean buoys | Every 6 hours | 0 */6 * * * |
| Airworthiness Directives | Daily 06:00 UTC | 0 6 * * * |
| FAA chart tile cache | Daily 06:00 UTC | 0 6 * * * |
| FAA aircraft registry | Daily 06:41 UTC | 41 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 |
| NTSB accident reports | 1st, 8th, 15th & 22nd of month at 13:39 UTC | 39 13 1,8,15,22 * * |
| 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 * * |
| Airspace boundaries | 1st & 15th of month, 05:00 UTC | 0 5 1,15 * * |
| Airways / routes | 1st & 15th of month, 05:00 UTC | 0 5 1,15 * * |
| FAA obstacles (DOF) | Daily, 06:00 UTC | 0 6 * * * |
| FAA Part 135 operators | Monthly, 1st 09:00 UTC | 0 9 1 * * |
| UAS Facility Maps | Daily, 07:00 UTC | 0 7 * * * |
| FAA Airman dataset | Monthly, 6th 06:00 UTC | 0 6 6 * * |
Two datasets that used to appear in this table no longer run on a cron cadence at all. The FAA retired the bulk CSV endpoints behind Part 141 flight schools and Part 145 repair stations, so both are now refreshed by administrator upload rather than on a schedule — there is no interval to publish for them.
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 chart cycle would re-fetch identical bytes. The job schedule above respects the publisher in both directions.
That is why the daily chart-tile row is not a daily re-download. It is a cycle-drift check: it compares the effective AIRAC cycle against what we already hold and does nothing when they match, so the chart bytes still move on the FAA's 56-day rhythm while the check that catches a missed cycle runs every day.
Two jobs run every minute rather than on a publisher rhythm. ADS-B traffic (adsb-sync) polls FlightAware AeroAPI once a minute — it is a pull on a 60-second cycle, not a stream pushed to us. The status-page health sweep is a probe rather than an ingest, and appears in the worker for sweep-style monitoring rather than for ingest cadence.
What the AIRAC cycle is
AIRAC — Aeronautical Information Regulation And Control — is the worldwide 28-day schedule on which charting, procedures, and airspace data are republished. The procedure and airspace entries above run on it directly. The VFR chart entries do not: they run on the FAA's 56-day chart cycle, which is exactly two AIRAC cycles and shares its effective dates, which is why the two are so easily conflated. When a number accompanies the term AIRAC, that number is 28. 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.