Scheduled Jobs
How background tasks are orchestrated around execution limits.
Job-Easy has 14 robust background cron jobs for syncing emails, polling ATS boards, draining mail queues, and cleaning up stale accounts.
The Vercel Limitation Bypass
The vercel.json file defines the crons. However, Vercel's Hobby plan rejects any cron expression that would fire more than once a day. The deployment literally fails if you try to deploy a sub-daily cron on a Hobby account. Because of this, the vercel.json expressions are essentially "once-a-day backstops".
To restore real cadence (e.g. syncing Gmail replies every 10 minutes, or draining the mail queue every minute), the endpoints accept a secure secret header:
Authorization: Bearer $CRON_SECRETThis allows an external scheduler to ping the endpoints securely at their intended frequency, bypassing Vercel's platform limits completely while keeping the jobs serverless.
The Two-Write Lifecycle
Every job is wrapped by a strict cronHandler() function that orchestrates the JobRun audit log. Because serverless functions are unceremoniously killed when they hit their execution ceiling, a killed function cannot record its own failure.
To solve this, the wrapper explicitly issues two writes per run:
- It writes a
runningstatus before the handler executes. - It writes
successorfailedafter completion.
A dedicated reaper job (/api/cron/purge-stale) sweeps the database for old running rows and safely marks them as timeout, cleanly distinguishing a platform execution kill from a code-level exception.
Manual Invocation
When an admin runs a job manually from the Monitoring dashboard (POST /api/admin/monitor/jobs/[job]/run), the system makes an internal HTTP call to the job's public route rather than importing the handler directly.
This ensures the manual run traverses the exact same middleware and cronHandler() instrumentation as the automated scheduler. There is no SSRF surface because the requested job key is strictly validated against the internal CRON_JOBS registry before the HTTP call is constructed.
Queue Concurrency
FOR UPDATE SKIP LOCKED raw SQL query to claim rows. This structurally prevents two concurrent cron invocations from accidentally grabbing and double-sending the same message if their execution windows overlap.