Vercel

Cron Jobs

Some application work needs to happen on a schedule instead of in response to a user click. You may need to refresh a sitemap, clear expired records, warm a cache, send a digest, check a provider status, or trigger a small maintenance task. Vercel Cron Jobs let you call a project endpoint on a schedule.

Cron Jobs are useful, but they are not a general replacement for a worker platform. A scheduled request still runs application code, uses platform resources, can fail, can call external services, and can create cost. Treat a Cron Job as a production automation feature, not as a toy timer.

What A Vercel Cron Job Does

A Vercel Cron Job is configured to make a scheduled request to a path in your project. That path is usually handled by a Function or framework route. The schedule determines when Vercel calls it. Your code decides what work happens when the request arrives.

A conceptual configuration in vercel.json can look like this:

{
  "crons": [
    {
      "path": "/api/cron/refresh-sitemap",
      "schedule": "0 5 * * *"
    }
  ]
}

This example is intentionally simple. The endpoint still needs authorization checks, logging, safe retries, and clear behavior. Do not expose a powerful maintenance endpoint just because the intended caller is Vercel's scheduler.

Good Cron Job Use Cases

Cron Jobs are good for small, bounded scheduled tasks. A sitemap refresh can rebuild or notify a search service. A cleanup task can remove expired temporary records. A cache warmup can call a few important pages after deployment. A digest task can gather recent activity and send one email. A health check can verify that a provider is responding.

The best scheduled tasks have a clear owner, clear schedule, and clear success condition. They should finish within platform limits and leave useful logs.

Good candidates include:

Refresh a sitemap.
Delete expired password-reset tokens.
Warm a small set of cache entries.
Sync a small provider status snapshot.
Send a daily internal summary.
Run a lightweight consistency check.

Poor candidates include large imports, long video processing, infinite queue consumers, high-volume batch jobs, and anything that must run continuously for hours. Those usually need a queue, worker, database job system, or separate infrastructure.

Secure The Endpoint

A Cron Job endpoint is still a URL. If it performs maintenance work, protect it. At minimum, require a secret header or token that is not available to browser code. Store the secret in Vercel Environment Variables and compare it in the handler.

A conceptual check looks like this:

export async function GET(request: Request) {
  const secret = request.headers.get('authorization');

  if (secret !== `Bearer ${process.env.CRON_SECRET}`) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }

  return Response.json({ ok: true });
}

Do not put the cron secret in frontend JavaScript, public environment variables, logs, or documentation visible to users. Rotate it if it leaks. Keep the endpoint path boring; security should come from authorization, not from hoping nobody guesses the URL.

Idempotency

Scheduled tasks should be safe to run more than once. This is called idempotency. If a cleanup job runs twice, it should not corrupt data. If a digest job is retried, it should not send duplicate emails to every user. If a cache warmup runs late, it should not break the site.

Design with retries and timing uncertainty in mind. Use database markers, processed-event ids, date windows, or provider idempotency keys where appropriate. Log what the job attempted and what it changed.

Idempotency is especially important because failures are often partial. A job may update three records and then fail on the fourth. The next run should handle that state safely.

Sitemaps And Cache Warmups

Refreshing a sitemap is a friendly beginner use case. The job can call a route that rebuilds a generated sitemap, notifies a search service, or refreshes cached content. Keep the work bounded. If the site has millions of pages, a simple Cron Job may not be the right architecture.

Cache warmups can also be useful, but they should be modest. Calling a few high-value URLs after deployment can reduce first-user latency. Calling every page of a large site every minute is wasteful and may create usage costs. Warm the paths that matter, and measure whether it helps.

Cleanup Tasks

Cleanup tasks remove data that should not live forever: expired sessions, old one-time tokens, temporary uploads, stale preview records, or abandoned draft entries. These jobs are easy to understand and useful in real apps.

Be careful with deletion. Start with a dry-run mode or conservative filter when the task is new. Log counts, not full private records. Consider soft deletes or archival rules if the data has business or legal value. For commercial projects, confirm retention requirements before deleting records automatically.

A cleanup job should answer three questions clearly: what qualifies as expired, what action is taken, and how you can verify the result.

Logs And Failure Review

Cron Jobs can fail quietly if nobody checks them. Add concise logs for start, success, failure, and important counts. Avoid logging sensitive records. Use Runtime Logs to inspect scheduled endpoint behavior.

A good log trail might say the job started, how many records it scanned, how many it updated, and whether a provider call failed. That is enough to debug most issues without leaking private data.

For serious projects, decide who reviews failed scheduled tasks. A daily cleanup job that fails for a month may not break the homepage immediately, but it can create a slow operational problem.

Plan Limits And Cost

Cron Jobs can have plan limits and usage implications. The exact numbers can change, so check Vercel's current Cron Jobs usage and pricing docs for the project plan. Frequency, number of jobs, function execution, provider calls, and logging can all matter.

For personal learning, schedule conservatively. For commercial, client, business, paid, ad-supported, or production business projects, confirm whether the plan supports the needed schedule and who owns billing. Do not promise a frequent production scheduler without checking plan limits.

Choose The Schedule Carefully

The schedule should match the business need, not the developer's first guess. A sitemap may only need to refresh daily after content changes. A cache warmup may only need to run after deployment or a few times per day. A cleanup task may be fine once per night. Running a job every minute can create unnecessary function usage, provider traffic, logs, and failure noise.

Start with the least frequent schedule that still meets the requirement. If users need data refreshed every five minutes, document why. If a client asks for a frequent schedule, explain the cost and reliability tradeoff. Scheduled work is still work, and repeated work can become expensive even when each individual run is small.

Also think about timing. A job that sends a digest should run when the audience expects it. A cleanup job should avoid peak traffic if it competes with user-facing work. A provider sync should avoid provider maintenance windows when known. Time zones should be documented so future maintainers know what the schedule means.

Manual Runs And Safe Testing

Every scheduled job should have a safe way to test it before trusting the schedule. In development, call the endpoint manually with the expected secret and test data. In Preview, use staging credentials and confirm logs look correct. In Production, run a small smoke test or wait for the first scheduled run while someone watches the logs.

For risky jobs, add a dry-run mode. A dry run reports what would happen without changing data. That is especially useful for cleanup, billing, notifications, and provider sync tasks. The dry-run result should summarize counts and decisions, not dump private records.

Manual testing also catches authorization mistakes. If a cron endpoint rejects your manual request with the wrong secret, the scheduled request may also fail. If it succeeds without any secret, the endpoint is too open. Testing the security behavior is as important as testing the business behavior.

Operational Ownership

A Cron Job needs an owner because no user is waiting on the page to report an error. Decide who receives failure alerts, who checks logs, and who can disable the job if it causes trouble. Add a short note near the route or project documentation that explains the purpose of the job, the schedule, the expected duration, and the safe rollback.

Without ownership, scheduled jobs become invisible dependencies. They may keep running after the feature they support is removed, or they may fail silently after an environment variable changes. A small amount of documentation prevents future confusion.

It also makes audits and handoffs much easier.

Future maintainers benefit.

Common Mistakes

The first mistake is leaving a maintenance endpoint unauthenticated.

The second mistake is putting the cron secret in frontend code.

The third mistake is making scheduled jobs non-idempotent.

The fourth mistake is using Cron Jobs for large background processing.

The fifth mistake is logging private records during cleanup.

The sixth mistake is ignoring plan limits, failed runs, and usage cost.

Review Questions

  • What does a Vercel Cron Job call?
  • Why should a cron endpoint still authenticate the request?
  • What does idempotency mean for scheduled tasks?
  • Why might a cache warmup become wasteful?
  • What should cleanup jobs log?
  • Why do commercial projects need plan-limit review before using Cron Jobs?

Official References