weekly cron job: how to disable on Dev?
I would like to set a weekly cron job that sends an email once per week. But I would like this to happen only in production.
Which is the recommended pattern for this?
First comes to mind to use an env variable.
15 Replies
That's how I've done it, added a
CONVEX_ENV
variable
would be cool to have that variable populated by the system come to think of it
(Netlify and Vercel both have this, for reference)you mean like the vercel integrations?
in this case i would set the env var in the convex dashboard, correct?
Yeah you just set it yourself
Vercel and Netlify both have system env vars that reflect "production", "development", or "preview" so you know what kind of deployment you're running in.
i'll try it out
You'll still incur function calls on both dev and prod, but if you bail immediately based on that env var you won't have much else for usage impact.
btw the reason we don't encourage using env variables in cron config is that the config won't be recalculated when the env variable changes (it's not reactive). for a static env variable like this, it should work though
oh you can also bail inside the cron function, that works and would be reactive 🙂
i think it would be helpful to be able to disable cron jobs from the dashboard
Just found this thread while searching with a similar question in mind. I 1000% agree that there should be a way of disabling cron jobs from the dashboard. Either that or a way of configuring them to specify where they run—dev vs prod—without having to use an environment variable to determine whether or not to bail after they're already running.
Or maybe a prompt when deploying with
npx convex deploy
asking if the user wants dev crons to be disabled. A flag like --disableDevCrons
could be added for cases where the deploy command is running on a server.For fully dynamic cron jobs you can check out https://stack.convex.dev/cron-jobs where you could start jobs in prod but nowhere else. This is now a component (sign up to get acccess for now)
For a sense of prod/dev, I'd suggest setting an env in prod.
Cron Jobs in User Space
Even though Convex supports the creation of cron jobs out of the box, until now, we've only supported static jobs. With user space crons, we now suppo...
You generally want prod & dev to not diverge too much, and for those differences to be explicit and probably checked into code. Setting an IS_PROD env variable yourself in your prod deployment is a one-time thing that should work for most usecases.
Also:
npx convex deploy
deploys to prod, not dev.
You can use a customFunction
wrapper for your crons that you only want to run in prod, if you want to avoid boilerplate in each.Yeah, I know. I was just saying that it might be nice to have the disabling of dev crons as an optional side-effect of prod deployment; i.e. "I see you're deploying to production. Would you like us to clean up your dev crons while we're at it?" I can't think of a situation where someone would want the same cron process to be running live in both dev and prod environments. Especially because crons in Convex are likely interacting with the DB in some way, kicking off both a prod cron and a dev cron to do the same thing to the same data is potentially dangerous, is it not?
I haven't looked into custom function wrappers yet. How would that be used in this case?
Never mind. I dug into it, and I think I get the idea. However, wrapped or not the function kicked off by the cron is still running in both dev and prod. It eats up more function and CPU usage than having it only run in prod, plus I'm still not sure how safe it is when both are interacting with the database simultaneously.
what is the cron doing that you only want to do in dev or prod but not both? A typical use-case of crons is to clean up data, which seems useful im both. Your prod and dev have the same schema and the same functions, so it doesn't sound dangerous to me to run the same crons on both
True, the dev and prod environments in Convex operate on different data. However, in my case there's another factor to consider, at least for a while.
At work, I'm starting to prepare to migrate our data and processes from Airtable to Convex. The bulk of the migration is several months away, but I'm starting to use Convex already for some new things, including recurring processes triggered by crons.
A sizable chunk of our business logic runs via serverless functions that currently live on DigitalOcean, and those functions operate on records in multiple Airtable bases. I set up a cron on Convex the other day to run weekly and kick off a DO function that checks—and possibly modifies—some data in Airtable. If that function is called simultaneously by both dev and prod crons on Convex, there's no telling what will happen with the data.
Until the Airtable data is moved to Convex where the prod and dev environments do operate on different data, that cron—and any more that I might end up creating before the actual data migration—will effectively be driving functions that operate on a single data source. For me, that's where the danger lies.
A lesser concern would be after our migration to Convex is complete, there would still be certain processes that run on a schedule, and some may optionally notify a staff member about certain things found in the data; e.g. a reminder to perform a certain task if something hasn't been addressed for a certain period of time. I wouldn't necessarily want those notices to go out based on both dev and prod data.
Interesting. It sounds like both your dev and prod convex deployments are writing to the same Airtable database. That's not what I would do -- I would use convex environment variables to ensure that dev talks to a separate (test) airtable database. Or maybe make sure the convex dev only reads, never writes, to the airtable db. This isn't related to crons; no convex functions in dev should be writing to a prod airtable db.
As for emails, that makes sense you don't want convex dev deployment to send emails, whether via cron or via any other function. So I would connect convex dev with an environment variable to a different email service, one that doesn't actually send emails.
In fact, most official emails you receive from Convex are sent by a Convex project, specifically the prod deployment. The dev deployments are configured with env variables to send dry-run emails, so we can inspect them in mailchimp but they don't get sent.
It sounds like both your dev and prod convex deployments are writing to the same Airtable database.Not quite. Our serverless functions on DigitalOcean are the only things writing to Airtable (and unfortunately our setup there is so complex, and Airtable doesn't have a built-in way of creating dev environments, that creating a dev environment that matches the live environment would be a maintenance nightmare; yet another reason I'm looking forward to moving to Convex!). My concern is about any Convex cron that I make that calls one of those DigitalOcean functions. A cron running in both prod and dev environments in Convex could potentially call the same DigitalOcean function twice at the same time. Right now I'm using the environment variable trick to only let the production crons actually execute on Convex. Until there's a switch in the dashboard to just disable crons in either environment, I guess that'll be how I manage things. As for the email thing, all of that is also happening on DigitalOcean for now. Any function over there that needs to send an internal email just calls another function to do the job. Once I migrate that logic to Convex, I'll likely use another environment variable hack, but in my case it'll just toggle the recipient instead of the service. I already do something similar for current testing on DigitalOcean, sending test emails to myself instead of the "live" recipient.