Where to run a kinda `cron` specific for each user?
I have the necessity to run a function each hour, this function will add some data into different database tables so I do not want to rely on a
cron
because, if the user stops to use the platform, I'll end up just adding trash to the database for no reason.
So my idea is to go into the auth.ts
and use the session
event provided to go and fetch the lastRun
column of my user profile.
If the difference between now and lastRun
is more than 1 hour, I'll call the function that will do all the things that has to do.
Do you think it could be a good approach or there are better ideas out there?8 Replies
Your idea seems ok... But checking on each session may be a little too much... Because session runs on each page refresh and in some cases een more frequently. Do you really want to slow down the loading of the site each time just to check that?
An alternative solution would be to use crons but have another cron checker which will run (e.g once a day) and check if there are any crons that should be deleted and delte them... Now this may be wrong depending on what services you use and how much that would cost you.
Thanks for the feedback, my 'issue' was about the fact that
cron
(Vercel ones) are Edge function and can timeout.
I know I am solving a problem that I do not have (yet) but the idea of moving on the user session was to make it more fast to check and run the function.
Dunno, start to think about putting this code into a localStorage
or a cookie and keeping the last time run in there, so the check will be on the client in the same browser 🤔
and I'll write on the database only when the function run and pull the data if the browser does not have that localStorage
Maybe you could store the
lastRun
in an HttpOnly cookie? The check would still be on every page, but at least it saves you a DB query.yup really similar to my conclusion, I believe cookies or
localStorage
have similar performances, but haven't checked it deeply.
As I can see by now, I have two options:
- move the check to the client
- make the cron
function as lightweight as possible
Still wondering which approach could be the best.
I like the client-side approach, but that will also need to account for how many days the user does not log in, adding additional logic.
The server-side approach instead will add more pressure on the database side.
Need to think about it 🤔Don't use Vercel Crons, you cannot edit,add,delete them programatically, but have to do it in their dashboard I believe.
Instead use something like Upstash which handles crons on the edge 👍
Another question, should this function of yours run each hour or each hour the user is active?
Because if it's for all users each hour you can have a cron job that will be get all the users from the db, then do whatever you need to do
I see your answer above
I like the client-side approach, but that will also need to account for how many days the user does not log in, adding additional logic.
But yea, you cannot have it all... you will need to make a compromise somewhere. In case you really need this to be done, you should do it with a cron serverside, because thats the only surefire way
And the fact that it will strain your db is not really that important, since it will probably strain more the backend where you do your logic
and if you use a db service like planetscale they will scale for you, sou you don't need to worry thereyup I think I'll do one task each hour for everyone, thanks for the tip on Upstash. Need to dig into it.
Also tbh now I am getting some issues on how to run a Next.js API call that will call the tRPC one that will do all the backendy stuff.
Don't have much time to explain, kids require attention now, but if you ask "why don't you call the tRPC straigh?' I was getting a 404 even if the procedure is public.
Anyway, do you think the gSSP could be a good approach here?
Not an expert, found it here and I still have to experiment with it 😅
https://youtu.be/G2ZzmgShHgQ
Christopher Ehrlich
YouTube
Advanced tRPC - Callers, functions, and gSSP
🚨 createSSGHelpers has been renamed to createServerSideHelpers 🚨
Repo for this video: https://github.com/c-ehrlich/you-dont-need-callers
If you want to use schema in the frontend, they cannot be imported from the same file as things that run specifically in the backend. One solution would be to put them into a
procedureName.schema.ts
or simi...No, for these kind of api calls you need an actual next api route not trpc.
So then you would have a cron job that triggers an acutal api endpoint
you shouldnt call trpc from an api, instead put the logic in the api endpoint
or extract that logic into a function then call the function in 2 places if needed
I believe I ended up following your suggestion without knowing it 😅
Basically I've created an
api/cron/transactions/update
in the relative Next.js folder that calls the tRPC endpoint with createCaller
in the following way:
Probably there are better ways to do it, but lucky me it works and right now I have other aspects of the app that I want to finish first. But if you want to leave a different approach I'll make sure to implement it when I'll have time to refactor the code.
Also, thank you so much for Upstash, been using it since then and it works like a charm 😅