Introduction
In March 2023 I subscribed to LaraJobs instant email notifications. I never unsubscribed.
Three years and 699 emails later, I have a longitudinal dataset of every Laravel job posted on the board — timestamped, structured, and normalized. Not a scrape. Not a snapshot. The actual notification stream, preserved as .eml files.
This post documents how I built the pipeline, what the data says about the Laravel job market from 2023 to mid-2026, and what surprised me.
The full pipeline is open:
- Python AI processor — GPT-5 mini extraction pipeline
- Structured JSON output — 699 records in a structured JSON output
- Report generator — data quality and distribution report
- Raw data insights — the markdown report this article draws from
The Dataset
LaraJobs sends one email per job posting, immediately on publication. The email contains the company name, job title, location, engagement type, and salary — when disclosed.
The first email arrived on March 20, 2023 from noreply@larajobs.com. Since June 2024 the sender switched to larajobs@userscape.com, indicating a platform migration. Both streams are included.
| Total records | 699 |
| Date range | 2023-03-20 → 2026-05-22 |
| Years covered | 2023, 2024, 2025, 2026 (partial) |
| Salary disclosed | 373 (53.4%) |
This is not scraped data. Every record originates from a push notification I personally received. The archive is reproducible — anyone subscribed to the same feed would have received the same emails.
The Pipeline
Saving Raw Emails
The Laravel application authenticates via IMAP using an app password and saves each matching email as a raw .eml file — full RFC 2822 message, headers and body intact:
email_fetcher.php
$header = imap_fetchheader($inbox, $uid, FT_UID);
$body = imap_body($inbox, $uid, FT_UID);
// Combine and store
$disk = Storage::disk('local');
$disk->put("emails/larajobs-com/{$uid}.eml", $header . $body);
Nothing is parsed at write time. The .eml format is the canonical artifact. If LaraJobs changes their email template — as they did when switching senders — the raw file still contains everything needed.
Cleaning Before the LLM
Before calling any model, the plain-text body is stripped down to its essential signal. A typical LaraJobs email, after decoding quoted-printable encoding and stripping HTML, looks like this:
New Larajob Posted!
Prep Network
Laravel Engineer
Location: Remote / USA
Full Time
View Job Details →: https://...
You're receiving this because you subscribed...
After cleaning — removing the header line, footer, tracking URLs, and collapsing whitespace — the input to the model is:
Prep Network
Laravel Engineer
Location: Remote / USA
Full Time
Four lines. That is the entire LLM input for most records. This matters for cost and latency.
Extraction with GPT-5 Mini
Each cleaned body is sent to gpt-5-mini with a structured extraction prompt requesting a JSON object with 14 fields: company, job title, engagement type, location, remote flag, canonical region, salary (raw text, period, min, max, currency), skills array, role title, seniority level, and terminology.
The model handles:
- Salary period detection —
$30-45/hr→P1H,€3,500/month→P1M, plain numbers →P1Y - Salary normalization — raw values stored as-is; annualized equivalents computed post-extraction using standard multipliers (
P1H × 2080,P1M × 12) - Skill canonicalization —
vue.js,vuejs,vue→vue;ts,typescript→typescript - Role classification — separating the shape of the role (
fullstack,backend,frontend) from the word used (developer,engineer)
Each result is cached as {uid}.json alongside the .eml file. Re-runs only call the model for new emails.
Cost
699 emails at approximately 150 tokens each: roughly 1.15 million tokens total, including all iterative prompt refinement during development. Total API cost: $0 — covered by OpenAI research program credits. At gpt-5-mini list pricing, the equivalent cost would be approximately $2.30.
Volume Over Time
| Month | Count | Visual Representation |
|---|---|---|
| 2023-03 | 5 | ███░░░░░░░░░░░░░░░░░░░░░░░░░░░ |
| 2023-04 | 15 | ██████████░░░░░░░░░░░░░░░░░░░░ |
| 2023-05 | 18 | █████████████░░░░░░░░░░░░░░░░░ |
| 2023-06 | 23 | ████████████████░░░░░░░░░░░░░░ |
| 2023-07 | 43 | ██████████████████████████████ |
| 2023-08 | 19 | █████████████░░░░░░░░░░░░░░░░░ |
| 2023-09 | 18 | █████████████░░░░░░░░░░░░░░░░░ |
| 2023-10 | 23 | ████████████████░░░░░░░░░░░░░░ |
| 2023-11 | 12 | ████████░░░░░░░░░░░░░░░░░░░░░░ |
| 2023-12 | 11 | ████████░░░░░░░░░░░░░░░░░░░░░░ |
| 2024-01 | 6 | ████░░░░░░░░░░░░░░░░░░░░░░░░░░ |
| 2024-02 | 15 | ██████████░░░░░░░░░░░░░░░░░░░░ |
| 2024-03 | 8 | ██████░░░░░░░░░░░░░░░░░░░░░░░░ |
| 2024-04 | 15 | ██████████░░░░░░░░░░░░░░░░░░░░ |
| 2024-05 | 18 | █████████████░░░░░░░░░░░░░░░░░ |
| 2024-06 | 16 | ███████████░░░░░░░░░░░░░░░░░░░ |
| 2024-07 | 22 | ███████████████░░░░░░░░░░░░░░░ |
| 2024-08 | 16 | ███████████░░░░░░░░░░░░░░░░░░░ |
| 2024-09 | 21 | ███████████████░░░░░░░░░░░░░░░ |
| 2024-10 | 15 | ██████████░░░░░░░░░░░░░░░░░░░░ |
| 2024-11 | 22 | ███████████████░░░░░░░░░░░░░░░ |
| 2024-12 | 10 | ███████░░░░░░░░░░░░░░░░░░░░░░░ |
| 2025-01 | 29 | ████████████████████░░░░░░░░░░ |
| 2025-02 | 23 | ████████████████░░░░░░░░░░░░░░ |
| 2025-03 | 19 | █████████████░░░░░░░░░░░░░░░░░ |
| 2025-04 | 15 | ██████████░░░░░░░░░░░░░░░░░░░░ |
| 2025-05 | 18 | █████████████░░░░░░░░░░░░░░░░░ |
| 2025-06 | 20 | ██████████████░░░░░░░░░░░░░░░░ |
| 2025-07 | 22 | ███████████████░░░░░░░░░░░░░░░ |
| 2025-08 | 13 | █████████░░░░░░░░░░░░░░░░░░░░░ |
| 2025-09 | 24 | █████████████████░░░░░░░░░░░░░ |
| 2025-10 | 29 | ████████████████████░░░░░░░░░░ |
| 2025-11 | 24 | █████████████████░░░░░░░░░░░░░ |
| 2025-12 | 20 | ██████████████░░░░░░░░░░░░░░░░ |
| 2026-01 | 25 | █████████████████░░░░░░░░░░░░░ |
| 2026-02 | 14 | ██████████░░░░░░░░░░░░░░░░░░░░ |
| 2026-03 | 18 | █████████████░░░░░░░░░░░░░░░░░ |
| 2026-04 | 8 | ██████░░░░░░░░░░░░░░░░░░░░░░░░ |
| 2026-05 | 7 | █████░░░░░░░░░░░░░░░░░░░░░░░░░ |
The July 2023 peak (43) is not organic growth. Accurate Biometrics posted the same "FULL STACK DEVELOPER" listing seven times in 24 hours; By the Pixel posted the same hourly Laravel/Vue role seven times across three days. Remove those ~14 duplicates and Q3 2023 drops from 80 to ~66 — below Q4 2025 (73).
By quarter, removing the noise:
| Quarter | Count | Visual Representation |
|---|---|---|
| 2023 Q1 | 5 | ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░ |
| 2023 Q2 | 56 | █████████████████████░░░░░░░░░ |
| 2023 Q3 | 80 | ██████████████████████████████ |
| 2023 Q4 | 46 | █████████████████░░░░░░░░░░░░░ |
| 2024 Q1 | 29 | ███████████░░░░░░░░░░░░░░░░░░░ |
| 2024 Q2 | 49 | ██████████████████░░░░░░░░░░░░ |
| 2024 Q3 | 59 | ██████████████████████░░░░░░░░ |
| 2024 Q4 | 47 | ██████████████████░░░░░░░░░░░░ |
| 2025 Q1 | 71 | ███████████████████████████░░░ |
| 2025 Q2 | 53 | ████████████████████░░░░░░░░░░ |
| 2025 Q3 | 59 | ██████████████████████░░░░░░░░ |
| 2025 Q4 | 73 | ███████████████████████████░░░ |
| 2026 Q1 | 57 | █████████████████████░░░░░░░░░ |
| 2026 Q2 | 15 | ██████░░░░░░░░░░░░░░░░░░░░░░░░ |
2023 Q3 Inflated by duplicate postings. 2026 Q2 Partial quarter.
The market did not contract. 2025 was the strongest year in the dataset, averaging 64 postings per quarter against 2023 and 2024's ~46. Q4 2025 (73) is the clean peak.
The Market Did Not Shrink
The narrative I expected to find was a shrinking board — fewer postings as companies migrate away or stop hiring entirely. That's not in the data. 2025 was the strongest year in the dataset
Quarterly averages by year:
| Year | Avg per quarter |
|---|---|
| 2023 | ~47 |
| 2024 | ~46 |
| 2025 | 64 |
| 2026 | ~57 (Q1 only) |
2025 growth of ~38% over 2023/2024 baseline is not noise. The board is more active, not less.
The AI Signal
Job titles mentioning AI, agentic workflows, or augmentation by year:
| Year | AI-adjacent titles | Share |
|---|---|---|
| 2023 | 2 | 1.1% |
| 2024 | 4 | 2.2% |
| 2025 | 4 | 1.6% |
| 2026 | 8 | 11.1% |
The 2026 jump is significant — in the first five months of 2026, more than 1 in 10 postings explicitly mentioned AI in the job title. Examples from the dataset:
- Senior AI-Native Full-Stack Engineer (
Laravel/Vue/Inertia) — Orpical Technology Solutions - Senior AI-Augmented Engineer (
Laravel 12+Agentic Workflows) — Lumion - Senior Laravel Backend Developer (
AI-Friendly) — Kettner Edelmetalle - AI Platform - Laravel Fullstack Developer -
Inertia/Vue/Tailwind— Plotdesk GmbH
Laravel is not being replaced by AI tooling. It is being combined with it.
Skills Distribution
Based on 424 records with at least one skill extracted (60.7% of total):
| Skill | Occurrences | % of jobs | Visual Representation |
|---|---|---|---|
| laravel | 349 | 49.9% | ██████████░░░░░░░░░░ |
| php | 109 | 15.6% | ███░░░░░░░░░░░░░░░░░ |
| vue | 78 | 11.2% | ██░░░░░░░░░░░░░░░░░░ |
| react | 19 | 2.7% | █░░░░░░░░░░░░░░░░░░░ |
| ai | 18 | 2.6% | █░░░░░░░░░░░░░░░░░░░ |
| tailwind | 13 | 1.9% | ░░░░░░░░░░░░░░░░░░░░ |
| livewire | 9 | 1.3% | ░░░░░░░░░░░░░░░░░░░░ |
| inertia | 7 | 1.0% | ░░░░░░░░░░░░░░░░░░░░ |
| filament | 7 | 1.0% | ░░░░░░░░░░░░░░░░░░░░ |
Vue remains the dominant frontend pairing. React appears in roughly 1 in 4 jobs where Vue appears — it is a presence, not a replacement. The TALL stack components (Tailwind, Alpine, Livewire, Laravel) collectively appear in 35 postings, most from 2024 onward.
Salary
Half the postings disclosed no salary. Of the 373 that did, 330 were annual, 19 hourly, 7 monthly, 1 daily.
All figures annualized using standard multipliers:
| Currency | Records | Avg Annual Min | Avg Annual Max |
|---|---|---|---|
| USD | 230 | $103,257 | $134,671 |
| EUR | 44 | €52,635 | €83,490 |
| GBP | 34 | £54,029 | £65,906 |
| CAD | 20 | $106,142 | $136,315 |
The USD average sits around $103k minimum, $134k maximum — consistent with mid-to-senior remote roles in a mature framework ecosystem.
These figures likely skew high. Disclosed salaries carry a selection bias — companies that advertise a number are either legally required to or confident it's competitive. Roles with below-market budgets have an incentive to withhold the figure and negotiate down from candidate expectations. The 46.8% non-disclosure rate is itself a signal: the true market floor sits below what this table shows.
Notable outliers:
skai.trade— Senior Frontend Engineer, Real-Time Prediction Markets: $600,000 TCDiagonal— Staff Laravel Engineer: $190k–$250k USDGivebutter— Senior Full-Stack Engineer II, Acquisition: $180k–$200k USDSquare— Group Technical Lead, eCommerce: $239k–$359k USD
On the other end, several European postings (particularly German and Eastern European companies) disclose annual minimums in the €29k–€40k range for senior roles — a substantial gap with the US market even after adjusting for cost of living.
Non-standard salary formats
15 postings included salary text that the model could not parse into numbers. A representative sample:
- Competitive salary + equity participation in JV projects
- D.O.E (Depending of experience)
- Negotiable — open to fixed price or hourly, based on experience
- DOQ (Depending of qualification)
These are not parse failures in the traditional sense. They are genuinely non-numeric salary disclosures — a pattern worth noting as a signal of how different employers approach transparency.
Role Shape and Seniority
Of 699 postings, role classification by title shape:
| Role | Count | % |
|---|---|---|
| Fullstack | 258 | 36.9% |
| Other | 238 | 34.0% |
| Software | 76 | 10.9% |
| Backend | 66 | 9.4% |
| Frontend | 20 | 2.9% |
| Web | 20 | 2.9% |
| Product | 18 | 2.6% |
| DevRel | 3 | 0.4% |
Other (34%) represents technology-specific titles without a clear role shape — "Laravel Developer", "PHP Engineer", "Laravel Maestro", "Humbly Confident Senior Laravel Engineer". These are valid postings; the classification schema simply has no bucket for a title that is purely a framework name.
Seniority, among the 381 postings where level was stated:
| Level | Count | % |
|---|---|---|
| Senior | 281 | 73.8% |
| Lead | 47 | 12.3% |
| Mid | 20 | 5.2% |
| Junior | 18 | 4.7% |
| Principal | 6 | 1.6% |
| Staff | 6 | 1.6% |
| Freelancer | 2 | 0.5% |
| CTO | 1 | 0.3% |
74% of stated-level postings are Senior. LaraJobs skews strongly toward experienced candidates. Junior postings exist but are rare. This is consistent with the board's positioning as a premium, community-adjacent board rather than a volume job aggregator.
Remote and Geography
| Value | Count | % |
|---|---|---|
| Remote | 590 | 88.5% |
| On-site | 77 | 11.5% |
88.5% of postings with a stated remote flag are remote. On-site roles come predominantly from the UK, Germany, Netherlands, and a handful of US cities.
Regional distribution (excluding null):
| Region | Count | % |
|---|---|---|
| USA | 237 | 35.0% |
| Global | 195 | 28.8% |
| Europe | 105 | 15.5% |
| UK | 36 | 5.3% |
| Canada | 27 | 4.0% |
| Germany | 19 | 2.8% |
| Netherlands | 13 | 1.9% |
Global (28.8%) means the posting explicitly accepted applicants from any timezone, typically phrased as "Remote GMT+X" or "Remote / World". The USA dominates but the board is genuinely international — 12+ distinct countries represented across 3 years.
Data Quality Notes
Building this pipeline exposed several classes of data quality issues worth documenting, since they reflect real patterns in how job boards work:
Salary non-disclosure is the norm. 46.8% of records have no salary text at all. Among those that do disclose, 53% use standardized numeric ranges; the rest use vague language ("Competitive", "D.O.E", "Negotiable").
Salary period is not always stated. Postings like "$30-45" with no unit are genuinely ambiguous. The model defaults to annual for values in the typical annual range, but edge cases like "130-155k" (parsed as 130–155 rather than 130k–155k) do occur. Five such failures are confirmed in the dataset.
Duplicate postings inflate volume. LaraJobs does not deduplicate. Accurate Biometrics posted the same listing 7 times in 24 hours in July 2023. By the Pixel posted the same hourly role 7 times across three days. The raw volume numbers include these; the quarterly analysis notes where inflated months appear.
One job title was a typo: "Lavavel Developer" Posted by Love Has No Limits on March 26, 2023. LaraJobs is a pass-through — the employer's form submission goes straight to email blast with no editorial review.
Closing Thoughts
Three years of push notifications, 699 emails, one SQLite-free ETL pipeline and $2.30 of equivalent compute. The dataset is the archive. It will not go stale the way a scraped snapshot does — the .eml files are the ground truth.
The headline finding is not what I expected: Laravel is not contracting. 2025 was the board's strongest year, AI is appearing as a complement rather than a replacement, and the salary floor for a senior remote role remains solidly above $100k in USD markets.
If you are subscribed to LaraJobs — or any job board that sends instant email notifications — you already have a dataset. You just need a pipeline to read it.
Full pipeline and data: