~/job-market-analytics

analytics engineering · portfolio project

Job postings in.
Tested, ranked data out.

A scheduled pipeline that pulls every public, keyless ATS feed into BigQuery, models it through a bronze → silver → gold dbt project that runs identically on DuckDB, and delivers a ranked digest of what is new. Every invariant it relies on is enforced by a check that fails — not by intent.

make site
manifest22 models · 11 sources · 2 exposures
built as3 incremental · 9 table · 10 view
tests117 data · 18 unit
contracts2 enforced
docs40 pages · 0 broken links
commit76fca94 · 2026-11-04
22dbt modelsbronze → silver → gold
117data testsschema + relationship contracts
18dbt unit testsmodel logic on fixed inputs
368pytest functionsbehind an enforced coverage floor
29decision recordsevery non-obvious choice

01Hiring at the tracked companies rebuilt after every scheduled run

Not the whole job market: these figures describe a curated list of company boards that the pipeline reads, and only those. They are the gold-zone agg_market_* models, exported by the production run and drawn when this page was built.

15,380open postings
211tracked companies hiring
1,199new in the last 7 days
44 daysmedian time a posting stays up

Open postings per tracked board

Divided by the boards read that day, so adding companies to the list does not read as a hiring surge.

020406080Jul 15Nov 4732026-07-15: 73.0 per board (511 open on 7 boards, 3 new)2026-07-16: 72.9 per board (510 open on 7 boards, 14 new)2026-07-17: 74.3 per board (520 open on 7 boards, 22 new)2026-07-18: 59.9 per board (539 open on 9 boards, 2 new)2026-07-19: 59.9 per board (539 open on 9 boards, 0 new)2026-07-20: 59.7 per board (537 open on 9 boards, 12 new)2026-07-21: 59.6 per board (536 open on 9 boards, 8 new)2026-07-22: 37.9 per board (379 open on 10 boards, 1 new)2026-07-23: 37.8 per board (378 open on 10 boards, 3 new)2026-07-24: 37.8 per board (378 open on 10 boards, 3 new)2026-07-25: 37.8 per board (378 open on 10 boards, 1 new)2026-07-26: 37.8 per board (378 open on 10 boards, 0 new)2026-07-27: 37.6 per board (376 open on 10 boards, 3 new)2026-07-28: 75.8 per board (9,015 open on 119 boards, 116 new)2026-07-29: 76.9 per board (9,074 open on 118 boards, 229 new)2026-07-30: 76.5 per board (9,108 open on 119 boards, 181 new)2026-07-31: 77.0 per board (9,168 open on 119 boards, 194 new)2026-08-01: 76.8 per board (9,140 open on 119 boards, 28 new)2026-08-02: 65.5 per board (10,409 open on 159 boards, 1 new)2026-08-03: 65.4 per board (10,467 open on 160 boards, 150 new)2026-08-04: 65.3 per board (10,508 open on 161 boards, 213 new)2026-08-05: 65.7 per board (10,577 open on 161 boards, 251 new)2026-08-07: 66.2 per board (10,666 open on 161 boards, 416 new)2026-08-08: 65.6 per board (10,562 open on 161 boards, 52 new)2026-08-09: 65.6 per board (10,563 open on 161 boards, 9 new)2026-08-10: 65.7 per board (10,574 open on 161 boards, 95 new)2026-08-14: 66.4 per board (10,691 open on 161 boards, 949 new)2026-08-15: 66.5 per board (10,709 open on 161 boards, 41 new)2026-08-16: 66.5 per board (10,706 open on 161 boards, 3 new)2026-08-31: 69.5 per board (10,844 open on 156 boards, 2,090 new)2026-09-01: 67.8 per board (10,573 open on 156 boards, 222 new)2026-09-02: 68.2 per board (10,638 open on 156 boards, 251 new)2026-09-03: 68.1 per board (10,629 open on 156 boards, 221 new)2026-09-04: 68.2 per board (10,645 open on 156 boards, 196 new)2026-09-05: 67.9 per board (10,589 open on 156 boards, 21 new)2026-09-06: 67.9 per board (10,594 open on 156 boards, 10 new)2026-09-07: 67.9 per board (10,597 open on 156 boards, 75 new)2026-09-08: 68.2 per board (10,638 open on 156 boards, 209 new)2026-09-09: 68.3 per board (10,653 open on 156 boards, 244 new)2026-09-10: 68.4 per board (10,678 open on 156 boards, 195 new)2026-09-11: 68.8 per board (10,737 open on 156 boards, 234 new)2026-09-12: 68.6 per board (10,700 open on 156 boards, 32 new)2026-09-13: 68.6 per board (10,698 open on 156 boards, 6 new)2026-09-14: 69.1 per board (10,774 open on 156 boards, 227 new)2026-09-15: 69.7 per board (10,800 open on 155 boards, 249 new)2026-09-16: 69.7 per board (10,811 open on 155 boards, 252 new)2026-09-17: 69.8 per board (10,826 open on 155 boards, 221 new)2026-09-18: 69.9 per board (10,838 open on 155 boards, 215 new)2026-09-19: 69.7 per board (10,796 open on 155 boards, 23 new)2026-09-20: 69.6 per board (10,782 open on 155 boards, 5 new)2026-09-21: 69.6 per board (10,781 open on 155 boards, 179 new)2026-09-22: 69.6 per board (10,784 open on 155 boards, 179 new)2026-09-23: 69.7 per board (10,806 open on 155 boards, 224 new)2026-09-24: 70.3 per board (10,830 open on 154 boards, 237 new)2026-09-25: 70.6 per board (10,806 open on 153 boards, 202 new)2026-09-26: 70.3 per board (10,763 open on 153 boards, 33 new)2026-09-27: 70.3 per board (10,762 open on 153 boards, 5 new)2026-09-28: 70.0 per board (10,705 open on 153 boards, 198 new)2026-09-29: 69.9 per board (10,693 open on 153 boards, 231 new)2026-09-30: 69.8 per board (10,676 open on 153 boards, 211 new)2026-10-01: 69.9 per board (10,625 open on 152 boards, 216 new)2026-10-02: 70.2 per board (10,672 open on 152 boards, 206 new)2026-10-03: 69.8 per board (10,538 open on 151 boards, 15 new)2026-10-04: 69.8 per board (10,544 open on 151 boards, 12 new)2026-10-06: 71.5 per board (10,724 open on 150 boards, 454 new)2026-10-07: 70.9 per board (10,494 open on 148 boards, 201 new)2026-10-08: 70.5 per board (10,508 open on 149 boards, 218 new)2026-10-09: 70.6 per board (10,514 open on 149 boards, 198 new)2026-10-10: 70.7 per board (10,468 open on 148 boards, 13 new)2026-10-11: 70.7 per board (10,466 open on 148 boards, 6 new)2026-10-12: 70.5 per board (10,436 open on 148 boards, 109 new)2026-10-13: 77.6 per board (15,988 open on 206 boards, 303 new)2026-10-14: 77.0 per board (15,852 open on 206 boards, 329 new)2026-10-15: 76.9 per board (15,915 open on 207 boards, 392 new)2026-10-16: 77.0 per board (16,018 open on 208 boards, 355 new)2026-10-17: 77.0 per board (15,947 open on 207 boards, 33 new)2026-10-18: 77.1 per board (15,954 open on 207 boards, 13 new)2026-10-19: 76.8 per board (15,903 open on 207 boards, 277 new)2026-10-20: 76.5 per board (15,919 open on 208 boards, 282 new)2026-10-21: 76.8 per board (15,969 open on 208 boards, 347 new)2026-10-22: 76.9 per board (15,985 open on 208 boards, 345 new)2026-10-23: 76.6 per board (15,943 open on 208 boards, 307 new)2026-10-24: 76.3 per board (15,865 open on 208 boards, 31 new)2026-10-25: 76.3 per board (15,865 open on 208 boards, 7 new)2026-10-26: 75.7 per board (15,811 open on 209 boards, 271 new)2026-10-27: 74.9 per board (15,809 open on 211 boards, 301 new)2026-10-28: 74.5 per board (15,711 open on 211 boards, 292 new)2026-10-29: 74.6 per board (15,738 open on 211 boards, 336 new)2026-10-30: 74.8 per board (15,710 open on 210 boards, 277 new)2026-10-31: 74.4 per board (15,629 open on 210 boards, 18 new)2026-11-01: 74.4 per board (15,628 open on 210 boards, 11 new)2026-11-02: 73.4 per board (15,482 open on 211 boards, 241 new)2026-11-03: 74.3 per board (15,687 open on 211 boards, 257 new)2026-11-04: 72.9 per board (15,380 open on 211 boards, 59 new)
020406080Jul 15Nov 4732026-07-15: 73.0 per board (511 open on 7 boards, 3 new)2026-07-16: 72.9 per board (510 open on 7 boards, 14 new)2026-07-17: 74.3 per board (520 open on 7 boards, 22 new)2026-07-18: 59.9 per board (539 open on 9 boards, 2 new)2026-07-19: 59.9 per board (539 open on 9 boards, 0 new)2026-07-20: 59.7 per board (537 open on 9 boards, 12 new)2026-07-21: 59.6 per board (536 open on 9 boards, 8 new)2026-07-22: 37.9 per board (379 open on 10 boards, 1 new)2026-07-23: 37.8 per board (378 open on 10 boards, 3 new)2026-07-24: 37.8 per board (378 open on 10 boards, 3 new)2026-07-25: 37.8 per board (378 open on 10 boards, 1 new)2026-07-26: 37.8 per board (378 open on 10 boards, 0 new)2026-07-27: 37.6 per board (376 open on 10 boards, 3 new)2026-07-28: 75.8 per board (9,015 open on 119 boards, 116 new)2026-07-29: 76.9 per board (9,074 open on 118 boards, 229 new)2026-07-30: 76.5 per board (9,108 open on 119 boards, 181 new)2026-07-31: 77.0 per board (9,168 open on 119 boards, 194 new)2026-08-01: 76.8 per board (9,140 open on 119 boards, 28 new)2026-08-02: 65.5 per board (10,409 open on 159 boards, 1 new)2026-08-03: 65.4 per board (10,467 open on 160 boards, 150 new)2026-08-04: 65.3 per board (10,508 open on 161 boards, 213 new)2026-08-05: 65.7 per board (10,577 open on 161 boards, 251 new)2026-08-07: 66.2 per board (10,666 open on 161 boards, 416 new)2026-08-08: 65.6 per board (10,562 open on 161 boards, 52 new)2026-08-09: 65.6 per board (10,563 open on 161 boards, 9 new)2026-08-10: 65.7 per board (10,574 open on 161 boards, 95 new)2026-08-14: 66.4 per board (10,691 open on 161 boards, 949 new)2026-08-15: 66.5 per board (10,709 open on 161 boards, 41 new)2026-08-16: 66.5 per board (10,706 open on 161 boards, 3 new)2026-08-31: 69.5 per board (10,844 open on 156 boards, 2,090 new)2026-09-01: 67.8 per board (10,573 open on 156 boards, 222 new)2026-09-02: 68.2 per board (10,638 open on 156 boards, 251 new)2026-09-03: 68.1 per board (10,629 open on 156 boards, 221 new)2026-09-04: 68.2 per board (10,645 open on 156 boards, 196 new)2026-09-05: 67.9 per board (10,589 open on 156 boards, 21 new)2026-09-06: 67.9 per board (10,594 open on 156 boards, 10 new)2026-09-07: 67.9 per board (10,597 open on 156 boards, 75 new)2026-09-08: 68.2 per board (10,638 open on 156 boards, 209 new)2026-09-09: 68.3 per board (10,653 open on 156 boards, 244 new)2026-09-10: 68.4 per board (10,678 open on 156 boards, 195 new)2026-09-11: 68.8 per board (10,737 open on 156 boards, 234 new)2026-09-12: 68.6 per board (10,700 open on 156 boards, 32 new)2026-09-13: 68.6 per board (10,698 open on 156 boards, 6 new)2026-09-14: 69.1 per board (10,774 open on 156 boards, 227 new)2026-09-15: 69.7 per board (10,800 open on 155 boards, 249 new)2026-09-16: 69.7 per board (10,811 open on 155 boards, 252 new)2026-09-17: 69.8 per board (10,826 open on 155 boards, 221 new)2026-09-18: 69.9 per board (10,838 open on 155 boards, 215 new)2026-09-19: 69.7 per board (10,796 open on 155 boards, 23 new)2026-09-20: 69.6 per board (10,782 open on 155 boards, 5 new)2026-09-21: 69.6 per board (10,781 open on 155 boards, 179 new)2026-09-22: 69.6 per board (10,784 open on 155 boards, 179 new)2026-09-23: 69.7 per board (10,806 open on 155 boards, 224 new)2026-09-24: 70.3 per board (10,830 open on 154 boards, 237 new)2026-09-25: 70.6 per board (10,806 open on 153 boards, 202 new)2026-09-26: 70.3 per board (10,763 open on 153 boards, 33 new)2026-09-27: 70.3 per board (10,762 open on 153 boards, 5 new)2026-09-28: 70.0 per board (10,705 open on 153 boards, 198 new)2026-09-29: 69.9 per board (10,693 open on 153 boards, 231 new)2026-09-30: 69.8 per board (10,676 open on 153 boards, 211 new)2026-10-01: 69.9 per board (10,625 open on 152 boards, 216 new)2026-10-02: 70.2 per board (10,672 open on 152 boards, 206 new)2026-10-03: 69.8 per board (10,538 open on 151 boards, 15 new)2026-10-04: 69.8 per board (10,544 open on 151 boards, 12 new)2026-10-06: 71.5 per board (10,724 open on 150 boards, 454 new)2026-10-07: 70.9 per board (10,494 open on 148 boards, 201 new)2026-10-08: 70.5 per board (10,508 open on 149 boards, 218 new)2026-10-09: 70.6 per board (10,514 open on 149 boards, 198 new)2026-10-10: 70.7 per board (10,468 open on 148 boards, 13 new)2026-10-11: 70.7 per board (10,466 open on 148 boards, 6 new)2026-10-12: 70.5 per board (10,436 open on 148 boards, 109 new)2026-10-13: 77.6 per board (15,988 open on 206 boards, 303 new)2026-10-14: 77.0 per board (15,852 open on 206 boards, 329 new)2026-10-15: 76.9 per board (15,915 open on 207 boards, 392 new)2026-10-16: 77.0 per board (16,018 open on 208 boards, 355 new)2026-10-17: 77.0 per board (15,947 open on 207 boards, 33 new)2026-10-18: 77.1 per board (15,954 open on 207 boards, 13 new)2026-10-19: 76.8 per board (15,903 open on 207 boards, 277 new)2026-10-20: 76.5 per board (15,919 open on 208 boards, 282 new)2026-10-21: 76.8 per board (15,969 open on 208 boards, 347 new)2026-10-22: 76.9 per board (15,985 open on 208 boards, 345 new)2026-10-23: 76.6 per board (15,943 open on 208 boards, 307 new)2026-10-24: 76.3 per board (15,865 open on 208 boards, 31 new)2026-10-25: 76.3 per board (15,865 open on 208 boards, 7 new)2026-10-26: 75.7 per board (15,811 open on 209 boards, 271 new)2026-10-27: 74.9 per board (15,809 open on 211 boards, 301 new)2026-10-28: 74.5 per board (15,711 open on 211 boards, 292 new)2026-10-29: 74.6 per board (15,738 open on 211 boards, 336 new)2026-10-30: 74.8 per board (15,710 open on 210 boards, 277 new)2026-10-31: 74.4 per board (15,629 open on 210 boards, 18 new)2026-11-01: 74.4 per board (15,628 open on 210 boards, 11 new)2026-11-02: 73.4 per board (15,482 open on 211 boards, 241 new)2026-11-03: 74.3 per board (15,687 open on 211 boards, 257 new)2026-11-04: 72.9 per board (15,380 open on 211 boards, 59 new)
Table view
DayBoardsOpenPer boardNewCompanies
2026-07-15751173.037
2026-07-16751072.9147
2026-07-17752074.3227
2026-07-18953959.929
2026-07-19953959.909
2026-07-20953759.7129
2026-07-21953659.689
2026-07-221037937.9114
2026-07-231037837.8314
2026-07-241037837.8314
2026-07-251037837.8114
2026-07-261037837.8014
2026-07-271037637.6314
2026-07-281199,01575.8116122
2026-07-291189,07476.9229122
2026-07-301199,10876.5181122
2026-07-311199,16877.0194122
2026-08-011199,14076.828122
2026-08-0215910,40965.51162
2026-08-0316010,46765.4150163
2026-08-0416110,50865.3213164
2026-08-0516110,57765.7251164
2026-08-0716110,66666.2416164
2026-08-0816110,56265.652164
2026-08-0916110,56365.69164
2026-08-1016110,57465.795164
2026-08-1416110,69166.4949164
2026-08-1516110,70966.541164
2026-08-1616110,70666.53164
2026-08-3115610,84469.52,090159
2026-09-0115610,57367.8222159
2026-09-0215610,63868.2251159
2026-09-0315610,62968.1221159
2026-09-0415610,64568.2196159
2026-09-0515610,58967.921159
2026-09-0615610,59467.910159
2026-09-0715610,59767.975159
2026-09-0815610,63868.2209159
2026-09-0915610,65368.3244159
2026-09-1015610,67868.4195159
2026-09-1115610,73768.8234159
2026-09-1215610,70068.632159
2026-09-1315610,69868.66159
2026-09-1415610,77469.1227159
2026-09-1515510,80069.7249158
2026-09-1615510,81169.7252158
2026-09-1715510,82669.8221158
2026-09-1815510,83869.9215158
2026-09-1915510,79669.723158
2026-09-2015510,78269.65158
2026-09-2115510,78169.6179158
2026-09-2215510,78469.6179158
2026-09-2315510,80669.7224158
2026-09-2415410,83070.3237157
2026-09-2515310,80670.6202156
2026-09-2615310,76370.333156
2026-09-2715310,76270.35156
2026-09-2815310,70570.0198156
2026-09-2915310,69369.9231156
2026-09-3015310,67669.8211156
2026-10-0115210,62569.9216155
2026-10-0215210,67270.2206155
2026-10-0315110,53869.815154
2026-10-0415110,54469.812154
2026-10-0615010,72471.5454153
2026-10-0714810,49470.9201151
2026-10-0814910,50870.5218152
2026-10-0914910,51470.6198152
2026-10-1014810,46870.713151
2026-10-1114810,46670.76151
2026-10-1214810,43670.5109151
2026-10-1320615,98877.6303206
2026-10-1420615,85277.0329206
2026-10-1520715,91576.9392207
2026-10-1620816,01877.0355208
2026-10-1720715,94777.033207
2026-10-1820715,95477.113207
2026-10-1920715,90376.8277207
2026-10-2020815,91976.5282208
2026-10-2120815,96976.8347208
2026-10-2220815,98576.9345208
2026-10-2320815,94376.6307208
2026-10-2420815,86576.331208
2026-10-2520815,86576.37208
2026-10-2620915,81175.7271209
2026-10-2721115,80974.9301211
2026-10-2821115,71174.5292211
2026-10-2921115,73874.6336211
2026-10-3021015,71074.8277211
2026-10-3121015,62974.418211
2026-11-0121015,62874.411211
2026-11-0221115,48273.4241211
2026-11-0321115,68774.3257211
2026-11-0421115,38072.959211

How long a posting stays up

Kaplan-Meier: still-open postings count as censored, not as closed.

0%25%50%75%100%day 0day 104median 44 days14%day 0: 100% still upday 0: 98% still up (16,629 at risk)day 1: 96% still up (16,202 at risk)day 2: 94% still up (15,695 at risk)day 3: 93% still up (15,105 at risk)day 4: 92% still up (14,884 at risk)day 5: 91% still up (14,711 at risk)day 6: 89% still up (14,266 at risk)day 7: 88% still up (13,714 at risk)day 8: 87% still up (13,260 at risk)day 9: 86% still up (12,842 at risk)day 10: 85% still up (12,436 at risk)day 11: 84% still up (12,295 at risk)day 12: 82% still up (12,094 at risk)day 13: 81% still up (11,656 at risk)day 14: 80% still up (11,181 at risk)day 15: 79% still up (10,708 at risk)day 16: 78% still up (10,364 at risk)day 17: 77% still up (10,002 at risk)day 18: 76% still up (9,826 at risk)day 19: 75% still up (9,670 at risk)day 20: 74% still up (9,265 at risk)day 21: 72% still up (8,843 at risk)day 22: 72% still up (8,486 at risk)day 23: 71% still up (8,174 at risk)day 24: 69% still up (7,994 at risk)day 25: 69% still up (7,861 at risk)day 26: 68% still up (7,759 at risk)day 27: 66% still up (7,511 at risk)day 28: 65% still up (7,219 at risk)day 29: 65% still up (6,962 at risk)day 30: 64% still up (6,607 at risk)day 31: 63% still up (6,498 at risk)day 32: 62% still up (6,395 at risk)day 33: 61% still up (6,284 at risk)day 34: 60% still up (6,056 at risk)day 35: 59% still up (5,824 at risk)day 36: 58% still up (5,655 at risk)day 37: 57% still up (5,420 at risk)day 38: 56% still up (5,221 at risk)day 39: 55% still up (5,137 at risk)day 40: 54% still up (5,044 at risk)day 41: 53% still up (4,847 at risk)day 42: 52% still up (4,628 at risk)day 43: 51% still up (4,414 at risk)day 44: 50% still up (4,206 at risk)day 45: 49% still up (4,043 at risk)day 46: 48% still up (3,947 at risk)day 47: 47% still up (3,854 at risk)day 48: 46% still up (3,681 at risk)day 49: 45% still up (3,520 at risk)day 50: 44% still up (3,344 at risk)day 51: 43% still up (3,174 at risk)day 52: 42% still up (3,012 at risk)day 53: 41% still up (2,946 at risk)day 54: 41% still up (2,862 at risk)day 55: 40% still up (2,723 at risk)day 56: 39% still up (2,556 at risk)day 57: 38% still up (2,417 at risk)day 58: 37% still up (2,305 at risk)day 59: 37% still up (2,238 at risk)day 60: 36% still up (2,205 at risk)day 61: 35% still up (2,141 at risk)day 62: 34% still up (2,030 at risk)day 63: 34% still up (1,892 at risk)day 64: 33% still up (1,785 at risk)day 65: 33% still up (1,681 at risk)day 66: 32% still up (996 at risk)day 67: 32% still up (986 at risk)day 68: 31% still up (958 at risk)day 69: 30% still up (940 at risk)day 70: 29% still up (904 at risk)day 71: 29% still up (889 at risk)day 72: 28% still up (874 at risk)day 73: 28% still up (854 at risk)day 74: 27% still up (837 at risk)day 75: 26% still up (818 at risk)day 76: 26% still up (802 at risk)day 77: 26% still up (792 at risk)day 78: 26% still up (784 at risk)day 79: 25% still up (778 at risk)day 80: 25% still up (772 at risk)day 81: 25% still up (761 at risk)day 82: 24% still up (736 at risk)day 83: 24% still up (516 at risk)day 84: 23% still up (508 at risk)day 85: 22% still up (496 at risk)day 86: 22% still up (470 at risk)day 87: 21% still up (431 at risk)day 88: 21% still up (417 at risk)day 89: 20% still up (392 at risk)day 90: 20% still up (294 at risk)day 91: 19% still up (288 at risk)day 92: 19% still up (229 at risk)day 93: 19% still up (193 at risk)day 94: 18% still up (161 at risk)day 95: 18% still up (156 at risk)day 96: 18% still up (145 at risk)day 97: 18% still up (107 at risk)day 98: 17% still up (69 at risk)day 99: 17% still up (32 at risk)day 100: 17% still up (10 at risk)day 101: 15% still up (9 at risk)day 102: 14% still up (8 at risk)day 104: 14% still up (7 at risk)
0%25%50%75%100%day 0day 104median 44 days14%day 0: 100% still upday 0: 98% still up (16,629 at risk)day 1: 96% still up (16,202 at risk)day 2: 94% still up (15,695 at risk)day 3: 93% still up (15,105 at risk)day 4: 92% still up (14,884 at risk)day 5: 91% still up (14,711 at risk)day 6: 89% still up (14,266 at risk)day 7: 88% still up (13,714 at risk)day 8: 87% still up (13,260 at risk)day 9: 86% still up (12,842 at risk)day 10: 85% still up (12,436 at risk)day 11: 84% still up (12,295 at risk)day 12: 82% still up (12,094 at risk)day 13: 81% still up (11,656 at risk)day 14: 80% still up (11,181 at risk)day 15: 79% still up (10,708 at risk)day 16: 78% still up (10,364 at risk)day 17: 77% still up (10,002 at risk)day 18: 76% still up (9,826 at risk)day 19: 75% still up (9,670 at risk)day 20: 74% still up (9,265 at risk)day 21: 72% still up (8,843 at risk)day 22: 72% still up (8,486 at risk)day 23: 71% still up (8,174 at risk)day 24: 69% still up (7,994 at risk)day 25: 69% still up (7,861 at risk)day 26: 68% still up (7,759 at risk)day 27: 66% still up (7,511 at risk)day 28: 65% still up (7,219 at risk)day 29: 65% still up (6,962 at risk)day 30: 64% still up (6,607 at risk)day 31: 63% still up (6,498 at risk)day 32: 62% still up (6,395 at risk)day 33: 61% still up (6,284 at risk)day 34: 60% still up (6,056 at risk)day 35: 59% still up (5,824 at risk)day 36: 58% still up (5,655 at risk)day 37: 57% still up (5,420 at risk)day 38: 56% still up (5,221 at risk)day 39: 55% still up (5,137 at risk)day 40: 54% still up (5,044 at risk)day 41: 53% still up (4,847 at risk)day 42: 52% still up (4,628 at risk)day 43: 51% still up (4,414 at risk)day 44: 50% still up (4,206 at risk)day 45: 49% still up (4,043 at risk)day 46: 48% still up (3,947 at risk)day 47: 47% still up (3,854 at risk)day 48: 46% still up (3,681 at risk)day 49: 45% still up (3,520 at risk)day 50: 44% still up (3,344 at risk)day 51: 43% still up (3,174 at risk)day 52: 42% still up (3,012 at risk)day 53: 41% still up (2,946 at risk)day 54: 41% still up (2,862 at risk)day 55: 40% still up (2,723 at risk)day 56: 39% still up (2,556 at risk)day 57: 38% still up (2,417 at risk)day 58: 37% still up (2,305 at risk)day 59: 37% still up (2,238 at risk)day 60: 36% still up (2,205 at risk)day 61: 35% still up (2,141 at risk)day 62: 34% still up (2,030 at risk)day 63: 34% still up (1,892 at risk)day 64: 33% still up (1,785 at risk)day 65: 33% still up (1,681 at risk)day 66: 32% still up (996 at risk)day 67: 32% still up (986 at risk)day 68: 31% still up (958 at risk)day 69: 30% still up (940 at risk)day 70: 29% still up (904 at risk)day 71: 29% still up (889 at risk)day 72: 28% still up (874 at risk)day 73: 28% still up (854 at risk)day 74: 27% still up (837 at risk)day 75: 26% still up (818 at risk)day 76: 26% still up (802 at risk)day 77: 26% still up (792 at risk)day 78: 26% still up (784 at risk)day 79: 25% still up (778 at risk)day 80: 25% still up (772 at risk)day 81: 25% still up (761 at risk)day 82: 24% still up (736 at risk)day 83: 24% still up (516 at risk)day 84: 23% still up (508 at risk)day 85: 22% still up (496 at risk)day 86: 22% still up (470 at risk)day 87: 21% still up (431 at risk)day 88: 21% still up (417 at risk)day 89: 20% still up (392 at risk)day 90: 20% still up (294 at risk)day 91: 19% still up (288 at risk)day 92: 19% still up (229 at risk)day 93: 19% still up (193 at risk)day 94: 18% still up (161 at risk)day 95: 18% still up (156 at risk)day 96: 18% still up (145 at risk)day 97: 18% still up (107 at risk)day 98: 17% still up (69 at risk)day 99: 17% still up (32 at risk)day 100: 17% still up (10 at risk)day 101: 15% still up (9 at risk)day 102: 14% still up (8 at risk)day 104: 14% still up (7 at risk)
Table view
Days upStill upAt riskClosed that day
097.9%16,629345
196.4%16,202251
294.2%15,695365
392.9%15,105209
491.9%14,884150
590.8%14,711174
689.4%14,266233
788.1%13,714185
887.1%13,260163
985.9%12,842177
1084.9%12,436137
1183.7%12,295173
1282.5%12,094182
1381.1%11,656196
1479.7%11,181193
1578.8%10,708115
1677.8%10,364137
1776.6%10,002145
1875.7%9,826125
1974.6%9,670138
2073.6%9,265127
2172.4%8,843138
2271.5%8,486103
2370.6%8,174113
2469.5%7,994126
2568.6%7,86192
2667.7%7,759105
2766.4%7,511143
2865.4%7,219112
2964.7%6,96276
3063.6%6,607109
3162.7%6,49893
3261.8%6,39589
3360.9%6,28498
3459.8%6,056105
3559.2%5,82456
3658.1%5,655113
3757.0%5,420100
3856.1%5,22183
3955.2%5,13778
4054.2%5,04489
4153.2%4,84793
4252.2%4,62887
4350.9%4,414107
4450.0%4,20680
4548.8%4,04394
4647.8%3,94779
4747.0%3,85470
4845.9%3,68180
4945.1%3,52061
5044.3%3,34460
5143.4%3,17468
5242.5%3,01264
5341.4%2,94671
5440.8%2,86246
5539.6%2,72379
5638.8%2,55650
5738.1%2,41744
5837.4%2,30544
5936.9%2,23827
6036.0%2,20554
6135.3%2,14141
6234.3%2,03057
6333.9%1,89226
6433.2%1,78535
6532.8%1,68121
6632.5%99610
6731.5%98628
6830.9%95818
6929.8%94036
7029.3%90415
7128.8%88915
7228.1%87420
7327.6%85417
7426.9%83719
7526.4%81816
7626.1%80210
7725.8%7928
7825.6%7846
7925.4%7786
8025.1%7729
8124.6%76116
8224.1%73614
8323.8%5168
8423.2%50812
8522.0%49626
8621.6%4707
8721.2%4319
8820.6%41712
8920.2%3927
9019.8%2946
9119.4%2886
9219.1%2293
9318.7%1934
9418.2%1615
9517.8%1563
9617.7%1451
9717.7%1070
9817.4%691
9917.4%320
10017.4%100
10115.5%91
10213.6%81
10413.6%70

Data roles by family

Open postings at the tracked companies, grouped by title.

Analytics: 197 at 60 companies; 60 remote, 12 hybrid, 15 on-site, 110 unstatedAnalytics197Data science: 106 at 38 companies; 23 remote, 5 hybrid, 1 on-site, 77 unstatedData science106Data engineering: 91 at 41 companies; 16 remote, 17 hybrid, 2 on-site, 56 unstatedData engineering91ML engineering: 80 at 29 companies; 4 remote, 3 hybrid, 0 on-site, 73 unstatedML engineering80Analytics engineering: 40 at 25 companies; 12 remote, 0 hybrid, 1 on-site, 27 unstatedAnalytics engineering40Data architecture: 19 at 5 companies; 1 remote, 0 hybrid, 0 on-site, 18 unstatedData architecture19Data governance: 13 at 7 companies; 0 remote, 2 hybrid, 0 on-site, 11 unstatedData governance13Business intelligence: 10 at 10 companies; 0 remote, 3 hybrid, 1 on-site, 6 unstatedBusiness intelligence10
Analytics: 197 at 60 companies; 60 remote, 12 hybrid, 15 on-site, 110 unstatedAnalytics197Data science: 106 at 38 companies; 23 remote, 5 hybrid, 1 on-site, 77 unstatedData science106Data engineering: 91 at 41 companies; 16 remote, 17 hybrid, 2 on-site, 56 unstatedData engineering91ML engineering: 80 at 29 companies; 4 remote, 3 hybrid, 0 on-site, 73 unstatedML engineering80Analytics engineering: 40 at 25 companies; 12 remote, 0 hybrid, 1 on-site, 27 unstatedAnalytics engineering40Data architecture: 19 at 5 companies; 1 remote, 0 hybrid, 0 on-site, 18 unstatedData architecture19Data governance: 13 at 7 companies; 0 remote, 2 hybrid, 0 on-site, 11 unstatedData governance13Business intelligence: 10 at 10 companies; 0 remote, 3 hybrid, 1 on-site, 6 unstatedBusiness intelligence10
Table view
FamilyOpenCompaniesRemoteHybridOn-siteUnstated
Other14,8242112,7581,3358929,839
Analytics19760601215110
Data science10638235177
Data engineering91411617256
ML engineering802943073
Analytics engineering4025120127
Data architecture19510018
Data governance13702011
Business intelligence10100316

What data roles ask for

Share of tracked companies' open data-role postings naming each technology.

SQL: 363 postings at 88 companiesSQL65%Python: 352 postings at 86 companiesPython63%Machine learning: 221 postings at 63 companiesMachine learning40%Experimentation: 144 postings at 54 companiesExperimentation26%dbt: 141 postings at 66 companiesdbt25%AWS: 138 postings at 47 companiesAWS25%Spark: 132 postings at 38 companiesSpark24%Data modeling: 129 postings at 55 companiesData modeling23%Snowflake: 124 postings at 58 companiesSnowflake22%LLMs: 118 postings at 50 companiesLLMs21%Databricks: 107 postings at 30 companiesDatabricks19%Airflow: 105 postings at 44 companiesAirflow19%GCP: 93 postings at 38 companiesGCP17%Azure: 89 postings at 29 companiesAzure16%CI/CD: 77 postings at 35 companiesCI/CD14%
SQL: 363 postings at 88 companiesSQL65%Python: 352 postings at 86 companiesPython63%Machine learning: 221 postings at 63 companiesMachine learning40%Experimentation: 144 postings at 54 companiesExperimentation26%dbt: 141 postings at 66 companiesdbt25%AWS: 138 postings at 47 companiesAWS25%Spark: 132 postings at 38 companiesSpark24%Data modeling: 129 postings at 55 companiesData modeling23%Snowflake: 124 postings at 58 companiesSnowflake22%LLMs: 118 postings at 50 companiesLLMs21%Databricks: 107 postings at 30 companiesDatabricks19%Airflow: 105 postings at 44 companiesAirflow19%GCP: 93 postings at 38 companiesGCP17%Azure: 89 postings at 29 companiesAzure16%CI/CD: 77 postings at 35 companiesCI/CD14%
Table view
TechnologyCategorySharePostingsCompanies
SQLLanguage65.3%36388
PythonLanguage63.3%35286
Machine learningAI39.7%22163
ExperimentationPractice25.9%14454
dbtTransformation25.4%14166
AWSCloud24.8%13847
SparkProcessing23.7%13238
Data modelingPractice23.2%12955
SnowflakeWarehouse22.3%12458
LLMsAI21.2%11850
DatabricksLakehouse19.2%10730
AirflowOrchestration18.9%10544
GCPCloud16.7%9338
AzureCloud16.0%8929
CI/CDPractice13.8%7735
BigQueryWarehouse13.3%7440
TableauBI13.1%7337
LookerBI11.5%6433
GitPractice10.3%5732
Power BIBI9.7%5434
ExcelBI9.0%5017
KafkaStreaming8.8%4922
KubernetesInfrastructure7.4%4122
DockerInfrastructure6.3%3521
TerraformInfrastructure5.0%2818
RedshiftWarehouse4.9%2718
ScalaLanguage4.9%279
JavaLanguage4.3%2412
FivetranIngestion4.0%2217
DagsterOrchestration2.5%1412
FlinkStreaming2.5%1414
PostgresDatabase2.3%1313
Data contractsPractice2.2%128
ClickHouseWarehouse1.4%87
MetabaseBI1.4%87
AirbyteIngestion1.1%65

Where the postings come from

Which applicant-tracking systems the tracked companies post on.

Greenhouse: 8,936 open postings on 70 boardsGreenhouse8,936Ashby: 2,625 open postings on 77 boardsAshby2,625Lever: 1,573 open postings on 20 boardsLever1,573Workable: 289 open postings on 10 boardsWorkable289BambooHR: 164 open postings on 25 boardsBambooHR164Other: 1,793 open postings on 9 boards (platforms with fewer than 5 boards each, combined)Other1,793
Greenhouse: 8,936 open postings on 70 boardsGreenhouse8,936Ashby: 2,625 open postings on 77 boardsAshby2,625Lever: 1,573 open postings on 20 boardsLever1,573Workable: 289 open postings on 10 boardsWorkable289BambooHR: 164 open postings on 25 boardsBambooHR164Other: 1,793 open postings on 9 boards (platforms with fewer than 5 boards each, combined)Other1,793
Table view
ATSOpen postingsBoards
Greenhouse8,93670
Ashby2,62577
Lever1,57320
Workable28910
BambooHR16425
Other1,7939

A curated list of company boards, not a sample of the job market; counted before any filter. A figure covering fewer than 5 companies is withheld. Snapshot taken 2026-11-04 00:17 UTC.

02From API to inbox

The dbt DAG, generated from manifest.json when this page was built. Click any node to open it in dbt docs. The AI models in silver are typed stubs on this DuckDB build, because the functions they call exist only in BigQuery.

03Decisions that shaped it

Medallion, dbt-native

Three zones map one-to-one onto staging → intermediate → marts, each in its own BigQuery dataset. Raw is append-only and every transform rebuilds from it, so a rule change applies retroactively with zero migrations.

ADR-0010ADR-0014

One SQL codebase, two warehouses

Every model runs on DuckDB for development and CI — with no secrets — and on BigQuery in production. Dialect differences live in adapter.dispatch macros, including the prod-only type traps that naive cross-database macros hide.

ADR-0002

Lifecycle, not snapshots

The source APIs have no date filters, so novelty is derived, never requested: first_seen_at, last_seen_at and is_active come from the append-only landing, and a staleness rule ages out a dropped board instead of leaving zombie postings.

ADR-0016ADR-0008

Rules are data

Locations, technologies and titles are dbt seeds, word-boundary matched and regex-safe (C++ and .NET work). Only location removes a row; everything else ranks, so recall stays high until a model can judge fit.

ADR-0015ADR-0023ADR-0028

Security is structural

No secret value exists anywhere in the repo. BigQuery auth is Workload Identity Federation, so there is no key file to leak; workflows are split by permission scope, actions are SHA-pinned, and gitleaks backstops every commit.

ADR-0007ADR-0011

AI that orders, never filters

LLM extraction and scoring run as incremental dbt models against BigQuery's in-SQL AI functions, keyed on a content hash so each text is billed once. The score sorts delivery and can never drop a posting: if it fails, the V1 result still ships.

ADR-0004ADR-0020ADR-0024

04Built to fail loudly

A scheduled pipeline's worst failures produce no signal at all. An invalid workflow file never starts, so nothing emails. A suspended schedule is silent. A run that lands almost nothing still exits zero. Each of these has its own gate here: workflow linting, a dead-man's switch, volume warnings and a source-freshness check.

The failures that look like health →

05Even the prose is tested

Docs drift silently: a file is renamed and the sentence pointing at it still reads fine. A checker in CI verifies every path, make target, model name, heading anchor and ADR number the docs mention, and lets a sentence assert a count against the code — so a number cannot rot under an edit.

All quality gates ↗

06Working on LLM scoring vs. embeddings

Two ways to rank a posting against a resume corpus, built to answer the same question by different means. Choosing between them without measuring is how a project ends up carrying both forever, so neither replaces the keyword score until labels say it should.

LLM fit score running

Reads the posting's requirements against the corpus and returns a score from 1 to 5. It reads polarity, so "we sponsor visas" and "we do not" score differently. The dearer half: one generation per posting, billed once per text by the content-hash guard.

Embedding similarity built, off

Finds the single resume bullet closest to the requirements and names it, so a ranking explains itself. The cheaper half, but blind to polarity: those two visa sentences are nearly the same vector, so location limits and people management stay with the LLM.

  1. Human labels. Labels from an LLM cannot settle it: grading a scorer against its predecessor rewards repeating the predecessor's mistakes.
  2. Precision@k over those labels for all three rankings, the keyword baseline included.
  3. Embeddings on, both rankings live side by side for a month, then the loser goes — with its column and its cost.
How V2 works →

07Decision log 29 records, newest first

0029The site's market charts publish suppressed aggregates, handed between workflowsaccepted2026-10-13 0028The filter-rule seeds are private configaccepted2026-08-17 0027Score against a resume corpus, not a skills listaccepted2026-08-16 0026The warehouse lives in us-central1, so the AI functions can reach a modelaccepted2026-08-16 0025Gemini 3.1 Flash-Lite, called on the global endpointaccepted2026-08-16 0024One visible match_score orders the digestaccepted2026-07-28 0023Deal-breaker tech demotes a posting; it no longer deletes itaccepted2026-07-28 0022Boards are fetched in parallel; politeness is per host, not globalaccepted2026-07-28 0021A V1 source must yield a description, even if that costs a second callaccepted2026-07-28 0020V2 scope: AI relevance only; score orders, never filters; embeddings deferredaccepted2026-07-18 0019email digest delivery; GitHub-native failure alerting (Slack retired)accepted2026-07-18 0018The company-discovery notebook lives in-repo, quarantinedaccepted2026-07-18 0017Evaluate openjobdata as an aggregated ingestion source (hybrid)proposed2026-07-18 0016silver is the retention layer; gold is live-onlyaccepted2026-07-18 0015Desired tech + title matches are soft signals, not filtersaccepted2026-07-18 0014Each medallion zone lands in its own BigQuery datasetaccepted2026-07-18 0013V1 ingestion broadens beyond Greenhouse + Leveraccepted2026-07-18 0012Company boards are identified by board_ref, not a single slugaccepted2026-07-13 0011The company list is private config, not a committed seedaccepted2026-06-17 0010Three medallion zones, not five layers; per-model materializationaccepted2026-06-17 0009Use Gemini 2.5 Flash-Lite for V2 extraction/scoringsuperseded→ 00252026-06-17 0008Separate identity key from change-detection hashaccepted2026-06-17 0007Secrets boundary independent of agent goodwillaccepted2026-06-17 0006Deliver links to full postings, not summariesaccepted2026-06-17 0005Greenhouse + Lever only in V1superseded→ 00132026-06-17 0004V2 LLM runs inside dbt as SQL (Pattern C)accepted2026-06-17 0003AI deferred to V2; V1 is ingestion + dbt onlyaccepted2026-06-17 0002Dual-target dbt: DuckDB dev, BigQuery prodaccepted2026-06-17 0001Medallion layers in one dbt projectaccepted2026-06-17