← Back to Data

Full Methodology

1. Data Collection

Job postings are collected from multiple sources via automated ingestion adapters (RSS, JSON API, XML feeds, and direct integrations). Each source runs on a configurable schedule (typically every 6 hours). Jobs are deduplicated using a SHA-256 hash of the normalized title, company name, and location.

2. Skill Normalization

Raw skill strings from job postings are normalized against a canonical skills registry. The normalizer matches on exact name, slug, or alias. Unrecognized skills are auto-created as ungrouped entries for administrative triage. A join table (job_skills) provides fast, indexed skill-dimension queries.

3. Dimension Discovery

At the start of each compute run, dimensions are discovered dynamically from the data. Only dimensions meeting the minimum sample threshold (20 jobs in the 90-day window) are considered. Dimensions include: skills, locations, companies, job types, experience levels, and remote/onsite status.

4. Salary Processing

Salary data undergoes several transformations:

  • Period normalization: hourly x 2,080, monthly x 12 to annual
  • Midpoint calculation: (min + max) / 2 when both are available
  • Outlier clipping: top and bottom 5% removed
  • Velocity caps: max 10 jobs per company per aggregate
  • Cross-source validation: values >3 std dev from median excluded

5. Confidence Scoring

Confidence reflects data reliability. It combines sample size with source quality weighting:

  • Employer-posted data receives weight 1.0
  • Imported (aggregator) data receives weight 0.7
  • User-generated data receives weight 0.5
  • Per-field confidence from the source is also factored in

6. Publication Thresholds

A stat page is published when its dimension reaches 30+ jobs. Below this threshold, the page exists but is marked as "below_threshold" and not linked publicly. Pages can be manually unpublished by administrators with a reason noted.

7. Snapshot Immutability

Quarterly snapshots are created using UTC boundaries and are immutable once written. Q1 = Jan 1 00:00:00 UTC to Mar 31 23:59:59 UTC. This ensures reproducibility and prevents timezone-related off-by-one errors in multi-region deployments.

8. Limitations

  • Statistics reflect posted salary ranges, which may differ from actual compensation
  • Not all job postings include salary data — salary stats may underrepresent certain segments
  • Location data quality depends on source accuracy; some locations may be imprecise
  • Skill extraction from unstructured text may miss or miscategorize some skills
  • Minimum sample thresholds mean niche dimensions may not have stats pages