Skip to main content
Mentum
Browse JobsCompaniesSalariesFor EmployersFor UniversitiesLog inSign up
Loading...
Loading...
Mentum

Transparent, skills-based job matching.

Browse JobsCompaniesSalariesFor EmployersFor UniversitiesLog inSign up

© 2026 Mentum. All rights reserved.

Privacy PolicyTerms of ServiceCookie PolicyLegalTrust CentreAI TransparencyHelp CentreProduct updatesContact

Apprenticeship vacancies provided under the Open Government Licence v3.0. Contains public sector information.

On this page
Reading progress0%

    On this page

    Reading progress0%

      ← Back to Legal

      Data Retention Schedule

      Last reviewed 23 September 2026 · Next scheduled review 29 July 2027

      Controller of record: Mentum. Contact: privacy@mentumjobs.com (data protection); dpo@mentumjobs.com (DPO routing); security@mentumjobs.com (security reports); support@mentumjobs.com (operational).

      Anchors: Privacy Policy; Terms of Service; Data Processing Addendum; Sub-processor list; Acceptable Use Policy; Service Level Agreement; Cookie Policy.

      This Data Retention Schedule is Mentum's published statement of how long each category of personal data is kept, what event starts the retention clock, and how the data is destroyed at the end of its period. It is the operational counterpart to the Privacy Policy: the Privacy Policy explains what Mentum processes and why; this Schedule sets the how long and how it ends.

      1. Purpose and scope

      1.1 Purpose

      This Schedule discharges Mentum's obligation under UK GDPR Article 13(2)(a) to inform data subjects of “the period for which the personal data will be stored, or if that is not possible, the criteria used to determine that period”. It also operationalises Article 5(1)(e) (storage limitation) by binding every personal-data category to a defined retention period, deletion trigger, and destruction mechanism.

      1.2 What this document is not

      • It is not the Privacy Policy. The Privacy Policy is the canonical disclosure of lawful bases, data categories, recipients, transfers, and data-subject rights. This Schedule presupposes that policy and goes deeper on retention only.
      • It is not the Data Processing Addendum. The DPA governs the contractual processor terms between Mentum and its paying customers; this Schedule describes Mentum's controller-side practice.
      • It is not Mentum's internal Records of Processing Activities (ROPA). ROPA is the Article 30 record and goes wider (lawful bases, recipients, transfers) and shallower (no per-table cron timing). Where this Schedule and ROPA disagree, this Schedule is authoritative for retention timing because it is generated from the live code.

      1.3 How to read this alongside the Privacy Policy

      • The Privacy Policy gives the summary retention statements that a candidate or employer can read in two minutes.
      • This Schedule gives the per-table retention statements that a DPO or auditor can verify against the code and migrations.

      2. Lawful basis recap

      Mentum's processing rests on the following Article 6 bases (see Privacy Policy § 3 for the full mapping):

      • Article 6(1)(b) — Contract. Account creation, matching, chat, interview booking, employer search of candidate profiles, advisor conversations for candidates who have opted in. This is the lawful basis for the majority of retention rows below.
      • Article 6(1)(a) — Consent. Marketing communications, AI-feature opt-in, and cookie categories beyond strictly necessary. Consent records themselves carry a statutory retention period (see § 9).
      • Article 6(1)(f) — Legitimate interests. Security telemetry, application audit logs, abuse prevention. Balancing-test outcomes are recorded in Mentum's internal ROPA.
      • Article 6(1)(c) — Legal obligation. Consent retention under UK GDPR Article 7(1) and Article 17(3)(e); breach-register retention under Article 33; PECR record-keeping. See § 9.

      3. Two retention concepts you'll see in this document

      This Schedule uses two distinct end-of-life mechanisms, and the distinction matters.

      3.1 Deletion

      The row is physically removed from the database. After the daily retention sweep, a hard DELETE (or a chain of foreign-key-cascading deletes) takes the data out of the live system. The only residual copy is in Supabase's encrypted, time-limited backup window — see § 10. Most rows on this Schedule are deleted at end-of-life.

      3.2 Pseudonymisation

      The row is preserved, but the identifying columns are nulled or replaced with the literal token [Removed]. The remaining row is structurally meaningful (foreign-key relationships, employer-side recordkeeping, statistical integrity) but is no longer attributable to the original data subject. Two specific cases use pseudonymisation rather than deletion:

      • The 36-month inactivity sweep on candidate profiles. A candidate who has not signed in for 36 months has their personal identifiers blanked from candidate_profile while structural columns are retained for aggregate analytics.
      • Chat messages after a match closes. Closed-match chat content is replaced with a retention notice; the surrounding metadata (sender, timestamp, match reference) is preserved for employer-side recordkeeping.

      In both cases the data is no longer personal data within the meaning of UK GDPR after pseudonymisation, but the database row remains. This Schedule labels every such case “Pseudonymisation” in the Destruction mechanism column so the difference is unambiguous.

      4. Retention schedule — candidate data

      The following table is the authoritative per-category retention schedule for personal data Mentum processes about candidates. Underlying table names are shown in code font after the plain-English category name for auditor cross-reference.

      Data categoryRetention periodDeletion triggerDestruction mechanism
      Active candidate account (candidate_profile)While account active. 24 months of sign-in inactivity → deactivation; 36 months → pseudonymisation (identifiers nulled to [Removed])Last sign-in timestamp older than thresholdpg_cron @ 04:15 UTC via run_retention_cleanup()
      CV file storageUntil account deletion or the 36-month pseudonymisation sweepUser-triggered erasure or 36-month inactivity sweepSynchronous on DELETE /api/auth/account. On the 36-month path the 04:15 UTC retention-cleanup-daily job nulls cv_url and enqueues the storage object paths into pending_storage_purge; the 05:00 UTC retention-storage-purge-daily job then deletes the actual storage bytes (a two-step flow, not a standalone Python sweeper)
      Profile photoUntil account deletion or explicit user deleteUser-triggered erasure or user clears photo in profile settingsSynchronous on DELETE /api/auth/account; storage delete on explicit user action
      Chat message content (chat_message.content)12 months after the parent match enters a closed status; 36 months absolute outer bound regardless of statusClosed match status or absolute age over 36 monthsPseudonymisation (row preserved, content replaced with a retention notice; sender, timestamp, match reference preserved) — pg_cron @ 04:15 UTC
      Chat attachmentsAligned with message content — purged when the closed-match window elapsesClosed match + 12-month windowTwo steps, like CV files: the retention sweep pg_cron @ 04:15 UTC clears the attachment metadata and queues the storage object; the bytes are deleted from the bucket by the storage-purge job at 05:00 UTC the same morning.
      AI match scores, summaries, feedback (match_ai_score, match_ai_summary, match_ai_positive_feedback, match_ai_negative_feedback, match_stats)Lifetime of the underlying job postingParent job deleted at 6 months inactive with no active matches or user erasurepg_cron @ 04:15 UTC FK-cascading delete or synchronous on DELETE /api/auth/account
      Enhanced career insights (match_enhanced_insights)Lifetime of the parent matchSame as match scores aboveSame as match scores above
      Advisor conversations (advisor_conversation)24 months after the conversation is marked inactive (fixed in the scheduled job run_retention_cleanup())is_active = false and age over threshold or user erasurepg_cron @ 04:15 UTC via run_retention_cleanup()
      Career-trajectory cache (career_trajectory_cache)7 days (regenerated on demand)Cache age over thresholdRefreshed on next request; deleted synchronously on account erasure
      Notifications — read6 monthsis_read = true and age over 6 monthspg_cron @ 04:15 UTC
      Notifications — unread12 monthsis_read = false and age over 12 monthspg_cron @ 04:15 UTC
      Notification preferencesUntil account deletionUser-triggered erasureSynchronous on DELETE /api/auth/account
      Push subscriptionsUntil user opt-out or account deletionUser opt-out via app settings or user erasureSynchronous on user action or DELETE /api/auth/account
      Behaviour events (candidate_behaviour_event)6 months (fixed in the scheduled job run_retention_cleanup())Age over thresholdpg_cron @ 04:15 UTC
      Eligibility declarations (candidate_requirement_status) — your self-declared answers to a role's licence, clearance, professional-registration, qualification and shift-availability requirementsUntil account deletion. Any single answer can be cleared back to unanswered at any time, which deletes that row immediately. Answers are included in the Art. 20 data export.User-triggered erasure or the candidate clearing an individual answerSynchronous on DELETE /api/auth/account via the delete_candidate_account RPC
      Saved matches, bookmarks, blocked companies, question answers, skills, experience, education, interests, accessibility preferences, availability (all candidate-owned rows)Until account deletionUser-triggered erasureSynchronous on DELETE /api/auth/account via the delete_candidate_account RPC
      Match details rows (match_details)Lifetime of the parent job; anonymised rather than deleted on candidate erasure — the candidate identifier is set to NULL while the row is preserved for the employer's recordkeeping (employment-law defensibility)Parent job purged at 6 months inactive + no active matches or user erasurepg_cron @ 04:15 UTC FK cascade (job-deletion path) or synchronous FK NULL on erasure
      Interview scorecards (interview_stage_feedback, stage_feedback_score) — the employer's per-stage rubric scores, hire recommendation, free-text notes, strengths and concerns, and the optional note the employer chooses to share with the candidateLifetime of the parent match record. Not cleared by candidate erasure: the match row is anonymised rather than deleted, and the scorecard is held as an employer-owned hiring recordParent match record deleted on the job purge in § 5, or the employer deletes the scorecard, or the scoring staff member's account is deletedFK-cascading delete from the match record, and from the scorecard to its rubric scores; synchronous when the employer deletes the scorecard or when the scoring staff member's account is deleted

      Headline read

      • No “set-and-forget” candidate data exists. Either the account is active (and rows persist), or the user has chosen to delete (and rows are removed synchronously), or the account has gone cold for 24/36 months (and rows are pseudonymised on the inactivity sweep).
      • The two pseudonymisation points are deliberate. The 36-month sweep is the inactivity floor; closed-match chat is the per-match floor. Both are explicit choices rather than incomplete deletion logic.
      • The match_details row is the only “preserved-but-anonymised” employer-facing artefact — preserved because deleting it would corrupt the employer's hiring record. The candidate identifier is removed; the row remains as a hiring-decision record under employment law.
      • An account that was never completed is removed on an event, not a clock. Choosing “Continue with Google” on the sign-in page without a Mentum account leaves a sign-in record that holds nothing but the email address, has no role and no profile, and cannot be used. Signing up by email with the same address deletes that record before the new account is created. It is not a sweep: a record nobody signs up over is retained until then.

      5. Retention schedule — employer and job data

      Data categoryRetention periodDeletion triggerDestruction mechanism
      Active employer account (company_profile)While account active. No inactivity timer — deleted only on user-triggered erasureUser-triggered erasureSynchronous on DELETE /api/auth/account via the delete_employer_account RPC
      Employer calendar connection (user_calendar_connection) — an employer staff user's calendar authorisation, held only as encrypted ciphertext, with the granted scopes and the calendar identifierWhile the connection is live. A revoked connection keeps its credential-free metadata for 90 days; revocation itself wipes both encrypted token columns immediatelyDisconnect, a terminal authorisation failure, or account erasure (all wipe the encrypted tokens immediately), then 90 days from revocation for the metadata rowImmediate wipe on revoke; pg_cron @ 04:15 UTC via run_retention_cleanup() (bounded to 1,000 rows a night); FK cascade when the staff account is deleted
      Calendar mirror delivery records (calendar_sync_outbox) — per-booking sync intents and their external calendar event identifiers; no candidate identifier and no names90 days after the intent reaches a terminal state, and only once the linked interview ended over 90 days ago or the booking link has been erased. Queued, retrying and processing intents — and any intent whose booking still has pending work — are never sweptTerminal state + 90-day age + the interview ended or the booking link erasedpg_cron @ 04:15 UTC via run_retention_cleanup() (the same bounded call); FK cascade when the connection or the staff account is deleted
      Employer-posted job — active stateWhile is_active = true. Auto-deactivated at 90 days from posted_on if there are no active matches90-day age + no active matchespg_cron @ 04:15 UTC flips is_active = false, bounded to 5,000 jobs a night so a larger cohort drains over the following nights. Pre-launch carve-out: the frozen pre-launch Adzuna job corpus is intentionally retained for matching development and is not subject to the 90-day deactivation until launch.
      Employer-posted job — inactive state6 months after the last update to the row (falling back to the creation date where a row was never updated), provided no active matches remainis_active = false for over 6 months, no active matches, and the job is not classified as hiring outside the UK. That last condition is a deliberate exemption: a job classified as foreign keeps its row so the country classification and the cross-source duplicate identity are retained. The comparison treats an unresolved or unset classification as not foreignpg_cron @ 04:15 UTC hard-delete with full match-tree FK cascade
      Feed-sourced job — inactive state, untouched by any user7 days after the last update to the row. A feed job any user has interacted with (a match, a saved or watched job, an employer claim) keeps the 6-month clock aboveis_active = false for over 7 days, feed-sourced, no match, saved, watched or claim row, and not classified as hiring outside the UK — the same exemption as the row above, applied by one shared conditionpg_cron @ 04:15 UTC hard-delete with full FK cascade (15,000-job nightly cap)
      Adzuna inbound job description text30 days after posted_on once the parent job is inactiveInactive Adzuna job + 30-day age thresholdpg_cron @ 04:15 UTC updates description text to NULL; the parent row is preserved
      Job ingestion queue — processed7 daysProcessed status + age over 7 dayspg_cron @ 04:15 UTC
      Job ingestion queue — failed30 daysFailed status + age over 30 dayspg_cron @ 04:15 UTC
      Skill processing log (skillprocessinglog)30 daysAge over 30 dayspg_cron @ 04:15 UTC
      Market snapshot (market_snapshot)12 monthsAge over thresholdpg_cron @ 04:15 UTC
      Skill metrics history (skill_metrics_history)6 monthsAge over thresholdpg_cron @ 04:15 UTC
      Skill trend (skill_trend)6 monthsAge over thresholdpg_cron @ 04:15 UTC
      Employer analytics snapshot (employer_analytics_snapshot)24 monthsAge over thresholdpg_cron @ 04:15 UTC
      Salary benchmark cache (salary_benchmark_cache)12 monthsAge over thresholdpg_cron @ 04:15 UTC
      Company intelligence cache (company_intelligence_cache)12 monthsAge over thresholdpg_cron @ 04:15 UTC
      Company intelligence history (company_intelligence_history)52 weeksAge over thresholdWeekly snapshot job @ 04:30 UTC Sundays
      Salary benchmark history (salary_benchmark_history)52 weeksAge over thresholdWeekly snapshot job @ 04:30 UTC Sundays
      Regional market snapshot (regional_market_snapshot)180 daysAge over thresholdDaily capture job @ 03:15 UTC

      Headline read

      • Employer accounts have no inactivity timer. Unlike candidate accounts, an employer account remains live until the user actively deletes it. This is deliberate: long-running employer relationships are a normal commercial pattern.
      • Jobs go through three states with three clocks. Active (90 days posted with no matches), then inactive (6 months for hard delete, measured from the last update to the row and falling back to its creation date where it was never updated), with Adzuna-sourced descriptions further accelerated to a 30-day text NULLification once the parent goes inactive.
      • Analytics tables intentionally outlive jobs. 6-to-24-month windows for market and skill analytics support employer dashboards that compare period-over-period; they hold aggregated analytics, not candidate-attributable data.

      6. Retention schedule — operational and audit data

      These tables matter less to a typical end user but are the artefacts auditors and DPOs ask about during procurement.

      Data categoryRetention periodDeletion triggerDestruction mechanism
      Data access log (data_access_log) — every employer→candidate PII access24 months (fixed in the scheduled job run_retention_cleanup())Age over thresholdpg_cron @ 04:15 UTC via run_retention_cleanup()
      Security events (security_events)12 months (fixed in the scheduled job run_retention_cleanup())Age over thresholdpg_cron @ 04:15 UTC
      Candidate abuse-control events (candidate_abuse_control_event) — one row per admission decision taken by the candidate abuse and rate controls: the event type, the outcome (allowed, denied or observed), a hashed IP prefix and device hash, a small detail object, and the candidate, account and match where known90 days, measured on the event dateAge over 90 daysA separate pg_cron @ 04:37 UTC job — not part of run_retention_cleanup(). Each run deletes at most 10,000 rows, so a backlog drains over the following nights. Ahead of the clock: FK cascade when the candidate profile or the match is deleted, and the account reference is set to NULL when the account is deleted
      Application audit (audit_errors, audit_runs)12 months (fixed in the scheduled job run_retention_cleanup())Age over thresholdpg_cron @ 04:15 UTC
      Pipeline run log (pipeline_run_log)6 monthsAge over thresholdpg_cron @ 04:15 UTC
      LLM usage log (gemini_usage_log) — cost and token attribution90 days (the permanent record is a per-day aggregate with no per-user attribution)Age over thresholdpg_cron @ 04:15 UTC
      Email send log (email_send_log)12 monthsAge over thresholdSeparate pg_cron @ 04:20 UTC (email-send-log-retention-nightly) and the main retention cron — belt-and-braces
      Push send log (push_send_log)6 monthsAge over thresholdpg_cron @ 04:15 UTC
      Email unsubscribe tokens (email_unsubscribe_token)30 daysAge over thresholdpg_cron @ 04:15 UTC
      Employer board event feed (kanban_board_event) — tells an open employer browser to refetch; company, job and match references plus an optional staff actor reference, no candidate identifier and no free text24 hoursAge over 24 hourspg_cron @ 04:15 UTC via run_retention_cleanup(), bounded to 5,000 rows a night so a backlog drains over the following nights
      Cron health log (cron_health_log) — clipped-run monitor90 daysAge over thresholdpg_cron every 30 min via detect_clipped_cron_runs()
      Consent records (user_consent) — statutory carve-out7 years (84 months)Age over threshold (survives account deletion)pg_cron @ 04:15 UTC — see § 9.1
      Breach register (breach_register) — statutory carve-outIndefiniteNone — retained for Art. 33 record-keepingNo automated purge — see § 9.2
      Asynchronous task store (Redis)10 minutesTTLRedis-managed TTL expiry
      Idempotency-Key store (Redis)24 hoursTTLRedis-managed TTL expiry
      Rate-limit keys (Redis)24-hour sliding window + 2-hour slackTTLRedis-managed TTL expiry

      Headline read

      • Operational logs run on three-band retention. Security and access logs hold the longest (12–24 months); pipeline logs hold mid-term (6 months) and the raw LLM-cost log short-mid-term (90 days, with a permanent non-attributable daily aggregate); transactional Redis state holds short-term (minutes to a day).
      • Email send-log retention is enforced twice. A standalone 04:20 UTC cron supplements the main 04:15 UTC retention sweep so the compliance team can observe the email-log path on its own schedule. Both jobs are idempotent.
      • Two carve-outs survive account deletion — consent records and breach register. These are spelled out below.

      7. AI-generated artefacts

      Mentum applies data-minimisation controls at the boundary with its LLM providers — OpenAI for the standard AI workloads (gpt-6-luna) and for the eight premium response surfaces (gpt-5.6-luna), and Google Gemini for embeddings, skill estimation, reading scanned CV files where that fallback is switched on, and as the standard-route fallback. The data flowing outbound varies by feature:

      • CV parsing and CV optimisation are the two paths where name-bearing CV text is sent to an LLM provider, because the name appears in the CV body. Both go to OpenAI; a scanned, image-only PDF is first transcribed by Google Gemini, as uploaded, where that fallback is switched on. On the parsing path National Insurance numbers, dates of birth and postal addresses are stripped before the call; on the optimisation path they are not, because redacting them would corrupt the rewritten CV the candidate asked for. Parsed CV data is persisted to structured fields on candidate_profile.
      • Match scoring, skill estimation and culture-fit run on the standard route (OpenAI, except skill estimation, which runs on Google Gemini) and strip the candidate name before fan-out: the provider sees structured profile data without the identifier.
      • Enhanced insights, career trajectory, advisor conversations, Career Compass and interview practice run on OpenAI's premium route with the same minimisation (name omitted, high-risk personal data stripped).

      The LLM-generated outputs — match scores, insights, advisor transcripts, trajectory caches — are subject to the candidate-side retention rows in § 4. There is no Mentum-side provider persistence beyond those rows. On the Google side, the Google Cloud Data Processing Addendum is in effect for the paid Gemini API Mentum uses (see the sub-processor list). On the OpenAI side, requests set store=false and Mentum does not opt API data into training; Batch API files used for job-description extraction (listing text, no candidate data) are deleted from OpenAI when the batch settles, with a seven-day provider-side expiry as the backstop. The production OpenAI account's DPA, transfer mechanism and retention controls must be evidenced before activation, and no zero-retention claim is made.

      8. User-triggered erasure (UK GDPR Art. 17)

      A candidate or employer who wishes to exercise the right to erasure (“right to be forgotten”) under UK GDPR Article 17 does so by deleting their account in their app settings, which calls DELETE /api/auth/account.

      8.1 What happens synchronously

      When the deletion request is accepted (after explicit in-app confirmation), the request handler executes the role-appropriate RPC — delete_candidate_account or delete_employer_account — within the same HTTP request, before the 2xx response is returned. The RPC performs:

      • Hard delete of all candidate-owned PII rows — profile, skills, experience, education, interests, question answers, saved matches, bookmarks, blocked companies, notifications, notification preferences, push subscriptions, accessibility preferences, availability records, and the related child rows.
      • Storage-bucket purge — CV file and profile photo from object storage.
      • Auth account deletion — the underlying authentication user row is deleted, which propagates as a SET NULL or cascade to every other table holding the foreign key.
      • FK-cascading behaviour for match-history rows — match_details rows have the candidate identifier set to NULL rather than being deleted, so the employer's hiring record remains structurally intact while the candidate is no longer attributable. Chat messages are scrubbed (content replaced with a deletion notice; sender and timestamp preserved).

      8.2 What does not happen synchronously

      • Backup retention. Supabase performs a daily encrypted backup with a 7-day rotation window. The deleted rows exist in those backups until the next rotation cycle naturally expires them. Mentum has no operational access to the backup contents and does not restore backups except in a documented disaster-recovery scenario (see § 10).
      • Statutory carve-outs. Consent records (Art. 7(1) and Art. 17(3)(e)) and breach-register entries (Art. 33) survive account deletion. See § 9.

      8.3 Cross-reference

      For the procedural detail on exercising any data-subject right (verification, response times, complaint route), see Privacy Policy § 11.

      9. Statutory retention carve-outs

      Two categories survive account deletion because UK GDPR or PECR requires it.

      9.1 Consent records

      Retention: 7 years (84 months). Survives account deletion under UK GDPR Article 17(3)(e) (processing necessary for the establishment, exercise or defence of legal claims) read with Article 7(1) (the controller's burden to demonstrate that consent was given). The 7-year window aligns with the UK limitation period for contract and tort claims under the Limitation Act 1980.

      Practical effect: even after a candidate or employer deletes their account, Mentum keeps an attenuated record showing which consent was given, at what time, for what purpose, and when it was withdrawn. The record does not include the substantive personal data the user has erased; it is a metadata receipt.

      9.2 Breach register

      Retention: indefinite. Retained under UK GDPR Article 33(5). The Article 33 record-keeping obligation has no defined expiry, and the supervisory authority (ICO) may request the historical record at any time during an investigation. The breach register contains incident metadata only; it does not store the affected data subjects' personal data beyond pseudonymised counts and category labels.

      9.3 Other carve-outs

      • Security telemetry retained for legitimate interest (security_events, data_access_log) — see § 6. These are not consent-based and are retained for the duration described regardless of any deletion request, on the legitimate-interest basis (Art. 6(1)(f)) of operating a secure platform. The Art. 21 right to object is balanced against Mentum's documented legitimate interest.
      • Application audit logs (audit_errors, audit_runs) are retained for the 12-month window described in § 6 on the same legitimate-interest basis.

      10. Backup retention

      10.1 Backup window

      Supabase performs daily encrypted backups of the production database. The retention window is 7 days (Pro plan default). Point-in-time recovery (PITR) is available within the same 7-day window down to a 5-minute granularity.

      10.2 What this means for an Art. 17 request

      A data subject who has exercised the right to erasure will see their data removed from the live database within the same HTTP request (see § 8). The data continues to exist within the encrypted backup window for up to 7 calendar days, at which point the natural rotation removes the backup copy.

      Mentum does not perform partial restores or surgical edits to backup contents — the operational shape of the backup system does not support row-level intervention. If a backup is restored as part of a disaster-recovery event, Mentum will re-run the retention process immediately after the restore so that prior erasure requests are re-applied.

      10.3 Recovery targets

      Mentum's Service Level Agreement commits to the following recovery posture, which is restated here for completeness:

      • Recovery Point Objective (RPO): ≤ 5 minutes (PITR Write-Ahead Log window).
      • Recovery Time Objective (RTO): ≤ 4 hours for the database tier.
      • Storage RTO: ≤ 8 hours.

      11. How retention is enforced

      11.1 Automation

      All time-based retention in this Schedule is enforced by pg_cron jobs running in the production database. There is no human review step. The relevant jobs:

      • retention-cleanup-daily at 04:15 UTC daily — runs the master run_retention_cleanup() PL/pgSQL function which executes every cleanup case in §§ 4, 5, and 6 except the standalone jobs listed below. Each case is wrapped in its own savepoint so a failure in one bucket does not abort the rest of the sweep.
      • retention-storage-purge-daily at 05:00 UTC daily — drains the pending_storage_purge queue (populated by the 04:15 job when it nulls cv_url) and deletes the actual storage bytes. Runs via pg_net → POST /api/internal/cron/run-retention-storage-purge (migration 499). The 04:15 job enqueues the object paths; this job removes the files — so CV-file destruction is a two-step flow, not a standalone Python sweeper.
      • email-send-log-retention-nightly at 04:20 UTC daily — standalone job for email_send_log deletion, kept separate from the master cron for compliance-team observability.
      • purge-candidate-abuse-events at 04:37 UTC daily — standalone 90-day sweep of candidate_abuse_control_event (§ 6), bounded to 10,000 rows a run. The minute is chosen so it does not contend with the employer-analytics snapshot that runs at 04:35.
      • detect-clipped-cron-runs every 30 minutes — internal health monitor that flags any cron job whose runtime was clipped by Supabase's 120-second platform default. Writes to cron_health_log (90-day retention per § 6) and surfaces in the on-call alerts.

      11.2 Configurability

      Retention periods that are user-configurable via environment variables are flagged in the tables above with (configurable via HYRE_*). Operator-side changes to these variables are recorded in the source-control history and reflected on the next review of this Schedule.

      11.3 Trigger types

      Two trigger types govern retention:

      • Date-based. “Age over 12 months” — the row's created_at or equivalent column is compared against now() - interval '12 months' within the cron-driven RPC. Most rows in §§ 5 and 6 fall here.
      • State-based. “Closed match status” or is_active = false — the row's status column drives the clock, not the calendar. Chat-message pseudonymisation and job-deletion paths fall here.

      The candidate-profile pseudonymisation case in § 4 is inactivity-triggered: a candidate who never signs in has the 24-month and 36-month clocks started on the last sign-in date, not the account-creation date. Active users have no time-based retention against their candidate_profile row.

      11.4 Monitoring trail

      Each cron run writes to pipeline_run_log (6-month retention per § 6), giving Mentum an auditable record of when the retention sweep ran, what it deleted, and whether it completed within the platform timeout. The cron_health_log health monitor cross-checks this and alerts on clipped or skipped runs.

      12. Changes to this schedule

      Mentum updates this Schedule on an annual cadence (the Next scheduled review date at the top of this page) and off-cycle on any material code change to the retention RPCs, pg_cron schedules, or deletion paths.

      • Material changes — a change to a retention period, a removal of a category, the addition of a new personal-data category, or a change to a deletion trigger — are notified to data subjects via the Privacy Policy banner and reflected in the Last reviewed date on this page.
      • Editorial changes — clarifications, link updates, formatting fixes — do not trigger re-notification; the Last reviewed date is still bumped so the audit trail is unambiguous.

      14 September 2026 update: categories that already had a sweep but were not listed here have been added — employer calendar connections and calendar mirror delivery records, the employer board event feed, employer interview scorecards, and candidate abuse-control events with their own 04:37 UTC job. Corrections in the same pass: the 90-day job-deactivation sweep is bounded to 5,000 jobs a night; the 6-month inactive-job clock is measured from the last update to the row, falling back to its creation date where it was never updated; the two inactive-job rows now state the exemption for jobs classified as hiring outside the UK; and § 4 records that a role-less, profile-less sign-in record is deleted when someone signs up by email with the same address. No retention period changed.

      Data subjects or customers who require a historical version of any prior period of this Schedule may write to privacy@mentumjobs.com and we will provide the relevant prior version.

      13. Contact and complaints

      For questions or complaints about Mentum's retention practice:

      • Data protection / DPO: dpo@mentumjobs.com and privacy@mentumjobs.com
      • Security reports: security@mentumjobs.com
      • Operational support: support@mentumjobs.com

      If you are not satisfied with Mentum's response, you have the right to lodge a complaint with the Information Commissioner's Office (ICO):

      • Website: ico.org.uk/make-a-complaint
      • Telephone: 0303 123 1113
      • Postal: Information Commissioner's Office, Wycliffe House, Water Lane, Wilmslow, Cheshire SK9 5AF

      You may also lodge a complaint with the data-protection supervisory authority of your habitual residence or place of work within the UK or EEA.


      Related: Privacy Policy | Terms of Service | Data Processing Addendum | Sub-processors | Service Level Agreement | Cookie Policy