DEV Community

Richard Lau
Richard Lau

Posted on

Using Cron on Vercel: Tips, Tricks, and Examples

Using Cron on Vercel: Tips, Tricks, and Examples

Cron jobs are fundamental yet powerful tools in the world of serverless computing. These time-based task schedulers are essential for developers building modern web applications, enabling them to automate recurring tasks without managing servers or infrastructure.

This article aims to demystify Cron jobs on Vercel. It provides a comprehensive guide explaining what Vercel Cron is, how it works, and most importantly, how to use it to automate repetitive tasks in your serverless applications.

Whether your goal is to set up automatic data synchronization, run scheduled scripts at specific times, or automate maintenance tasks for your serverless applications, this article will show you how Vercel Cron can make it all possible. Let's get started!

What is Vercel Cron?

Vercel Cron is a serverless cron job scheduler that allows you to run scheduled tasks in your Vercel deployments. Unlike traditional cron jobs that run on a server, Vercel Cron executes your functions on a schedule, leveraging Vercel's serverless infrastructure.

It's most commonly used for automating maintenance tasks, data processing, API health checks, and periodic data synchronization, but it can be used for any purpose that requires regular, scheduled execution of serverless functions.

How Vercel Cron Works

At its core, Vercel Cron operates as a serverless scheduling service. When you configure a cron job, Vercel automatically invokes your specified API route or Serverless Function at the scheduled intervals.

The system checks your cron configuration and triggers the appropriate endpoints when the scheduled time arrives. This naturally leads to the next key aspect of setting up Vercel Cron operations—configuration files.

Cron Configuration Files

The vercel.json file is the heart of the Vercel Cron job scheduling system. This configuration file contains the cron schedule definitions that tell Vercel when and how to execute your scheduled functions.

Each cron job entry in the vercel.json file represents a separate scheduled task and includes information about when the job should run, along with the path to the function or API route that should be executed.

Essentially, Vercel Cron configurations are defined in your project's vercel.json file, which should be placed at the root of your project directory. Here's what you need to know about the key details.

Cron Syntax Basics

Cron jobs in Vercel are defined using standard cron syntax, which consists of five time fields followed by the path to your function or API route. The basic syntax for a Vercel Cron job is as follows:

{
  "crons": [
    {
      "path": "/api/cron",
      "schedule": "0 0 * * *"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Understanding the Cron Schedule Structure

Let's break down the schedule component:

Minute (0-59)
This field specifies the minute at which the command will run. It can be a value between 0 and 59. For example, setting it to 0 will run the command at the start of the hour.

Hour (0-23)
The hour field is specified in 24-hour format. It determines the hour of day for execution. For example, setting it to 14 will run the command at 2:00 PM.

Day of Month (1-31)
This field specifies the day of the month when the command will run. It can be any value from 1 to 31, depending on the number of days in the month. For example, setting it to 1 will run the command on the first day of each month.

Month (1-12)
The month field determines the month when the command should execute. It can be a value from 1 (January) to 12 (December). For example, setting it to 12 will execute commands in December.

Day of Week (0-6)
This field specifies which day of the week the command should run. It can be a value from 0 (Sunday) to 6 (Saturday). For example, setting the command to 5 will run every Friday.

Special Characters in Cron Syntax

Cron syntax also supports special characters to specify more complex scheduling patterns:

Asterisk (*): Represents "every" time unit. For example, * in the hour field means "every hour."

Comma (,): Allows specifying a list of values. For example, 1,3,5 in the day-of-week field means "run on Monday, Wednesday, and Friday."

Hyphen (-): Specifies a range of values. For example, 9-17 in the hour field means "from 9 AM to 5 PM."

Slash (/): Specifies increments. For example, */10 in the minute field means "every 10 minutes."

When working with complex cron schedules, online tools like Crontab Calculator provide powerful web-based interfaces to help you visualize and validate your cron expressions before implementing them in your Vercel configuration.

Setting Up Vercel Cron Jobs

Now that we've covered the theory, let's get into the exciting part: creating your first Vercel Cron job.

Basic Setup

To create a Vercel Cron job, you'll need to:

  1. Create or update yourvercel.json file in the root of your project
  2. Add acrons array with your scheduled jobs
  3. Create the API route or Serverless Function that will be executed

Example: Creating a Daily Cleanup Job

Let's create a simple example that runs a cleanup task every day at midnight:

Step 1: Create vercel.json

{
  "crons": [
    {
      "path": "/api/cleanup",
      "schedule": "0 0 * * *"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the API Route

In your pages/api/cleanup.js (for Pages Router) or app/api/cleanup/route.ts (for App Router):

// app/api/cleanup/route.ts
import { NextResponse } from 'next/server'

export async function GET(request: Request) {
  // Verify the request is from Vercel Cron
  const authHeader = request.headers.get('authorization')
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return NextResponse.json({ message: 'Unauthorized' }, { status: 401 })
  }

  try {
    // Your cleanup logic here
    console.log('Running daily cleanup...')

    // Example: Delete old database records
    // await deleteOldRecords()

    return NextResponse.json({ 
      success: true, 
      message: 'Cleanup completed',
      timestamp: new Date().toISOString()
    })
  } catch (error) {
    console.error('Cleanup failed:', error)
    return NextResponse.json(
      { success: false, error: error.message },
      { status: 500 }
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Set Environment Variable

Add CRON_SECRET to your Vercel environment variables for security.

Creating Multiple Cron Jobs

You can define multiple cron jobs in a single vercel.json file:

{
  "crons": [
    {
      "path": "/api/daily-backup",
      "schedule": "0 2 * * *"
    },
    {
      "path": "/api/hourly-sync",
      "schedule": "0 * * * *"
    },
    {
      "path": "/api/weekly-report",
      "schedule": "0 9 * * 1"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Security Best Practices

Protecting Your Cron Endpoints

Since cron endpoints are accessible via HTTP, it's crucial to secure them. Vercel provides a VERCEL_CRON_SECRET header that you can verify:

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

  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 })
  }

  // Your cron job logic
}
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can check for the x-vercel-cron header:

if (request.headers.get('x-vercel-cron') !== '1') {
  return new Response('Unauthorized', { status: 401 })
}
Enter fullscreen mode Exit fullscreen mode

Common Cron Job Examples

Here are several practical examples covering most common scheduling scenarios:

Every Minute

{
  "path": "/api/health-check",
  "schedule": "* * * * *"
}
Enter fullscreen mode Exit fullscreen mode

Every Hour

{
  "path": "/api/hourly-task",
  "schedule": "0 * * * *"
}
Enter fullscreen mode Exit fullscreen mode

Every Day at Midnight

{
  "path": "/api/daily-task",
  "schedule": "0 0 * * *"
}
Enter fullscreen mode Exit fullscreen mode

Every Day at 2 AM

{
  "path": "/api/nightly-backup",
  "schedule": "0 2 * * *"
}
Enter fullscreen mode Exit fullscreen mode

Every Monday at 9 AM

{
  "path": "/api/weekly-report",
  "schedule": "0 9 * * 1"
}
Enter fullscreen mode Exit fullscreen mode

Every 15th of the Month

{
  "path": "/api/monthly-billing",
  "schedule": "0 0 15 * *"
}
Enter fullscreen mode Exit fullscreen mode

Every 5 Minutes

{
  "path": "/api/frequent-check",
  "schedule": "*/5 * * * *"
}
Enter fullscreen mode Exit fullscreen mode

Every Hour During Business Hours (9 AM - 5 PM)

{
  "path": "/api/business-hours-sync",
  "schedule": "0 9-17 * * *"
}
Enter fullscreen mode Exit fullscreen mode

Every Tuesday and Thursday at 4 AM

{
  "path": "/api/biweekly-task",
  "schedule": "0 4 * * 2,4"
}
Enter fullscreen mode Exit fullscreen mode

Advanced Use Cases

Database Cleanup

// app/api/cleanup-db/route.ts
export async function GET(request: Request) {
  // Verify cron secret
  if (request.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 })
  }

  try {
    // Delete records older than 30 days
    const thirtyDaysAgo = new Date()
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30)

    // await db.deleteMany({
    //   where: {
    //     createdAt: {
    //       lt: thirtyDaysAgo
    //     }
    //   }
    // })

    return NextResponse.json({ 
      success: true,
      deleted: 0 // Replace with actual count
    })
  } catch (error) {
    return NextResponse.json({ error: error.message }, { status: 500 })
  }
}
Enter fullscreen mode Exit fullscreen mode

API Health Check

// app/api/health-check/route.ts
export async function GET(request: Request) {
  const endpoints = [
    'https://api.example.com/health',
    'https://another-api.com/status'
  ]

  const results = await Promise.allSettled(
    endpoints.map(url => fetch(url))
  )

  const failed = results.filter(r => r.status === 'rejected').length

  if (failed > 0) {
    // Send alert
    // await sendAlert(`${failed} endpoints are down`)
  }

  return NextResponse.json({
    checked: endpoints.length,
    failed,
    timestamp: new Date().toISOString()
  })
}
Enter fullscreen mode Exit fullscreen mode

Data Synchronization

// app/api/sync-data/route.ts
export async function GET(request: Request) {
  try {
    // Fetch data from external API
    const response = await fetch('https://external-api.com/data')
    const data = await response.json()

    // Process and store data
    // await db.upsertMany(data)

    return NextResponse.json({
      success: true,
      synced: data.length,
      timestamp: new Date().toISOString()
    })
  } catch (error) {
    return NextResponse.json({ error: error.message }, { status: 500 })
  }
}
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Cron Jobs

Unfortunately, when Cron jobs fail to run, it can be frustrating. Here are some guidelines for investigating the issue.

Verify Cron Configuration

The first step in troubleshooting is to ensure your cron job is defined correctly. Verify that:

  • Yourvercel.json file is in the root directory
  • The syntax is correct (you can useCrontab Calculator to validate)
  • The path to your API route is correct
  • Your deployment includes thevercel.json file

Check Function Logs

View your function logs in the Vercel dashboard to see if the cron job is being triggered and what errors might be occurring:

  1. Go to your project in Vercel dashboard
  2. Navigate to the "Functions" tab
  3. Find your cron endpoint and view its logs

Test Manually

Before relying on automated execution, test your function manually by making a direct HTTP request to the endpoint:

curl -X GET https://your-project.vercel.app/api/your-cron-endpoint \
  -H "Authorization: Bearer your-cron-secret"
Enter fullscreen mode Exit fullscreen mode

This helps you determine if the issue is with the function itself or with the cron scheduling.

Common Issues

Issue: Cron job not running

  • Ensurevercel.json is committed and deployed
  • Verify the cron syntax is correct
  • Check that your function exists at the specified path

Issue: Function timing out

  • Vercel has execution time limits (10 seconds on Hobby plan, 60 seconds on Pro)
  • Optimize your function or break it into smaller tasks
  • Consider using Vercel's Edge Functions for faster execution

Issue: Authentication failures

  • VerifyCRON_SECRET is set in environment variables
  • Check that your authorization header matches exactly
  • Usex-vercel-cron header as an alternative verification method

Best Practices and Tips

  1. Test your functions manually before relying on cron scheduling to ensure they work as expected.
  2. Use absolute paths and environment variables in your functions to avoid path-related issues.
  3. Implement proper error handling and logging to capture any issues during execution.
  4. Set up monitoring for your cron jobs to be notified when they fail.
  5. Be mindful of Vercel's execution limits when scheduling resource-intensive tasks.
  6. Use cron expressions wisely—consider using online tools like Crontab Calculator to validate complex schedules.
  7. Secure your endpoints by verifying the cron secret or using the x-vercel-cron header.
  8. Add idempotency to your functions to handle cases where they might run multiple times.
  9. Monitor costs—while Vercel Cron is included in most plans, be aware of function execution costs if you have high-frequency cron jobs.
  10. Document your cron jobs in your codebase so team members understand what scheduled tasks exist and why.

Conclusion

Vercel Cron is an essential tool for serverless application development. It provides a powerful and versatile solution for scheduling and automating tasks without managing servers or infrastructure.

The beauty of Vercel Cron lies in its simplicity and precision. From simple commands executed every minute to complex scripts scheduled for specific dates and times, cron adapts to many needs.

Through Vercel's serverless infrastructure and straightforward configuration via vercel.json, cron jobs provide developers with the flexibility to customize task scheduling according to their specific requirements.

By leveraging the insights and examples in this article, you'll be well on your way to scheduling success, increased productivity, and unlocking new possibilities in your serverless application journey.

For more detailed information, Vercel's documentation contains excellent information and explanations about how the cron system works on their platform.

Thank you for your time! Your feedback and comments are always welcome.

Top comments (0)