Track Remote Hiring Trends by Tech Stack with RemoteOK (2026)
Thirdwatch's RemoteOK Scraper makes remote tech-stack demand a tracked time series at $0.0015 per record — pull weekly snapshots, count tag frequencies, surface rising and falling stacks. Built for HR researchers, recruiter strategists, and developer-relations teams who want a structured leading indicator of where remote hiring is concentrating.
Why track remote hiring trends by tech stack
Tech-stack demand is the cleanest leading indicator of where the industry is paying for engineers. According to Stack Overflow's 2024 Developer Survey, the gap between most-loved and most-paid languages widens every year as employers chase scarce skills — and the boards that publish employer-set tags surface that demand earlier than salary surveys can. RemoteOK is unusually clean for this purpose: every listing carries 3-8 tags covering tech stack, seniority, function, and location flexibility, all employer-set rather than algorithm-inferred.
The job-to-be-done is structured. A developer-relations team at a language-or-framework company wants to see whether their stack is gaining or losing remote-hiring share. A bootcamp curriculum lead wants to know which stacks are rising fastest to update the syllabus. A recruiter agency benchmarking remote-engineering rates wants pay distributions per tag to set offer bands. All of these reduce to the same data shape — snapshot RemoteOK weekly, group by tag, track frequency and salary over time. The Thirdwatch actor returns each snapshot's data in clean JSON ready for pandas.
How does this compare to the alternatives?
Three options for tracking remote hiring demand by tech stack:
| Approach | Cost per 1,000 jobs × weekly | Reliability | Setup time | Maintenance |
|---|---|---|---|---|
| Manual RemoteOK browsing | Effectively unbounded analyst time | Low (selection bias) | Continuous | Doesn't scale |
| Paid talent-intel SaaS (Lightcast, Burning Glass) | $20K–$200K/year flat | High coverage | Weeks–months to onboard | Vendor lock-in |
| Thirdwatch RemoteOK Scraper | $1.50 × weekly = $78/year | Production-tested, first on Apify Store | 5 minutes | Thirdwatch tracks RemoteOK changes |
Talent-intel SaaS aggregates dozens of boards and does the trend analysis for you. The trade-off is cost and lack of customisation — your specific cuts (e.g. "junior Rust roles paying 80K+") may not be on the dashboard. The RemoteOK Scraper actor page gives you the structured raw feed; the trend analytics are downstream pandas you control.
How to track remote hiring trends by tech stack in 4 steps
Step 1: How do I authenticate against Apify?
Sign in at apify.com (free tier, no credit card), open Settings → Integrations, and copy your personal API token. Every example below assumes the token is in APIFY_TOKEN:
export APIFY_TOKEN="apify_api_xxxxxxxxxxxxxxxx"
Step 2: How do I take a weekly snapshot of all roles I care about?
Use a broad query like engineer or developer with a high maxResults to capture the full weekly volume.
import os, requests, datetime, json, pathlib
ACTOR = "thirdwatch~remoteok-jobs-scraper"
TOKEN = os.environ["APIFY_TOKEN"]
resp = requests.post(
f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items",
params={"token": TOKEN},
json={"queries": ["engineer", "developer"], "maxResults": 1500},
timeout=600,
)
jobs = resp.json()
week = datetime.date.today().isocalendar()
ts = f"{week.year}-W{week.week:02d}"
pathlib.Path(f"snapshots/remoteok-{ts}.json").write_text(json.dumps(jobs))
print(f"{ts}: {len(jobs)} jobs snapshotted")
A 1,500-job weekly snapshot costs $2.25 at FREE pricing — annual data costs sit at roughly $120 for the entire trend dataset.
Step 3: How do I compute weekly tag-frequency trends?
Aggregate snapshots, normalise tag tokens, count weekly frequencies, compute 8-week rolling growth.
import pandas as pd, glob
TAG_NORM = {"js": "javascript", "golang": "go", "py": "python",
"ts": "typescript", "k8s": "kubernetes",
"ml": "machine-learning", "dataops": "data-engineering"}
def normalise(t):
return TAG_NORM.get(t.lower(), t.lower())
frames = []
for f in sorted(glob.glob("snapshots/remoteok-*.json")):
week = pathlib.Path(f).stem.replace("remoteok-", "")
for j in json.loads(pathlib.Path(f).read_text()):
for tag in (j.get("tags") or []):
frames.append({"week": week, "tag": normalise(tag), "url": j.get("url")})
df = pd.DataFrame(frames).drop_duplicates(subset=["week", "tag", "url"])
weekly = df.groupby(["week", "tag"]).size().reset_index(name="jobs")
pivot = weekly.pivot(index="tag", columns="week", values="jobs").fillna(0)
weeks = sorted(pivot.columns)
if len(weeks) >= 8:
recent, baseline = weeks[-1], weeks[-8]
pivot["growth_8w"] = (pivot[recent] / pivot[baseline].clip(lower=1)) - 1
rising = pivot[(pivot[recent] >= 30) & (pivot.growth_8w >= 0.5)] \
.sort_values("growth_8w", ascending=False)
print(rising[[recent, baseline, "growth_8w"]].head(20))
The rising table is the dashboard's headline — stacks growing 50%+ over 8 weeks with at least 30 listings in the latest week.
Step 4: How do I correlate stack with salary trends?
Aggregate salary by tag and snapshot:
sal_frames = []
for f in sorted(glob.glob("snapshots/remoteok-*.json")):
week = pathlib.Path(f).stem.replace("remoteok-", "")
for j in json.loads(pathlib.Path(f).read_text()):
if j.get("salary_min") is None or j.get("salary_max") is None:
continue
mid = (j["salary_min"] + j["salary_max"]) / 2
for tag in (j.get("tags") or []):
sal_frames.append({"week": week, "tag": normalise(tag),
"url": j["url"], "salary_mid": mid})
sdf = pd.DataFrame(sal_frames).drop_duplicates(subset=["week", "tag", "url"])
sal_pivot = (sdf.groupby(["week", "tag"])["salary_mid"]
.median().reset_index()
.pivot(index="tag", columns="week", values="salary_mid"))
sal_pivot["pay_growth_8w"] = (sal_pivot[weeks[-1]] / sal_pivot[weeks[-8]]) - 1
print(sal_pivot.sort_values("pay_growth_8w", ascending=False).head(20))
A stack with both growth_8w >= 0.5 (job count rising) AND pay_growth_8w >= 0.1 (median pay rising) is a true scarcity signal — both demand and price are climbing, which is what every developer-relations team and bootcamp curriculum lead wants to know about.
Sample output
A single record with the tag and salary fields highlighted looks like this. The trend analysis stitches many such rows across weekly snapshots.
{
"title": "Senior Backend Engineer",
"company": "GitLab",
"salary_min": 120000,
"salary_max": 180000,
"tags": ["python", "go", "kubernetes", "senior"],
"location": "Worldwide",
"description": "We are looking for a Senior Backend Engineer to help scale our core API across multiple regions...",
"posted_date": "2026-04-08",
"url": "https://remoteok.com/remote-jobs/123456-senior-backend-engineer-gitlab"
}
A typical rising-stack output table from 8 weekly snapshots looks like this:
| Tag | Jobs (week 16) | Jobs (week 8) | Growth (8w) | Median pay change |
|---|---|---|---|---|
| rust | 64 | 26 | +146% | +12% |
| bun | 42 | 8 | +425% | +18% |
| solidity | 38 | 21 | +81% | +5% |
| kubernetes | 195 | 168 | +16% | +3% |
Bun appearing from near-zero is the kind of zero-to-something trend RemoteOK surfaces months before it shows up in mainstream salary surveys.
Common pitfalls
Three issues recur in tag-frequency trend pipelines. Tag-taxonomy drift — RemoteOK occasionally renames or merges tags (js → javascript, dataops → data-engineering); without a normalisation map, a single rename causes a fake 100% drop in week N+1 alongside a fake 100% jump for the new label. The map in Step 3 is the canonical fix. Reposted-listing inflation — employers sometimes repost the same job across consecutive weeks; deduping by url within a week is enough since RemoteOK URLs are stable per posting, but cross-week dedupe would erase real demand signal so don't try. Salary-null bias — only ~50% of RemoteOK listings publish salary, so pay-trend analysis runs on a much smaller sample than job-count analysis. Surface the sample size on every salary chart so consumers know the confidence level.
Thirdwatch's actor returns tags always as a list of strings and salary_min/salary_max as integer USD when published. The pure-HTTP architecture means a 1,500-job weekly snapshot completes in under five minutes and costs $2.25 — annual trend data sits at roughly $120, three orders of magnitude cheaper than any paid talent-intel subscription.
Related use cases
- Scrape remote jobs with the RemoteOK API
- Build a remote jobs aggregator with Apify
- Find remote engineering jobs by salary band
- The complete guide to scraping job boards
- All Thirdwatch use-case guides
Frequently asked questions
Why use RemoteOK for tech-stack trend analysis?
RemoteOK exposes employer-set tags on every listing — typically 3-8 tags per job covering tech stack, seniority, function, and location. That tag taxonomy is materially cleaner than keyword extraction from titles or descriptions, which makes RemoteOK the highest-signal single source for tech-stack demand trends across remote roles. Aggregator boards like LinkedIn don't surface tags this consistently.
How often should I snapshot for trend analysis?
Weekly is the right cadence. Daily snapshots produce noisy week-over-week changes; monthly is too coarse to catch a stack rising from obscurity. A weekly cadence with an 8-week rolling window smooths most noise while still surfacing genuine demand shifts within a quarter. Schedule the actor on Apify cron to run every Sunday at midnight UTC.
What's a meaningful threshold for declaring a stack rising?
A 50%+ growth in tag-frequency over an 8-week rolling window with a floor of 30+ jobs in the latest week is a useful default. Below 30 jobs the percentages are noise; above 50% growth is genuinely interesting. Real signals look like Rust climbing from 25 to 60 listings over 8 weeks, or Bun appearing from zero to 40 listings within a quarter.
How do I separate primary stack from secondary tags?
RemoteOK doesn't distinguish primary vs secondary tags — they're a flat array. Build a heuristic: a tag appearing in the title or first 200 characters of the description is likely primary; tags only in deeper description text are secondary. For most trend analysis, treat all tags as equal-weight; tag presence is the demand signal regardless of primary/secondary status.
Can I correlate stack trends with salary?
Yes. Group by tag and aggregate salary_min and salary_max for jobs where both are non-null. Compare median salary by tag across snapshots to surface stacks where pay is rising fastest — a leading indicator of skill scarcity. Salary fields are null on 50% of RemoteOK listings, so plan sample sizes accordingly.
How do I handle tag taxonomy drift over time?
Build a normalisation map. RemoteOK occasionally renames tags (js → javascript, golang → go, dataops → data-engineering); maintain a manual mapping that snaps old tags to current canonical. Run the normalisation before counting frequencies. The map is small (~50 entries) and stable; review it quarterly.
Run the RemoteOK Scraper on Apify Store — pay-per-job, free to try, no credit card to test.