← Templates

A cron job without a server to keep alive

A cron job without a server. It runs on a timer you set in a config file. It has no public address, so nothing on the internet can start it, and there's no cron daemon to look after.

You want a job on a timer, not a server to keep up for it

A cron job usually needs a machine that stays up and a daemon on it that stays configured. Here the timer is one line in a config file. We start your code when it fires.

The whole template is public. Read it before you trust it.

Or scaffold it

$ npx wawesome init --template scheduled-job
$ npx wawesome deploy

What you get

A private Function called health-check. Every five minutes it fetches TARGET_URL and logs the status code and how long the answer took. That check stands in for your own work. It lives in src/check.ts, the handler that runs it is src/index.ts, and src/index.test.ts has the tests.

The schedule is in wawesome-function.json:

{
  "app": "scheduled-job",
  "function": "health-check",
  "entry": "src/index.ts",
  "visibility": "private",
  "opens_host": ["TARGET_URL"],
  "schedules": [{ "name": "health-check", "expression": "*/5 * * * *" }]
}

The expression is five-field cron, in UTC, and five minutes is the shortest interval. "visibility": "private" means the Function has no public address. It runs when the timer fires or when you run npx wawesome invoke.

Run it

npx wawesome init --template scheduled-job

It offers to log you in if you aren’t. Then it asks for a Function name, health-check by default, and an App slug. If you haven’t deployed yet, it offers to change your workspace address, which locks at your first deploy. Then it asks for two values:

  • TARGET_URL, the address to check. Try https://httpbin.org/status/200, or your own service’s health endpoint. We open that one host to your App’s outbound calls. If you leave it blank, every run fails and logs that there’s nothing to check.
  • JOB_SECRET, optional. Leave it blank unless you make the Function public.

Then it deploys and the timer starts. To see a run now:

npx wawesome invoke
npx wawesome logs --follow

Schedules need a paid plan, and on the free plan the deploy is refused. Solo is the cheapest one that has them. See pricing.

What to change first

The body of checkEndpoint in src/check.ts. Put the work you want done there. src/index.ts already logs what it returns.

Nobody reads the response of a scheduled run, so logs are its only output. The status code is the result: a 2xx is a successful run, anything else a failed one. The handler returns 204 even when the check fails. Return an error status if you want a failed check to count as a failed run.

A call to any host other than the one in TARGET_URL is refused until you open it. Egress shows how. To change how often it runs, edit the expression and run npx wawesome deploy.

What it doesn’t do

It doesn’t remember anything between runs. A job that keeps state needs a database of your own. It doesn’t alert you when a check fails, beyond the log line. And a run that was due while the schedule was paused isn’t made up later. Schedules covers pausing and the run history.

  • scheduled
  • cron
  • timer
  • background
  • job
  • typescript

Ready in about a minute

Sign in with GitHub, deploy, and get a public HTTPS endpoint.

Deploy this template