Most recruiting teams don't realize they have a data platform problem until an audit request lands or a VP asks "why do these two reports disagree?" By then the ATS, the sourcing tools, the assessment vendors, the scheduling platform, and three spreadsheets have all been quietly diverging for a year. The reports disagree because every system has its own version of the truth, and nobody decided which one wins.
This is less about picking a fancy warehouse and more about deciding where hiring data lives, who can change it, and how you prove what happened after the fact. Those three questions drive almost every architectural tradeoff you'll face. Get them wrong early and you don't notice for a while. You notice at 400 hires a year when legal asks for the complete decision trail on a rejected candidate who filed a complaint, and you can't reconstruct it because your ATS overwrote the old scorecard fields.
Here's how a source-to-hire data platform is actually built, where the common forks are, and how to design audit trails that survive both scale and scrutiny.
The core architectural fork: warehouse-first vs reverse ETL
Almost every TA data stack eventually lands on one of two shapes, and the choice quietly dictates everything downstream.
Warehouse-first means you pull all your recruiting data — ATS, CRM, assessments, HRIS — into a central warehouse (Snowflake, BigQuery, whatever), model it there, and that warehouse becomes the source of truth for reporting and analysis. The operational tools stay operational. The warehouse is where you reconcile.
Reverse ETL flips part of that. You still have a warehouse, but you push modeled, cleaned data back out into the operational tools so recruiters see unified data inside the ATS or CRM they actually work in. Instead of making people log into a BI tool, you sync the "golden" candidate record back into the systems of record.
| Dimension | Warehouse-first | Reverse ETL (write-back) |
|---|---|---|
| Time to first value | Fast (weeks) | Slower (months) |
| Source of truth clarity | Clean — warehouse wins | Murkier — operational + warehouse blend |
| Risk when sync breaks | Reports go stale | Operational tools show bad data |
| Best for team size | Early to mid (under ~300 hires/yr) | Scaling teams with heavy recruiter-in-tool workflows |
| Audit complexity | Lower | Higher — must log both pull and push |
| Recruiter adoption | Lower (people avoid BI) | Higher (data lives where they work) |
A pattern worth naming: teams tend to overbuild reverse ETL too early. If your recruiters aren't already drowning in tool-switching, warehouse-first gets you 80% of the value at a fraction of the maintenance. Reverse ETL earns its keep when recruiters genuinely need enriched, cross-system context in the moment — a sourcer needing to see prior candidacy, consent status, and assessment history without opening four tabs.
When warehouse-first makes sense
-
You're under roughly 300 hires a year and reporting is your primary pain
-
Your recruiters already live mostly in one system
-
You don't yet have a data engineer who can babysit write-back pipelines
-
You need defensible reporting now and can tolerate a lag between warehouse and tools
When reverse ETL is worth the complexity
-
Recruiters routinely stitch data across three or more tools manually
-
You've got duplicate-candidate chaos that only a golden record can fix
-
You have at least part-time data engineering capacity
-
Enriched context in-tool measurably changes recruiter behavior (faster triage, fewer re-screens)
Who should not do this yet
If you're a five-person team running one ATS and a couple of job boards, you don't need either architecture formally. You need clean schemas and disciplined field usage. Building a warehouse before you've agreed on what a "qualified candidate" field means is just relocating your mess to a more expensive address. The schema and ownership conversation comes first — we go deep on that in Recruiting data ownership, schemas, and cross-system attribution, and it's genuinely the prerequisite for any platform decision here.
Why hiring data decays differently than other business data
Recruiting data has a weird property that most data platform advice ignores: the operational record and the legal record have different lifespans and different update rules.
Never lose track of top talent again.
Recioly helps you manage every stage of recruiting efficiently, from application to offer.
- Centralized candidate tracking
- Automated interview scheduling
- Collaborative hiring workflows
No credit card required
In sales, if a deal stage changes, you want the latest state. Overwriting is fine. In hiring, the sequence of states matters as much as the final state. You don't just need to know a candidate was rejected — you need to know who rejected them, at what stage, against which scorecard version, on what date, and whether that aligned with the role's defined bar at that time. That's not a current-state question. That's an event-history question.
This is where most ATS-centric stacks quietly fail. Standard ATSes are built around current state. The candidate "is" in stage X. When they move to stage Y, stage X is gone or buried. Custom fields get overwritten. Scorecard templates get edited, and old submissions silently re-render against the new template. Six months later, your audit trail is fiction.
Teams assume their ATS is their audit trail. It isn't. It's a current-state operational tool with some history bolted on. The history it keeps is whatever the vendor decided was worth keeping, which rarely matches what your legal or DEI team will need.
Append-only event stores: the recipe that actually holds up
The fix for the decay problem is to stop treating your warehouse as a mirror of current state and start treating part of it as an append-only event log. The principle: you never update or delete, you only append. State changes become new rows, not overwrites.
-
event_id(unique, immutable) -
candidate_id(stable across systems — this is the hard part) -
requisition_id -
eventtype(applied, screened, scorecardsubmitted, stagechanged, offerextended, etc.) -
event_payload(the actual data — scores, stage names, reasons) -
actor_id(who did it — human or system) -
source_system(where it originated) -
occurred_at(when it happened in reality) -
recorded_at(when your platform captured it)`
That split between occurredat and recordedat matters more than people expect. When a sync runs six hours late, or a recruiter backfills a scorecard the next morning, you need both timestamps to reconstruct what was actually known when. A compliance reviewer asking "what did the hiring manager see at the time of decision?" can't be answered without it.
Use CDC from your ATS when available to capture state changes as events rather than relying on periodic snapshots.
-
Agree on a stable candidate identity. Before anything, solve candidate ID across systems. Without a durable
candidate_id, your event log fragments and nothing joins. This is usually the longest step and the most skipped. -
Capture events, not snapshots. Configure your pipelines to emit a row per state change rather than overwriting a current-state table. Change data capture (CDC) from your ATS is ideal if available.
-
Make the event table append-only at the permission level. Revoke UPDATE and DELETE on that table for everyone, including admins. If someone can edit history, your audit trail is only as trustworthy as your least careful admin.
-
Version your templates and store the version with the event. When a scorecard is submitted, record the scorecard template version in the payload. Never let edits re-render old submissions.
-
Build current-state views on top of the event log, not beside it. Your dashboards read a derived "latest state" view. The log stays pure; the view does the convenience work.
The reason append-only wins is subtle: it turns "prove what happened" from a forensic exercise into a simple query. You're not reconstructing history from scattered timestamps. You have the history, in order, by design.
This illustrates the flow from systems into an append-only event log and the derived views used for reporting and operational syncs.
Lineage controls: knowing where every number came from
Once you've got data flowing from five systems into a platform, the question that breaks reporting trust is "where did this number come from?" If a recruiter challenges a time-to-fill metric and you can't trace it back to the source events, you lose the argument and, eventually, the team's trust in the whole platform.
Lineage is the discipline of tracking data from source → transformation → final metric, so any number is traceable backward. The teams that get this right do a few unglamorous things:
-
Tag every record with its source system and ingestion timestamp. Non-negotiable. When two systems disagree, you need to know which fed the number.
-
Document transformations as code, not tribal knowledge. The logic that turns raw events into "quality-of-hire" or "time-to-fill" lives in version-controlled models, not in one analyst's head or a buried spreadsheet formula.
-
Keep transformation versions. When you change how time-to-fill is calculated, old reports should still reflect the old logic, or at minimum flag the change. Silent metric redefinitions are how two VPs end up citing different numbers from the "same" dashboard.
The mistake is treating lineage as a nice-to-have you'll add later. Lineage is almost impossible to retrofit. You can't reconstruct where last year's numbers came from if you weren't tagging as you went. Build it in from the first pipeline or accept that your first year of data is directionally useful at best.
This connects directly to how you measure hiring outcomes over time. If you're tracking whether your hires actually work out — which you should be — that measurement depends entirely on clean lineage between the hire event and the performance data months later. We cover the measurement side in Tie hiring to 6–12 month performance with a quality-of-hire system, and the platform work here is what makes those long-horizon joins possible.
Retention and archival: the part legal actually cares about
Retention is where TA data platforms quietly become legal liabilities. Different data has different required lifespans, and most teams use a single blunt rule — "keep everything forever" — which is both expensive and legally risky. Holding candidate data longer than your stated retention policy is its own violation in several jurisdictions.
| Data type | Typical retention approach | Storage tier |
|---|---|---|
| Active candidate records | Kept live during process + consent window | Hot / operational |
| Decision & audit events | Long retention (often 1–3+ yrs per jurisdiction) | Warm, append-only, indexed |
| Rejected candidate PII | Minimize — anonymize after retention window | Cold → anonymized |
| Aggregate hiring metrics | Keep indefinitely (no PII) | Warm/cold, cheap |
| Raw sync logs / pipeline debug | Short (30–90 days) | Cheap, auto-expire |
The key move is decoupling the audit record from the PII. You can anonymize or delete personal data after your retention window while keeping the structural event trail — stages, timestamps, decision reasons, template versions — intact for defensibility. That way you honor deletion obligations without destroying your ability to prove process fairness in aggregate.
A realistic archival workflow: active data stays in hot storage during the hiring process and consent window. Once a requisition closes and the window lapses, records move to warm storage where they're cheaper but still queryable for audits. PII fields get anonymized on a scheduled job. Pure-metric and event-structure data ages into cold storage, where you pay almost nothing to keep it for the long tail of audits and trend analysis.
The platform principle: retention is a per-data-type decision, enforced automatically, not a company-wide "keep it all" default.
Indexing recommendations that keep audits from timing out
One quiet failure mode: your audit trail exists but queries against it take four minutes because nobody indexed for the access patterns auditors actually use. Event logs grow fast — millions of rows within a couple years at volume — and an un-indexed event table turns every audit request into a slow, frustrating slog.
-
By candidate — "show me everything for this person" → index on
candidate_id -
By requisition — "show me the full decision trail for this role" → index on
requisition_id -
By time range — "all decisions in Q2" → index on
occurred_at -
By actor — "every action this interviewer took" → index on
actor_id -
By event type — "all scorecard submissions" → index on
event_type
A composite index on (candidateid, occurredat) covers the single most common audit query — one candidate's full timeline in order — and is worth setting up on day one. The pattern to avoid is indexing for your dashboards while ignoring your audit queries. Dashboards and audits read data very differently; optimize for both or your compliance queries will be the ones that crawl.
A maturity decision matrix
Where you should invest depends heavily on where you are. Pouring effort into event sourcing when you're doing 40 hires a year is a waste; ignoring it at 600 is negligence.
| Stage | Volume (rough) | Primary platform move | Audit approach |
|---|---|---|---|
| Starting out | < ~100 hires/yr | Clean schemas, disciplined fields, one source of truth | ATS-native history + exported snapshots |
| Growing | ~100–300 | Warehouse-first, basic lineage tagging | Warehouse event table, append-only, manual retention |
| Scaling | ~300–600 | Add reverse ETL where it changes behavior; version templates | Full append-only event store, automated retention jobs |
| Mature | 600+ | Golden records, enforced lineage, tiered storage | Immutable event log, indexed for audit, anonymization pipelines |
Most teams are one stage behind where their volume says they should be. The platform work lags the hiring growth because it isn't anyone's emergency until it suddenly is. The teams that stay ahead treat each volume threshold as a trigger to revisit the stack before the pain, not after the audit request arrives.
A real scenario
A growing fintech doing somewhere around 250–300 hires a year ran everything through their ATS plus a sourcing CRM, an assessment vendor, and a scheduling tool. Reporting came out of spreadsheet exports stitched together monthly by one overworked ops person.
Two problems collided. First, a rejected candidate raised a fairness complaint, and legal asked for the complete decision trail: scorecards, reasons, timestamps, who decided. The ops team spent close to three weeks reconstructing it from exports, and parts were simply unrecoverable because the scorecard template had been edited mid-year and old submissions re-rendered against the new version. Second, every leadership meeting devolved into arguing about whose time-to-fill number was right.
They went warehouse-first. Nothing fancy — a central warehouse, CDC from the ATS into an append-only event table, source tagging on every record, template versions stored with each scorecard submission, and permissions locked so nobody could edit history. Current-state dashboards read from derived views on top of the log. Retention got tiered so rejected-candidate PII anonymized automatically after their window while the event structure stayed intact.
The reporting arguments mostly stopped within a quarter, because everyone was reading from the same lineage-traceable numbers. The bigger win came the next time legal asked for a decision trail — it took about half a day instead of three weeks of archaeology. The upfront build ran a few months of part-time data engineering work, but the first avoided compliance scramble roughly paid for it.
Where modern tooling fits
The reason this is more achievable now than a few years ago is that the glue work — syncing systems, capturing events, versioning templates, tagging lineage — no longer requires a full data engineering team babysitting brittle scripts. AI-assisted operational platforms can handle a lot of the tedious middle: flagging when two systems disagree on a candidate record, catching sync failures before they corrupt operational data, auto-tagging source and timestamps, and surfacing anomalies that used to only get caught during an audit. That's the useful role for automation here — not replacing judgment about retention or fairness, but removing the manual drudgery that causes event logs to drift and audit trails to rot.
The judgment calls stay human: what to retain, how long, which number is the real number, whether a decision trail holds up. Automation just makes sure the raw material for those decisions is captured cleanly and consistently, instead of depending on whether a busy ops person remembered to export the right snapshot that month.
Closing thought
A source-to-hire data platform isn't really a technology purchase — it's a set of decisions about truth, history, and defensibility that you either make deliberately or make by accident. The teams that struggle aren't the ones with the wrong warehouse. They're the ones who never decided which system wins, never made their history immutable, and never tagged where their numbers came from.
Volume just exposes those gaps faster. Start with identity and schemas, make your decision records append-only, tag your lineage from the first pipeline, and let your retention tiers do the compliance work automatically. Do that, and the next audit request is a half-day query instead of a three-week scramble.
A source-to-hire data platform isn't really a technology purchase — it's a set of decisions about truth, history, and defensibility that you either make deliberately or make by accident. The teams that struggle aren't the ones with the wrong warehouse. They're the ones who never decided which system wins, never made their history immutable, and never tagged where their numbers came from.
Volume just exposes those gaps faster. Start with identity and schemas, make your decision records append-only, tag your lineage from the first pipeline, and let your retention tiers do the compliance work automatically. Do that, and the next audit request is a half-day query instead of a three-week scramble.
Ready to elevate your hiring process?
Join 1,500+ recruiting teams using Recioly to save time, improve collaboration, and hire smarter.