-
Notifications
You must be signed in to change notification settings - Fork 0
Algorithm Trajectory Tiering
The trajectory logging system uses an 8-tier priority system (0-7) to intelligently capture flight position history. Higher-priority tiers (lower numbers) capture positions more frequently during operationally significant moments, while lower-priority flights are sampled less often to conserve storage.
Trajectory history allows you to:
- Replay flight paths for post-event analysis
- Review flight profiles for climb/descent patterns
- Analyze holding patterns during weather events
- Verify compliance with reroute instructions
The system automatically prioritizes tracking based on operational significance:
| Situation | Priority | Capture Rate |
|---|---|---|
| Takeoff/Landing | Highest | Every 15 seconds |
| Approaching destination | High | Every 30 seconds |
| Transitioning altitude | High | Every 30 seconds |
| Stable cruise over US | Medium | Every 5 minutes |
| Oceanic cruise | Lower | Every 10-30 minutes |
| Outside covered airspace | None | Not logged |
Flights are tracked if they have origin, destination, or current position in:
- United States (K*, P* airports)
- Canada (C* airports)
- Mexico (MM* airports)
- Central America (MG, MH, MN, MR, MP, MS, MB airports)
- Caribbean (T* airports)
- South America (S* airports)
European-to-Europe flights, for example, are not logged (Tier 7) unless they transit Americas airspace.
| Tier | Interval | Criteria | Daily Rows (est) |
|---|---|---|---|
| 0 | 15 sec | Critical phases: takeoff, landing, go-around | ~40,000 |
| 1 | 30 sec | Approaching events: TOD, destination <100nm, climbing/descending | ~60,000 |
| 2 | 1 min | Oceanic cruise (NAT, PAC) | ~20,000 |
| 3 | 2 min | Ground operations (taxi) | ~15,000 |
| 4 | 5 min | Stable cruise (US domestic) | ~80,000 |
| 5 | 10 min | Extended oceanic, sim pause detection | ~20,000 |
| 6 | 30 min | Ultra-long oceanic (>1000nm from land) | ~3,000 |
| 7 | Never | Irrelevant (outside covered airspace) | 0 |
Total estimated daily rows: ~248,000 (based on 2,000 active flights)
-- Current tier distribution
SELECT
last_trajectory_tier AS tier,
COUNT(*) AS flights,
dbo.fn_GetTierIntervalSeconds(last_trajectory_tier) AS interval_sec
FROM dbo.adl_flight_core
WHERE is_active = 1
GROUP BY last_trajectory_tier
ORDER BY last_trajectory_tier;Expected Distribution:
- Tier 0-1: 10-15% (critical phases)
- Tier 4: 50-60% (stable cruise)
- Tier 5-6: 5-10% (oceanic)
- Tier 7: 10-20% (irrelevant)
| Symptom | Cause | Resolution |
|---|---|---|
| All flights Tier 7 | fn_IsFlightRelevant broken | Check function exists |
| Too many Tier 0 | Distance calculations wrong | Verify dist_to_dest_nm populated |
| Storage growing fast | Tier thresholds too aggressive | Review tier criteria |
| Missing transitions | Interval too long | Check tier promotion logic |
-- Trajectory storage by age
SELECT
CAST(recorded_utc AS DATE) AS date,
COUNT(*) AS rows,
COUNT(*) * 60 / 1024.0 AS size_kb_estimate
FROM dbo.adl_flight_trajectory
WHERE recorded_utc > DATEADD(DAY, -7, GETUTCDATE())
GROUP BY CAST(recorded_utc AS DATE)
ORDER BY date DESC;Storage estimates:
- Hot tier (7 days): ~1.7M rows, ~100 MB
- Warm tier (30 days): ~7.5M rows, ~450 MB
- Cold tier (90 days): ~22M rows, ~1.3 GB
The fn_GetTrajectoryTier function evaluates flights in priority order:
1. Check relevance (fn_IsFlightRelevant) → If 0, return Tier 7
2. Check Tier 0 conditions (critical phases)
3. Check Tier 1 conditions (approaching events)
4. Check Tier 2 conditions (oceanic)
5. Check Tier 3 conditions (ground ops)
6. Check Tier 4 conditions (stable cruise)
7. Check Tier 5 conditions (extended oceanic)
8. Check Tier 6 conditions (ultra-long oceanic)
9. Default: Tier 4
-- Initial climb
@dist_from_origin_nm < 50 AND @vertical_rate_fpm > 300 AND @altitude_ft < 18000
-- Final approach
@dist_to_dest_nm < 15 AND @vertical_rate_fpm < -300 AND @altitude_ft < 10000
-- Go-around
@dist_to_dest_nm < 5 AND @vertical_rate_fpm > 1000 AND @altitude_ft < 5000
-- Runway operations
@groundspeed_kts BETWEEN 40 AND 180 AND @altitude_ft < 500 AND near_airport
-- Very close to airport
@dist_from_origin_nm < 3 OR @dist_to_dest_nm < 3-- Approaching TOD (within 5 minutes)
@time_to_tod_min <= 5 AND @time_to_tod_min > 0
-- Approaching destination
@dist_to_dest_nm < 100
-- Altitude transition in cruise
@altitude_ft > 25000 AND ABS(@vertical_rate_fpm) > 500
-- Any climbing/descending phase
@phase IN ('departed', 'climbing', 'descending')The system prevents inappropriate demotion to lower tiers:
-- Example: Don't demote from Tier 1 to Tier 4 if approaching TOD
IF @time_to_tod_min IS NOT NULL AND @time_to_tod_min <= 10
RETURN 1; -- Stay at Tier 1, don't demote to Tier 4This ensures operationally significant events aren't missed due to the flight being in "stable cruise" moments before a transition.
-- Checks origin airport prefix
IF @dept_icao LIKE 'K%' OR @dept_icao LIKE 'P%' -- US
RETURN 1;
IF @dept_icao LIKE 'C%' -- Canada
RETURN 1;
IF @dept_icao LIKE 'MM%' -- Mexico
RETURN 1;
-- ... etc
-- Checks destination airport prefix
-- ... same patterns
-- Checks current position bounding box
IF @current_lat BETWEEN 15 AND 72
AND @current_lon BETWEEN -180 AND -50 -- North America
RETURN 1;-- sp_ProcessTrajectoryBatch uses iTVFs for parallel execution
;WITH FlightTiers AS (
SELECT
c.flight_uid,
tier.tier AS current_tier,
interval_calc.interval_seconds
FROM dbo.adl_flight_core c
CROSS APPLY dbo.itvf_GetTrajectoryTier(...) tier
CROSS APPLY dbo.itvf_GetTierIntervalSeconds(c.last_trajectory_tier) interval_calc
WHERE c.is_active = 1 AND c.is_relevant = 1
)
INSERT INTO dbo.adl_flight_trajectory (...)
SELECT ...
FROM FlightTiers ft
WHERE ft.current_tier < 7 -- Don't log Tier 7
AND (
ft.last_trajectory_utc IS NULL
OR DATEDIFF(SECOND, ft.last_trajectory_utc, @now) >= ft.interval_seconds
);| Column | Type | Description |
|---|---|---|
trajectory_id |
BIGINT | Primary key |
flight_uid |
BIGINT | Foreign key to flight_core |
recorded_utc |
DATETIME2(0) | When position was logged |
lat |
DECIMAL(10,7) | Latitude |
lon |
DECIMAL(11,7) | Longitude |
altitude_ft |
INT | Altitude in feet |
groundspeed_kts |
INT | Groundspeed in knots |
heading_deg |
SMALLINT | Heading (0-359) |
vertical_rate_fpm |
INT | Vertical rate (+ climb, - descent) |
tier |
TINYINT | Tier at time of logging |
tier_reason |
VARCHAR(32) | Why this tier was assigned |
flight_phase |
VARCHAR(16) | Phase at time of logging |
dist_to_dest_nm |
DECIMAL(10,2) | Distance remaining |
dist_from_origin_nm |
DECIMAL(10,2) | Distance flown |
source |
VARCHAR(16) | Data source (vatsim, simulated) |
The V2.0 implementation uses inline table-valued functions (iTVFs) instead of scalar UDFs:
| Approach | Execution | Parallelism |
|---|---|---|
| Scalar UDF | Row-by-row | Single-threaded |
| iTVF | Set-based | Multi-threaded (8 vCores) |
Expected speedup: 4-8x for trajectory processing step.
- Algorithm-ETA-Calculation - Uses trajectory tier for ETA decisions
- Algorithm-Zone-Detection - Complements trajectory with OOOI events
- Database-Schema - Table definitions
- Troubleshooting - Performance issues
PERTI - Virtual Air Traffic Control System Command Center Production Site | GitHub | Report Issue
Last updated: 2026-02-25
Home Navigation Helper (NEW)
Comprehensive Guides
Getting Started
Architecture
Algorithms & Processing
- Algorithms Overview
- Algorithm ETA Calculation
- Algorithm Trajectory Tiering
- Algorithm Zone Detection
- Algorithm Route Parsing
- Algorithm Data Refresh
SWIM API (Public/External)
- SWIM API
- SWIM Routes API
- SWIM Playbook API
- SWIM Route Data Integration
- Building Route Processing
- CDM Connector Guide
PERTI API (Internal)
Features
Walkthroughs
Operations
Development
Analysis
- Analysis (index)
- ETA Accuracy (Jan-Mar 2026)
Reference