← Blog

Data & Engineering2 min read

From SSIM to your warehouse: normalizing schedule data for analytics

A fixed-width schedule file and an analytics warehouse want very different shapes. Getting from one to the other — typed, normalized, partitioned, columnar — is the unglamorous work that makes schedule data queryable at scale.

A fixed-width SSIM record transforming into typed, partitioned columnar rows ready for a data warehouse, on an Active Flights blog card.

Sooner or later, schedule data has to leave the SSIM file and join the rest of the business — in a warehouse, a database, or a lakehouse where analysts and other systems can query it. That hand-off looks like plumbing, but doing it well is what turns a schedule from a file you parse into an asset you analyse.

Two very different shapes

A Chapter 7 record is optimized for exchange: fixed-width, positional, compact, one row per leg with segment data trailing. An analytics store wants the opposite: typed columns, explicit values, and a shape that’s cheap to filter and aggregate. The gap between them is the normalization job.

SSIM (exchange) Warehouse (analytics)
Fixed-width text, positional Typed columns (int, date, enum)
A leg pattern over a period Rows the query layer can group/join
Local times + mode + offset Normalized (UTC + local)
Codes (IATA equipment, DEIs) Resolved / mapped values

What “good” normalization does

  • Type everything. Dates as dates, times as times, days-of-operation and equipment as typed values — not strings a downstream query has to re-parse.
  • Expand deliberately. Decide whether you store the pattern (compact) or the expanded operating dates (query-friendly) — each has a cost; pick on purpose, not by accident.
  • Normalize time. Carry UTC and local so cross-timezone analysis is correct without every query re-deriving offsets.
  • Keep provenance. Retain enough to trace a row back to the source leg and the trailer-verified file it came from.

Columnar, compressed, partitioned

Schedules are wide, repetitive, and huge — exactly the profile columnar formats were built for. Storing normalized rows as a columnar format (e.g. Parquet), partitioned by the dimensions you filter on most (carrier, season, period), and compressed, gives you two wins at once: aggregations scan only the columns they need, and partition pruning skips the data they don’t. Analytical queries that would crawl over a row store run quickly over columns — and an embedded engine can query the files directly, no heavyweight cluster required.

warehouse/
  carrier=QF/season=W26/  legs.parquet   ← columnar, compressed, typed
  carrier=QF/season=S26/  legs.parquet
  …partition-pruned + column-projected at query time

The exchange format is built to travel; the analytics format is built to be asked questions. Normalization is the translation between the two.

Doing it right — and privately

The other requirement is that this often shouldn’t leave your environment. Schedule data is commercial; the ideal is to normalize and export it locally, into the shape your warehouse, database, or object store already speaks, without shipping the raw file to a third party first.

That’s exactly one of SSIM Toolkit’s jobs: read the schedule faithfully, and hand it off as clean, typed, partitioned data your stack can query — carrier-partitioned Parquet, a relational target, or a bucket for your analytics — deterministically, on your machine. The parsing stops being a project; the schedule becomes just another well-modelled table.

SSIM Toolkit · Desktop app

Download SSIM Toolkit

Enter your email and we'll send you a download link. It works for 24 hours. Free during the Early Access Preview.

By downloading, you'll receive release notes and product updates from Active Flights by email. Unsubscribe any time. See our privacy policy.