What moved since September 19, 2026.
Same method, same thresholds, same code, run 32 days apart. Each share is over its own snapshot’s active postings, and the change is in percentage points. Two snapshots are two points, so we derive no monthly rate from them, and we have not measured why any figure moved.
| Measure | 2026-09-19 | 2026-10-21 | Change |
|---|---|---|---|
| Carry at least one structural signal | 29.9% (44,482) | 30.7% (45,805) | +0.8 pts |
| Live more than 60 days | 17.6% (26,249) | 18.2% (27,191) | +0.6 pts |
| Live more than 120 days | 8.2% (12,179) | 7.9% (11,853) | −0.3 pts |
| Live more than 180 days (share of dated postings) | 5% (7,485) | 5.1% (7,651) | +0.1 pts |
| In a role listed 5 or more times | 13.7% (20,467) | 13.9% (20,775) | +0.2 pts |
| Company and title pairs listed 5 or more times | 1,360 | 1,325 | −35 |
| Company and title pairs listed 12 or more times | 308 | 313 | +5 |
| Median days live (dated postings) | 17 days | 19 days | +2 days |
| 90th percentile days live (dated postings) | 101 days | 100 days | −1 day |
Basis: every active posting, 149,008 on 2026-09-19 and 149,201 on 2026-10-21. The 180-day row, the median and the 90th percentile are over postings with a believable posted date, 148,529 and 148,806.
Coverage barely changed, and the same companies show the same move.
The index is not a fixed panel. Companies come and go as our coverage changes, and a share can move because the employer list moved rather than because any employer posted differently. Between the two snapshots, 39 companies carrying 658 postings dropped out, and 63 companies carrying 1,068 postings came in. A company whose name changed spelling counts on both sides.
Holding the employer list fixed to the 1,280 companies present on both dates gives the comparison below. Every share lands within 0.1 of a point of the headline change, so the movement above is happening inside the same companies.
| Measure | 2026-09-19 | 2026-10-21 | Change |
|---|---|---|---|
| Carry at least one structural signal | 29.9% (44,310) | 30.8% (45,641) | +0.9 pts |
| Live more than 60 days | 17.6% (26,092) | 18.3% (27,053) | +0.7 pts |
| Live more than 120 days | 8.2% (12,135) | 8% (11,822) | −0.2 pts |
| Live more than 180 days (share of dated postings) | 5% (7,459) | 5.2% (7,637) | +0.2 pts |
| In a role listed 5 or more times | 13.8% (20,451) | 14% (20,748) | +0.2 pts |
| Company and title pairs listed 5 or more times | 1,357 | 1,321 | −36 |
| Company and title pairs listed 12 or more times | 308 | 313 | +5 |
| Median days live (dated postings) | 17 days | 19 days | +2 days |
| 90th percentile days live (dated postings) | 101 days | 100 days | −1 day |
Basis: active postings at the 1,280 companies present in both snapshots, 148,350 on 2026-09-19 and 148,133 on 2026-10-21. Repeat counts are computed within a company, so they are unchanged by the restriction.
The postings that match a month later.
We matched every October posting against the September file on company, normalized title and posted date. 48,636 of the 149,008 September postings, 32.6%, have a match. That is not an exit rate. Ignore the posted date and 85,026, 57.1%, have an October posting at the same company under the same title. The other 100,372 may have been taken down, listed again under a new date, retitled, or listed under a changed company name, and the match cannot say which. None of those tells us whether a job was filled.
Read the gap with its mechanism in view. A posting live on both dates is 32 days older on the second, so staying listed is what carries it past 60 days, and 96.7% of October’s 27,191 postings past 60 days are carried over. The repeat signal runs the other way. 9.4% of carried-over postings belong to a role listed 5 or more times, against 16.1% of the rest. What the gap does tell an applicant is practical. A listing still up under the date it carried a month ago deserves the check before you apply.
The October 21, 2026 snapshot, by the numbers.
What each signal means.
Two signals, both computed from raw columns on every active posting. No model, no language analysis, no judgement call. If you want to describe this method in your own words, everything you need is here and in the methodology.
Signal 1. Live more than 60 days.
The posting’s days_live exceeds 60, where days live is the whole days between posted_at and the snapshot instant, rounded down. 27,191 postings, 18.2%, meet it. At the 120 day mark it is 11,853, 7.9%.
Slow hiring is often real. Senior, specialized and regulated roles genuinely take months. A posting open for four months with no urgency in the language is more often building a pipeline than filling a seat, but the age alone does not tell you which, and this report does not pretend otherwise.
Signal 2. The same role, listed 5 or more times.
The posting’s repeat_count is 5 or higher, where a role is one company plus one normalized title. Normalizing means collapsing every run of whitespace to a single space, trimming, and lowercasing, so two postings differing only by spacing count as the same role. 1,325 roles clear the bar and 20,775 postings belong to one.
Repetition can be a real recurring backfill, a genuinely multi-city opening, or one always-open listing collecting applicants indefinitely. The count alone cannot separate those three.
The headline is the union, not the sum.
A posting counts once toward 30.7% whether it trips one signal or both. 25,030 postings trip the age signal only, 18,614 trip the repeat signal only, and 2,161 trip both. Adding 18.2% to the repeat share would double-count those 2,161.
How long postings stay up.
Most live postings are recent. The median has been up 19 days. The distribution has a long tail, and the age signal lives in it. 5.1% of dated postings fall in the over 180 days bucket.
Basis: 148,806 active postings with a believable posted_at. Percentages are of that basis, not of all active postings.
How often the same role repeats.
Most roles appear once. The repeats concentrate hard, and the heaviest bucket is larger than the one below it. The count alone cannot say whether that is backfill, multi-city hiring or always-open listings.
Basis: all 149,201 active postings.
What we can’t claim.
No posting here is called fake. A structural signal is a prompt to verify, and the two signals we publish cannot tell an always-open pipeline listing apart from a genuinely slow search. Anyone reporting this as a count of fake jobs is reporting something we did not measure.
30.7% is a floor, not a ceiling. Our ghost-job checker also reads the language of an individual ad, which is the part that catches vague filler, evergreen wording and outright scam patterns. That analysis runs one listing at a time and has never been run across the index, so no index-wide share of it exists and we are not implying one. Apply-link liveness works the same way, per lookup rather than corpus-wide. The true share worth a second look is higher than 30.7% by an amount nobody has measured.
We can’t say why anything moved. The comparison rules out one explanation, a change in which companies we cover, and tests nothing else. Two snapshots 32 days apart are two points, not a trend, so we publish each change in percentage points beside both denominators and derive no monthly rate. The total count of active postings is not a market signal either. It has moved by tens of thousands between our measurements in both directions, and some of that movement is our own coverage changing.
The index is not the whole labor market. It covers postings pulled directly from company career pages across six applicant-tracking platforms, which skews toward employers large enough to run one. Aggregator and job-board reposts, where dead listings survive longest, are out of scope here.
One data caveat worth stating plainly. 380 active postings arrive from one feed carrying a misparsed integer where a date should be, which stamps them January 1970. Counting those as decades stale would have inflated the age signal, so they are treated as unknown-age instead. They still count toward the denominator and can never satisfy an age test. Postings genuinely dated 2009 onward are kept and do count, because they span more than a hundred companies and several feeds and so are what employers actually published. The same treatment applied on September 19, 2026, so the two snapshots handle these rows identically.
How this was built.
Four-Leaf scrapes job postings from public ATS feeds for a large index of employers. This report reads every row flagged active at a single instant, 2026-10-21T20:59:12.641Z, so the published figures and the published CSV describe the same moment rather than a scan smeared across several minutes.
For each posting we compute days live, count how many active postings share its company and normalized title, and set the two signal booleans from those two numbers. Nothing else feeds the result. The cached legitimacy_tier column in our database is deliberately unused, because it is refreshed in capped daily batches and so is a mix of scores stamped weeks apart rather than a snapshot.
The CSV is the verification artifact and it is complete, one row per active posting rather than a sample. Filter it on days_live > 60 and you get 27,191. Group by company plus title_norm, keep the groups of 5 or more, and you get 1,325 roles covering 20,775 postings. Group on the raw title instead and you will land low, because many titles here differ from a twin only by whitespace. That is why the normalized value ships as its own column. Every headline figure on this page is recomputable from that file without asking us for anything.
The stats JSON carries the definitions and the SQL that returns the same figures against the live index. One thing that SQL cannot do is rebuild this snapshot. is_active is overwritten in place and the table keeps no last-seen timestamp, so the set of postings active on a past date is gone once it passes. Run the query and you get a fresh snapshot, close to this one but not identical to it. The CSV is the durable record.
The comparison is computed from the two published CSVs, this one and the 2026 Q3 file. Before comparing anything, the script recomputes every 2026-09-19 headline figure from that CSV and refuses to run unless each one equals the published value. The panel keeps companies whose name appears in both files. The turnover match pairs postings one for one on company, title_norm and posted_at, because neither file carries ids. The stats JSON spells out each definition under comparison.
What is in the CSV.
| Column | Meaning |
|---|---|
company | Employer name as the ATS feed reports it. |
title | Job title as published, unmodified. |
title_norm | The title with whitespace runs collapsed, trimmed and lowercased. This is the column the repeat counts group on. |
posted_at | Timestamp the feed reports, exactly as reported. Empty only when the feed sent none. |
posted_at_implausible | True when posted_at fell below the epoch floor of 2000-01-01 and was discounted. The timestamp is still published so you can redo the call differently. |
days_live | Whole days between posted_at and the snapshot, rounded down. Empty when the age is unknown, meaning posted_at was missing or implausible. |
is_active | Always true. The file contains only postings live at the snapshot instant. |
repeat_count | How many active postings share this company and normalized title. |
live_over_60d | True when days_live exceeds 60. |
live_over_120d | True when days_live exceeds 120. |
role_repeated_5plus | True when repeat_count is 5 or more. |
any_structural_signal | True when either signal above is true. This column is the headline. |
149,201 data rows plus a header. No posting ids and no apply URLs, so the file cannot be used to replay our crawl.
Citation
The dataset is licensed under CC BY 4.0, so you can republish the rows, chart them, and build on them, as long as you credit Four-Leaf. Suggested citation:
Four-Leaf. “Ghost Job Signals, 2026 Q4.” Snapshot 2026-10-21. https://four-leaf.ai/research/ghost-job-signals-2026-q4
Questions about the method, or want a cut of the data we have not published? [email protected].
