Hacker News new | past | comments | ask | show | jobs | submit login
Deno Cron (deno.com)
278 points by 0xedb 11 months ago | hide | past | favorite | 183 comments



I am a lead on a small startup team and one of the biggest pain points is dealing with infrastructure. We have no dedicated devops person and much of that work falls on me and other people who would be better writing code. I think the cloud paradigm is experiencing a shift. Few of us want to deal with cloud infrastructure (whether clicking around or via Terraform or equivalent) to execute a function every X minutes - its unnecessary developer hours. The functionality is so common that it should just work. Perhaps stemming from that there seem to be two recent trends:

1. Services like this cron with Dyno Deploy or Vercel where the cloud things are abstracted away for you.

2. I have no data to back it up but it seems like JVM is experience a bit of a comeback with a few companies adopting Kotlin for backend and, also subjectively, talk about Elixir has increased here on Hacker News (we've all seen that table that shows how the Erlang VM is cron/background jobs/logging service/KV store all rolled into one). And if those are not the trends I feel like they should be.

Both of those are very appealing to me as a team lead. Honestly, I have never been a fan of managing services in AWS/GCP/etc - the setup overhead rarely seemed to outweigh the pros, at least until some heavy amount of data start moving around. I might be stating the obvious - less work is definitely better, but pretty much every company I have consulted for in the last few years had a (crappy) bespoke cloud setup that was a massive time sink.


It is really disappointing to me when I hear takes like this. As an industry we are splitting the roles of programmers and engineers so that programmers can just throw spaghetti at the wall and it is the engineers problem to happily run it.

We need more well rounded people that also fundamentally understand how their code is executing on the backend so performance and cost can be optimized.


You're wrong.

App/mobile and web developers are stretched beyond belief as it comes to skills expected of them. This handbook gives a reasonable overview of the scope of a front-end developer:

https://thoughtworksinc.github.io/front-end-handbook/en/

Yet it's still incomplete, most of the cloud stuff isn't even included.

We're over-asking people. Take Spotify. Has an army of quite decent engineers. They had to actually build a homegrown platform to shield developers from the ops tooling madness. The average developer struggles to understand just git. Even senior ones do.

Front-end developers were a joke 20 years ago. Not taken very serious, not "real" developers. Now it's one of the most complicated programming jobs there are. You have to know...everything.

As for performance, there I do agree that a programmer has a responsibility.


I’d urge you to not so flatly dismiss someone’s opinion as wrong. The situation is obviously (I would think) more nuanced than that.

I’d also argue that if a senior developer does not have control over their VCS, they should rethink their title.

These are tools in a toolbox - you don’t need to be an expert in all of them, but seniority requires, at a minimum, proficiency.


Not to dismiss your opinion, but for someone arguing in favor of nuance, your perspective on seniority is surprisingly... un-nuanced. So a senior is not a senior if they are not proficient at Git? How do you even measure that proficiency?

EDIT: FWIW, I don't value titles like "senior" and never took them to be meaningful.


> So a senior is not a senior if they are not proficient at Git?

In my opinion (for whatever that's worth!), no (although I would say VCS in general, not git specifically). I personally consider being able to properly version control your code to be a critical skill when it comes to development - regardless of your place on the stack. YMMV.

> FWIW, I don't value titles like "senior" and never took them to be meaningful.

I don't necessarily disagree with regard to the current state of the industry, however as a proponent of development having more professional standards I still believe that we should be attempting to find some common ground on the standards of proficiency and mentorship.


While I agree that there is a lot to frontend development, that list is ridiculous. It is useful as far as knowing what categories of things you may come across at some point. But as far as things you need to know? This is significantly overstating it.


The point being that all of those topics are a potential area to deep dive. The previous poster is disappointed that not everyone happens to deep dive on his specific area of interest, while there are likely a hundred areas other people are experts in that he has not done a deep dive for.


Given time you will come across almost all of them. And you're expected to rapidly pick up any gaps you may have in that list.

For the simple reason that on most teams, there's no other person.


It's a pretty fair list of things I have come across in my career. As lead, it's my job to know at least generally about all these things, and for many to have deep experience and intuition into others.

The breadth of my frontend career has only kept expanding over the last 10 years, it's definitely harder than when I started.


This whole post was great except for the first sentence.

I'm getting old and I feel overwhelmed by the creep of "stuff" that I need to know. For me, it used to be UNIX + C + bash shell was enough to survive. My only defence is to write a small Wiki page for each category of "stuff". After a year on the job, I have built an organic encyclopedia that I can quickly search to remind me about "stuff" that I use infrequently.

And, to be fair, holy shit is modern web programming complicated. I am consistently amazed by the results on a wide variety of platforms.

EDIT

Wow, the link that you shared is amazing. Very well written. Thank you to share.


I don’t think having a breadth of knowledge in frontend, backend, and cloud infra is too much to ask.

Think of how much is asked from other white collar professions such as law and medicine.


[dead]


Very few people "understand" git outside of the core development team.

People do know how to use git in their day to day life. Clone, pull, push, maybe a cheeky rebase if they're up for it.

But bisecting and all that deep level stuff? No way an "average developer" will do that without prompted.

I consider myself a senior developer and in many cases I just resort to re-cloning the repository and copying my changes over to it by hand instead of spending time fighting git tooling to get everything done Properly. My way is faster and I can go on with my day.


This is a hot take statement in both directions.

Git is complicated. You’ll also probably only use 10% of it unless you’re writing Git tooling as part of your work.

One does not simply understand “just Git”. One also is not a poor excuse for a developer for not bothering to understand the 90% of Git that is never even used in a day to day workflow, and it’s not really true that an average developer struggles to understand the 10% of Git that they need to know to do their jobs.


Barnacle of the recent boom where cheap money meant every team and business were 2-3x as big as necessary, everyone got an assistant (even the assistants) and lattes all day

Some projects seems to be pulling “ops” functionality into a new monolith that is also the languages native environment (deno, vercel)

Still all Linux at the hardware layer and oodles of scripting language state, HTML/CSS. The web is a bloated mess after the “throw spaghetti at wall to try and gain market advantage, boost engagement” efforts of the last 10-12 years

MBAs ran software engineering as if machines were squirting soup into cans.


We need decently designed environments where running stuff is trivial. It's not practical to expect the same person to be able to deal with both all the bullshit that comes from making the spaghetti and all the bullshit that comes from making it adhere to the wall.


It is practical, a lot of us do it. Besides, the amount of bullshit it takes to make the spaghetti stick to the wall is dictated by how it was made.

Make nice spaghetti and it sticks to the wall effortlessly. Make bad spaghetti and it takes 4 people and a dozen rolls of duct tape to get it up there.


> the amount of bullshit it takes to make the spaghetti stick to the wall is dictated by how it was made

I really don't know where the bullshit coming from. Often it looks like every single person is fighting for their lives against it, and yet it keeps growing.

But it's mostly dictated by overarching decisions that constrain both how it runs and how it's made (AKA, outside somewhere). Of course, there exist people on both sides that create problems all by themselves, but those are always easy to solve.


> But it's mostly dictated by overarching decisions that constrain both how it runs and how it's made (AKA, outside somewhere).

While annoying, there's often a good reason behind those if you can drill down to the engineers that asked for that rule.

Just as an example, it's easy to provide a single HA solution at the infrastructure tier... provided the infra people can make a few assumptions about your app (stateless, can handle multiple copies running at once, etc). It's virtually impossible to build HA that makes no assumptions, and it's incredibly burdensome to support 85 different HA implementations with varying sets of assumptions.

It makes business sense to have infra do the HA instead of each developer team, and that means restrictions on how apps are built and run.

What you're experiencing is the platform-ization of a bunch of aspects of the app.

Making nice spaghetti usually consists of finding the rules, finding the people who made them, and then grabbing them and asking "what does it take for this app to be in prod 15 minutes after we push the last commit?". It sounds like it will be a lot of people because there's a lot of rules, but there's usually like a half-dozen teams that make all the rules.

It will likely force you to build differently than you would have, but it will also mean that you're more likely to have 0 friction and you're more likely to get help with the friction you do encounter.


Oh, but we have been doing HA everywhere since the turn of the century. It adds some complexity, but absolutely can't explain it constantly creeping in.

There's some complexity coming from better usability requirements, but again, it only explains a small part of it. There's something from the even-driven nature of the web never actually making inroads into our toolset (any toolset people actually use), that's a larger one, but again, it was 20-and-many years ago, it can't explain a constant creep-in.

Instead, since the 10's all the large innovations on software development seem to be about standardizing the complexity, and separating it so you can offshore. And yet, every time one of those gets adopted, the complexity creeps in.


> It's not practical to expect the same person to be able to deal with both all the bullshit that comes from making the spaghetti and all the bullshit that comes from making it adhere to the wall.

I don't think I agree. Complexity--many parts, opposes "simple"--is part of the job; I'm pretty comfortable reasoning at the product layer (I've done devrel and product management) and working down to the cloud or bare metal (sometimes you find yourself wielding strace and wondering what mistakes got you here). Granted, that I have a handle on that complexity is part of why I'm a staff/principal engineer: to do that, and to help others who haven't achieved that level of understanding yet.

But by trying to remove complexity, IME you invariably introduce complication--relative difficulty in comprehending a given part, opposes "uncomplicated"--and that's where the demons lie. You give "the spaghetti maker" a nice, perfectly spherical pasta extruder; the amount of complication introduced by attempting to insulate the person on that side of the house only introduces problems for the other, who in turn must introduce complication to maintain it. That itself in turn introduces new constraints to the guy who just wants to turn the crank on the spaghetti maker and now his world reintroduces the complexity the initial perfectly-spherical-tool tried to remove.

Better, instead, to embrace that there are multiple moving parts that themselves are allowed to be uncomplicated, and work from there. Some complication is inevitable and irreducible, but if you don't treat each part of your system as being on an island, you can manage it and put it where it has the least impact.


It does not matter if you are "well rounded". If you can schedule something with a line of code then that is objectively faster to develop and maintain than to (for GCP for example):

- setup cloud cron job

- setup pubsub channel

- create pubsub subscription

- add environment variables specifying the subscription

- make all that work in terraform and run migrations

And that process is different for every cloud provider.


I had exactly this problem, and honestly the easiest thing to do was set up a $12/mo VPS and use actual cron. I evaluated the cloud scheduled function you laid out there and was like "...nah".


Straight up have engineers I work with on the regular who don't know how to use a Linux distro. The concept of a VPS or SSH'ing into something, not even a prod env, is seemingly terrifying to people.


I feel this deeply, many of the devs in my company don't know linux, kubernetes or even docker, though the services they developed run on these things, I can understand that they need to focus on business logic and implementations, but it just seems odd for me that they don't even try to understand the underlying infrastructure, they just leave it to devops guys.


This is a very different thing. Deno deploy have identified a few commonly used tools and implemented them as (IMO) very leakless abstractions. Why hire a team of engineers to implement a worse abstraction layer for you?

Performance (in particular cold start time) is better than most other similar cloud faas products. Dev ergonomics also.

If you need something more, sure go ahead and use another tool. But very many use cases will be well served by deploy in its current state.


A person can only be a true expert in a few areas. I'm interested in math and data science outside of writing business code. Maybe you're an expert in those too? I don't feel like I should be dismissed because I don't have much interest in hardware.


"Engineer" seems to be synonymous with "Dev Ops Engineer" to you.


What you are descibing is an SRE... in the old Google definition.


> We need more well rounded people that also fundamentally understand how their code is executing on the backend so performance and cost can be optimized.

There's also some sort of balance that needs to be struck. As a 'web developer'... to be 'well balanced', I need to understand (or dig in to) the minutia of:

* JS build tools, syntax, oddities, versions, and be able to troubleshoot these in a variety of environment (works locally with these architectures, and runs on production, but the CI pipeline changed to accommodate someone else and now I have to unstuck all this).

* SQL - I need to understand the implications and nuance of various indexing strategies because... hey, PG 14 changed and now our caching approach needs tuning. Should I be using b-tree indices, or something else? Should my indices be clustered? How do I manage replication and backups? And I need to understand the tradeoffs of ORMs vs hand-rolled, vs stored procedures, time-series databases, performance impact of views and materialization. And security.

* Application level - I need to understand various aspects of security at the application layer, and balance security vs usability vs accessibility vs performance vs feedback from various program/product managers and end users. Oh, and I need to be able to troubleshoot the application in a variety of contexts. Oh... and mobile. I need to be conversant and 'well rounded' in various flavors of mobile development (hybrid vs native vs whatever).

* System updates - what? I'm still on JDK 11? WTF? Why aren't you on the current versions? We need to update pronto, because there's too many security issues we'll get dinged on!

* UI - I need to be a CSS master, and if I'm not already on the tailwind bandwagon, I risk losing my job. Or... at least, I'll fall behind as I try to incorporate the new tailwind UI work the new person did because they couldn't be bothered to learn bootstrap 5. And... accessibility - need to be an expert in that.

* Deployment - hey, I now need to be able to understand multiple deployment approaches and processes, be fluent in docker/k8s and various tools, be able to troubleshoot these self-sufficiently. Doesn't matter if these are necessarily the right tools for the situation - someone else dictated this and lobbying for anything else means you're afraid to learn new things.

And... I should be cheery and helpful and positive about all of this being my responsibility. Because when I ask for folks from another team to help, I get told I need to 'own' the project, and I can't just 'throw it over the wall' and expect someone else to do something for me. If I push back on anything, I risk getting labelled "old" and "a dinosaur" and "afraid of change" and "unwilling to learn new things".

tldr - if you actually have teams of people with related yet diverse skills, consider letting each play to their strengths, help support them in their strengths, and organize around everyone doing what they're best at. The 'well rounded' thing has its limits.


And security


For sure. As someone who has stayed away from this part of the biz, infrastructure always looked like makework to me. Necessary, mind you, but still makework that was indicative of poor/insufficient computing primitives for services.

> it seems like JVM is experience a bit of a comeback with a few companies adopting Kotlin for backend

JVM 21 adding virtual threads, and Spring Boot 3.2 using them with one line of config is huge. We can now write simple code that looks blocking and let the runtime handle it instead of writing async function/await everywhere. Personally I'm loving Spring Boot 3.2 with Kotlin, especially for the fact that I can bundle scheduled jobs, API, and frontend all in one place for my indie projects. Plus the JVM world of devs seems to have a somewhat decent appreciation of how to make web services that aren't rife with unnecessary coupling.

The bad? There is a legendary amount of cargo-culting blog posts and questionable advice around Spring Boot, often for older versions.


> one of the biggest pain points is dealing with infrastructure

> We have no dedicated devops person

I understand that not every startup can afford an extra person for infra-heavy tasks, but this should not be surprising. Any tool which looks like an abstraction to you might get complex by time, and steal your time. The cloud was supposed to fix some of these, look where we are now.


I don't understand the reluctance to hire a system administrator. If you have two or more technical folks, at least one of them should be a sysadmin (or "devops" if you prefer). Pretending that it's an unskilled role that anyone should pick up reflects a poor understanding of the industry.


The "crappy bespoke cloud setup" is usually the result of people whose jobs are usually just regular app devs, but had been thrown into the infrastructure side head first. I think the key is to actually have someone who knows what they are talking about.

Unlike other people I don't think you need to hire someone directly. I do devops freelancing so you could hire someone like me. Or look online for various people that do it. I mean if its a toy app without many customers then who cares, but once you start scaling infrastructure gets to me more and more important.


Or you could just use an actual host running actual cron. No clicking, no terraform, just crontab -e. The last thing small short-staffed startups with no infra people should be doing is messing around setting up cloud infra to run something on a schedule.


Okay, but who's taking care of the actual host? I know this is HN and we're all server admin wizards, but there is some effort and maintenance required.

This is theoretically even easier than that. Yay for a spectrum of options!


That's an overblown problem, especially for a small business which is not going to have the infra problem of someone with scale problems.

We've just been sold lies that pushed us to buy expensive clouds - and are not that much simpler than good old tools


I agree that "it's way too much effort to ever consider running your code on your own servers / EC2 instances" is overblown, and has very much favored cloud providers.

But for the specific problem of "I wanna execute some code on a regular schedule, but I want it to be production-ready", Deno Cron does seem much quicker and lighter than provisioning a host, setting up health checks, setting up remote access controls for new devs, etc.

There are obviously many people who would find it very easy to do all the "server-work" I'm describing. I am not one of them! This service looks awesome to me.


It's not an option if you have more than one machine and you want the machines to be uniform. If they are not uniform means it's back to square one - bespoke setups. And then I want reproducibility across environments and environments that are easy to set up (for testing for example). Basically I think it's not an option.


Why does a small startup need several machines though?


> We have no dedicated devops person and much of that work falls on me and other people who would be better writing code. I think the cloud paradigm is experiencing a shift.

Part of that shift is that prior to the cloud, the development environment and production environments were very similar. By that I mean if a programmer could set up his debian / redhat laptop from the command line, then it wasn't a big jump to set up a server running debian / redhat in a production environment.

But no one in their right mind runs k8s on their laptop just to support VSCode and a compiler. Worse they could not run AWS/GCP because they are proprietary, insanely large, complex and forever changing. I'm pretty sure becoming an expert engineer in those environments is a full time job. The end result is a new class of engineers have arisen that look after the production side, and the developers just throw their code over the wall once it's tested.

I'm sure the cloud providers love this, as they have created a cohort of engineers that have invested years in learning their product, now have their wages dependent on that product being used within their organisation, and a total monopoly over that product because it can never be reproduced by anyone else. But for the industry as a whole, it looks to be a backward step. Once the problem expands beyond what a single human mind can cope with, you need teams. The communication overhead of a team means they don't have a hope of being as productive as a single person.

The share amount of complexity introduced by these proprietary cloud frameworks looks to be unnecessary. Most of it smells like technical debit created by organic growth together with an insistence on backward compatibility (don't want to give those locked in customers an excuse to move). And desktop OS's are (Debian / Windows / ...) are insecure by design, at least when compared to their phone brethren. And, their phone brethren look somewhat like cloud designs now, Phones have isolated apps with private data areas. The apps communicate via channels provided by the OS, and the availability of those channels is controlled by permissions assigned by the user. In the cloud we isolated things for performance as they could run on distance machines, whereas in a personal device we did it for security. But the end result looks similar.

So maybe one day we will end up where we started, with a developer environment looking like the cloud we deploy too. I fear I'm too old to experience if / when it does happen, but it does seem like something we should aspire to.


For cron jobs in Elixir you can use:

- [0] Quantum, quite simple and supports cron syntax.

- [1] Oban, which is a job runner, requires a DB, but also supports periodic jobs with a cron syntax.

(probably others but that's the ones I've used)

[0] https://github.com/fanduel/quantum-elixir

[1] https://github.com/sorentwo/oban


There's a good argument to make that you should never use your application code for running tasks better handled by infrastructure. Eventually you will want an operations team of some kind and they will absolutely hate you for doing this.

It doesn't scale, organizationally speaking. Logic? write it in app code sure. How it's triggered or runs? Probably don't go near that. Use your job scheduler (CRON) or cloud infra to do it. Your operations team can port it, scale it, and cost optimize it without breaking a sweat.

If more sysadmin / DevOps are hired to help they are going to roast your development team if they can't actually help you. Elixir may be able to glide by some of this given how flexible its process model is - but it's not good general advice.


Doesn't make any kind of sense to me. It might be best practices, but if you can automate things, you should be doing it. And the best automation happens behind a great abstraction.


There’s a new crop of PaaS products that aim to provide a layer of sanity on top of cloud providers (e.g. Aptible). Might be a good fit for you.


> 1. Services like this cron with Dyno Deploy or Vercel where the cloud things are abstracted away for you.

I agree with the sentiment, but to me it’s a shame this even qualifies as abstraction in the first place. Periodic execution of a function is extremely basic and already exists in almost every programming environment. If this needs to be a service (instead of a library call), there is something deeply wrong elsewhere, imo. We all laughed about leftpad, but at least that was native code and not “as-a-service”, dependent on networking and proprietary code on someone else’s machine.

I have nothing against Deno in particular, and I’m also not saying this is easy from an implementation perspective (due to complexity elsewhere). I’m just surprised that trivial features – from an end-user perspective – justify such a ruckus.


> Periodic execution of a function is extremely basic and already exists in almost every programming environment.

Periodic execution is surprisingly complicated. What happens when your node is down when it was supposed to execute and then comes back up? What happens around timezone changes and leap years? What does this thing do if a run takes so long that the previous run is still going? How do you get logs/notifications if it fails?

"Best effort" periodic execution is super easy, where you try to make a thing happen every period but it's okay if it doesn't happen as long as it does happen at some point in the near future (i.e. periodic clean up jobs, or maybe batch emails).

There's also a salient argument that you shouldn't run things inside the same process/VM if you can avoid it. It'd be a real shame if the production app went down because the cleanup cronjob went haywire and choked out the CPU.


I am a big fan of avoiding service proliferation and cloud complexity, and just making really good use of the facilities provided by your language and OS of choice.

But for exactly the reasons you outline, scheduling jobs is one of the few things where i would be eager to use some reliable, observable, carefully-engineered service.


> What happens when your node is down when it was supposed to execute and then comes back up?

If you want at-least-once scheduling you’d probably use a library that writes a last-completed time to your db.

> What happens around timezone changes and leap years?

For wall-time scheduling you’d need to handle it, yes. Why would a service be better than a library though?

> What does this thing do if a run takes so long that the previous run is still going?

I think we’d need either another db entry or simply prevent overlap directly in the library.

> How do you get logs/notifications if it fails?

Same way as other things in your app that fails I guess. Perhaps logging a critical event?

If you’re talking about external health monitoring then yes, you’d need to have a separate service by definition, preferably with a completely different provider/host.


Scheduled actions on a scalable deployment aren't straight forward, unless you just want all your live instances to run the scheduled actions at the same time in parallel. You'd need the instances to coordinate with each other to make sure they aren't redundantly running the same actions, and you might need to scale the number of instances based on the scheduled actions. (Consider the case where the service is scaled down to 0 live instances, or where all the instances are busy with load and you want more instances to come up to deal with the scheduled actions.) In this case, you want cron handled by something aware of all your instances and can scale them (or you want it running outside of your scalable deployment and have it hit your load balancer which is aware of all your instances and can scale them, etc).


I wonder why more people don't just set up a cheap VM and run this sort of thing via crontab.


The same reason why most people stopped manually editing some random files via FTP to do deployments: to get a proper reproducible, automated and monitored production environment.


I think there's a threshold below which this is just unnecessary infrastructure overhead, and I'd posit that most cron use cases fall below this threshold. If yours is above it, well and good.


Cloud setups are not reproducible, because you cannot reproduce the same env locally or in the other cloud.


Does crontab on a self-managed VM guarantee at least once delivery? For many, if not most, use-cases that guarantee is critical.


No. But I don't think there's any environment out there that is going to 100% guarantee that your cron succeeds. Even if it is reenqueued on failure, it could just keep hitting the same problem and crashlooping. You still need some kind of failure reporting, and a human to jump in to fix whatever went wrong.


Because managing servers adds a lot of tech overhead (OS and security updates/access control/disk/HA/monitoring) + provisioning/config + deployment.

That said, there will be a time when your SaaS costs more than managing infra.


crontab is just the schedule, there's a bunch of job handling missing. systemd timers get a bit closer and are worth learning for those that still touch actual Linux machines.


I think this is where modern PHP (8.0+) has its strengths.

Its well known how to deploy. Its easy to deploy. The footguns are vigorously and thoroughly documented. The frameworks (Symfony, Laravel) are good. They all have a solution for X (be it queues, async work, cron jobs etc) and they have turn key deploy solutions favored by their respective communities.

Its honestly one of the easiest languages to deploy with nowadays, in my estimation. Rivaled only by C# / F# or platforms like Deno Deploy or Cloudflare workers. Sometimes the most boring / mature thing is the best thing.


PaaS

Sounds like you’d like to use a PaaS provider.

Heroku/Render/Fly/etc.


There is a collection of new tools trying to address this exact problem such as Nitric, Winglang and Ampt for example. (disclaimer, I work on Nitric)


+1, as someone whose company has a crappy bespoke cloud setup that's a massive time sink


> Honestly, I have never been a fan of managing services in AWS/GCP/etc - the setup overhead rarely seemed to outweigh the pros

I just `ssh` into prod and `git pull` and either `docker compose up` or `kubectl apply` or `terraform apply` or `helm update` or `argocd sync`


Okay, this is either really good satire, or you are wildly overestimating the average startup engineer's knowledge of each of those tools and their configurations


The AI-generated imagery at https://deno.com/blog/cron/cover.png is actually painful the longer you look at it. The multiple watch hands might be an artistic effect, but the clock lacks the tenth hour and has two elevenths, the dinosaur's legs make absolutely no sense, and the water reflections show a different pattern on the dinosaur legs and a completely different set of clock hands than what is visible above.

I know that displaying artwork is not the point of the article, but please, at least make it believable when you look at it for more than one second.


Yes, by all means, make sure that the dinosaur wearing a clock around his neck looks believable. I'd hate to see something ridiculous.


I'll take this bait :) why do dinosaurs that can read and create clocks have two elevens on the clock face (instead of one ten and one eleven)?


It's hard to ignore when it takes up my entire screen and I have to scroll to see anything else. AI artwork is popping up everywhere and I don't think it looks as cool as people seem to think. It comes off incredibly tacky.


Perhaps bad AI art will go down as a tacky nostalgia, the "'under construction' gif" of their time


No, we'll just wait for it to get better... all of those critiques are solvable by future iterations of AI tooling, at least for generic blogpost headers, where the alternative is usually some other generic stock photo or nothing at all. Rarely is human ever involved in creating it new.


It's especially disappointing to see Deno doing this, because in the past they've used endearing art made by an artist, hashrock, which I liked very much.


Yeah, this guy (https://w.wallhaven.cc/full/x8/wallhaven-x8r18l.png) is much cuter...


I mean, it's a hero image above a technical article. What percentage of readers even did look at it for more than one second?

I thought it was awesome, even though it was pretty obviously AI-generated for the reasons you stated.


Right... also, the shadows on the mountains don't make sense if the sun is sitting behind the dinosaur (never mind that the sun is much too big, as you said, artistic effect). But as AI-generated images go, this is actually one of the better ones...


I was pleasantly surprised to see this, but it seems that the JS context in each run of the cron script is cloned so cron jobs are actually run in a separate "process".

Namely, I ran this example.

  let s = 0, r = 0;
  Deno.cron("Add second", "* * * * *", async () => {
    console.log(`Add second ${s++}`);
  });
  Deno.serve(async (_req) => {
    return new Response(`Seconds Running: ${s} / Number of requests: ${r++}`);
  })
Example deployed here: https://weak-stoat-26.deno.dev

So, effectively, it seems that Deno.Cron clones the JS context but any changes done to that context will not be reflected in the Deno.serve. And, if that's the case, why don't handle Cron jobs in a different flow rather than mixing them with Deno.serve? (I think it can lead to unintended side-effects)

I'd love if someone from the Deno team could provide more context here, maybe I missed something?


If you need to manipulate state - you should use Deno KV or some other persistent database. V8 isolates are created on-demand to handle Deno.cron and Deno.serve requests, potentially in different regions. You should not make assumptions that the same isolate will be used to handle all requests.


I love Deno, and it is because it usually avoids these kind of footgun situations. It is hard to grok that you can access those variables in the shared scope, but if you manipulate them, they are actually in completely different isolates. I understand architecturally why it is that way right now though.

I just wish there it was more obvious that you are really inheriting a fresh state somehow. Maybe only `const` should be allowed at the top-level? That still wouldn't handle objects really, but it'd be better than nothing.


I agree, this seems error prone. People do all kinds of crazy stuff with module variables, this is a big foot gun.

I’m all for making access to cloud services easier, but this screams product development not language development.


Is this really that surprising of a behavior, though? PHP apps threw away state after each request, and in the Node.js world data doesn't persist across server restarts or across instances of the app.

The only way I could see someone being confused about this is if they thought Deno Deploy was just a single VM running a single instance their code.


It is surprising behavior, because if the code can be accessed inside the scope, it is safe to assume that any modification to it will change the state, since it is still inside closure. If they throw `s++` with accessing undefined variable error, it will be much better. It'll be better if they can catch it during compile / validating / linting level.

And yes, PHP's behavior is surprising too. Unless we're doing scratch PHP without any classes or frameworks, any temporary variables become non-intuitive.


Kind the point of Deno Deploy is that you never have to think about a unit like a VM or container.

The runtime shouldn’t allow you to mutate variables in a parent scope. It probably shouldn’t allow any shared context at all. Because it isn’t actually doing that.

Everything should be passed into the cron function as an argument. It seems like this should be more like the interaction with web workers where those clearly execute in their own context.


> The runtime shouldn’t allow you to mutate variables in a parent scope. It probably shouldn’t allow any shared context at all. Because it isn’t actually doing that.

What you're proposing alters the semantics of JavaScript-the-language, which is outside the scope of the Deno project. Pretty much everyone is already in the habit of avoiding variables in the global scope. Why should they go to the trouble of redefining the semantics of JavaScript for something that is already widely understood?


`Deno.cron` isn't JavaScript-the-language. It is part of a runtime. They could implement this in a different way. Just like how Web Workers still just use JavaScrip-the-language, but within a different execution context than `<script>`.


I like a lot of what Deno does, but I'm having some trouble understanding why this (along with Deno's KV and Queues offering) is part of the Deno runtime.

The blog post touts this as a feature to reduce the amount of code to get up and running, but a library would accomplish the same thing. A first-party library could even directly integrate with Deno Deploy in the same way that this appears to.

Why pollute the runtime with something unrelated?


What makes jobs "tricky" is that jobs are--by definition--entirely side-effects.

So: - What happens if the process where you called the job crashes? - What happens if the entire application crashes? - What happens if two threads/processes schedule the same job? - Should jobs be stored in memory? On disk? In a db?

Are all sort of interesting questions. Presumably the Deno runtime deals with this in a way that's opaque to the user, but that using "a library" does not, especially in a language like Javascript where processes/jobs are not really first-class.


>Why pollute the runtime with something unrelated?

Because money.

They are venture funded and need to show some kind of path to profitability.


People acting like Bun, which is also ventured funded, isn't going to be doing a lot of similar things once they stabilize their runtime. Node had a lot of runway in the era/climate it was made in.


I also get the sense that Dahl ended up feeling slighted about his loss of control (see: ability to extract rent) of the Node ecosystem, and doesn't want to let that happen again. It feels almost quaint how open things were back then.


Interesting, didn't know that was a background intention


I think Ryan Dahl (creator of Deno and Node before that) is trying to make it stand out from Node which has a very small standard library. So they are including common things that used to be in many separate modules.


Great, but do they really have to leave the cron schedule format as the only option for specifying? It seems like a great idea if it's 1975 and you are dealing with limitations of that time. And I think it's good to keep it as an option.

But why not include any kind of schedule specifier that is a bit less cryptic and error prone? Is it really so much code?

Maybe someone has a package already that can wrap this or output a schedule from a human readable description or something. Maybe something like `human-to-cron`.


A JSON schedule format is coming soon: https://github.com/denoland/deno/pull/21340


This is something I like about in Laravel:

    $schedule->call(new DeleteRecentUsers)->daily();

    $schedule->job(new Heartbeat)->everyFiveMinutes();

    $schedule->exec('node /home/forge/script.js')->lastDayOfMonth('15:00');

    $schedule->command('foo')
       ->weekdays()
       ->hourly()
       ->timezone('America/Chicago')
       ->between('8:00', '17:00');

    $schedule->command('emails:send')
       ->hourly()
       ->days([Schedule::SUNDAY, Schedule::WEDNESDAY]);
https://laravel.com/docs/10.x/scheduling


As someone who has not seen this syntax before, it's OK. But, "timezone" shouldn't be a separate method, it should be a parameter to the function taking the time specification. Functions named as nouns should be named "onNoun" instead (onWeekdays, onDays). It's also very unclear what happens if I do something like ->daily()->weekdays() ("daily on weekdays") or ->weekdays()->lastDayOfMonth('15:00') ("on the last weekday of the month at 15:00").


While I agree with most if not all your points. Let's agree that "should" is a strong word for what is basically our opinion. These are all debatable.

For example:

- Prefixing everything with "on" adds noise. It's debatably intuitive enough as it is.

- Demanding timezone arguments on these methods also adds noise. More often than not you just want to use system default noise since it is such an important thing that you want to control at a higher level anyway.

- It can be okay to allow edge/confusing states if the tradeoff is to keep implementation simpler. One can always rely on unit tests to keep expectations in check.


The docs already link out to a cron string generator: https://www.npmjs.com/package/cron-time-generator


> How exactly does Deno Deploy know there’s a cron in your code, even when there’s no web server handling requests?

> When a new production deployment of your project is created, an ephemeral V8 isolate is used to evaluate your project’s top-level scope and to discover any Deno.cron definitions. A global cron scheduler is then updated with your project’s latest cron definitions, which includes updates to your existing crons, new crons, and deleted crons.

Having cron jobs defined in the code itself just feels weird. I get the convenience of doing things "in one place", but it's such an orthogonal concept. But I suppose combining things is part of the allure of deno any way.

Now that aside, the Flavor Flav dinosaur is the best thing I've seen all week.


Where better to put cron work? In another repo? If the cron jobs are 100% unrelated to the codebase, yeah, it might be weird. If the jobs are "run the foo() method every 2am"... having that info colocated with the foo() method itself makes a lot of sense, imo.


To me, it would depend on whether you always wanted to deploy the cronjobs with the codebase. I think I usually want the option to deploy them separately.

Just as an example, if you have 8 nodes or whatever, your cronjob is going to get updated when the first one is deployed, not the last. The other nodes may or may not support that cronjob until they get the update.

Going the other direction, if you have to roll back a single node for whatever reason, now you have conflicting cronjob versions.

I typically want those rollouts to be separate so that I can handle failures in the app deployment before I update the cronjob.


Just a normal yaml file...? Why go through the complexity of putting it in another codebase when you can just make a single config file?

There are probably some benefits of using the Deno.cron syntax for some functions, and benefits of using a config file for others, but acting like the only other option is "put it in a completely seperate codebase" doesn't make any sense to me.


Or even a crontab! You know, the thing that this is named after.


I think there are sensible reasons people don't like using unlabeled, whitespace-delimited formats that require an ascii-art diagram to explain in the modern day.


I mean this is just that same format but wrapped in a JavaScript method call, so I don’t see a huge difference.


You can put ordinary crontab into your repo.


That too - but keeping the items that deal with the code with the code seems simplest for most use cases.


Nice, I was just wondering if there was an opportunity for a product similar to vercel for batch jobs.

This isn't quite that but close.

From my experience there 5 main components for larger scale system.

- Request server

- database

- queue

- background worker

- offline batch jobs

I feel like so far serverless has the first 3 fairly well developed but the last two are still underdeveloped.

But maybe I'm just not aware of other solutions?


This is pretty much what Inngest is (https://www.inngest.com/). Runs on Deno as well.


Ingest is definitely nice. Its design is an orchestrator/scheduler where you offload your workers as serverless functions.

The only issue is for background jobs you need to design it in such way to not run in to timeouts.

Which makes it slightly more complex then just having a single executable running periodically.

There is also https://www.defer.run/ which run your code on their infra and don't have timeouts. But they only support node/bun at the moment.


We'll also be supporting long-running services as well in the near future which subscribe to updates from Inngest, rather than get invoked via HTTP.

Currently, to get beyond the ~5 min limit per step, you'd need to deploy to something non-serverless like Fly.io, Render, or your own instance running Express.js or similar.


This is really interesting - we’ve tried really hard to solve some of these with Bacalhau[1] - a much simpler distributed compute platform. Would love your feedback!

[1] https://github.com/bacalhau-project/bacalhau

Disclosure: I confounded Bacalhau


Huh, this is pretty cool.

I took a quick look through the docs and from what I understand you can just submit docker containers to be run on a cluster. The default one is a public cluster. In some way it seems similar to Google Borg.

What I don't understand though is do you have to pay? Who provides the compute?

Maybe possible to build a vercel type service on top of the private cluster where people can just submit their code?


Thanks! The idea is that it’s up to you - we offer a demo network, and there are ISPs who are interested in doing this privately, but the default is to allow you to trivially setup your own cluster (much easier and more maintainable than many cluster providers today - no hate! Just different)


That's exactly what windmill.dev is (https://windmill.dev)


EventBridge + Lambda or ECS gets you pretty far for the last two imo


But then you need to set it up. On small fast moving teams having something that just works from the code is a massive win and I'd rather not cross the infra/code barrier.


You should check Windmill.dev.


I will check out windmill. Though it does look somewhat complex.

One tangentially related is I'm looking for somewhere to just run a python script once a day.

I'll see if I can do that with windmill.


We have been using a self-hosted Windmill instance for running batch processes in Production for a while now. It has been a very nice upgrade from cron jobs for us (adding captured job outputs, status info, ability to re-run jobs, etc).


(disclaimer: Dev Advocate for Airplane)

Seems like that would be a good fit for Airplane's Schedules: https://www.airplane.dev/schedules.

It's pretty much as straightforward as deploying your Python script (and any dependencies with requirements.txt) and setting up your schedule for when you want it to run!


I will try this as well thank you!


Yes, you can do that quite trivially on WM.


I'd add a 6th one:

- workflow system


Check out temporal.io. It has support for schedules as well.


There is no doubt that this is a cool technical feat, but I don't think you'll catch me handling cron-like scheduling like this alongside application code.

I can see from comments like vvpan's that there is a fatigue around managing services in AWS/GCP/etc, but I have gone very much in the other direction in the last few years towards bare metal servers managed with NixOS. I feel much more confident in handling scheduled jobs on bare metal with Systemd timers than tying myself even deeper into a specific language+deployment solution ecosystem.


Not using something more intuitive than cron's schedule format seems like a missed opportunity.


This is being worked on: https://github.com/denoland/deno/issues/21122. Should be available with the next Deno release.


hey, andy from the deno team here. we're really excited to land this. happy to answer any questions or pass questions along to the team!


Why on earth would you copy Cron's incomprehensible syntax? You're writing code in a statically typed language! You can make a nice type checked API that actually is understandable without having to use one of the many many crontab generator UIs.

Crazy API design!

Edit: seems like there is a WIP typed API but I still have no idea why you would lead with the terrible one...


Is the spikiness of cron schedules going to cause you operational problems? You're going to end up with a _lot_ of jobs scheduled at "0 0 * * *".


Yes, we're anticipating more spiky workloads because of this. Deno Deploy is already designed to handle spikes, but we also have a few additional mitigations in place for Cron. For example, we will limit concurrent dispatches for the same project/user/organization, which may slightly delay the execution of specific cron tasks.


Charge 25% more for every 0 in the scheduling expression, problem solved :-)


Or add a default randomness factor that makes it run within a certain time (like 60s or 5m) of the target, perhaps with an additional charge to run at the exact time if people have that requirement.


I've been looking for something like this! Is it possible to run rclone to send Google Drive documents to an S3 compatible endpoint? (~20GB of files)


how does it works on self-hosted environment?


We're gathering more feedback for supporting self-hosted cron environment. Can you describe how you would use it?


Any plans for an SQL db service?


we've gotten a bunch of interest for this and the team is discussing it :)


Personally I would stay within your niche and focus on documentation, guides, and outreach to convert more people to your stack. A few simple but very reliable easy solutions is better than a lot of not great solutions.


use sqld (libsql)?


is there an API to receive the state of this and/or other cron jobs?


Not currently, but this is on the roadmap


Overlapping as an option would be nice, if I'm using cron to pull data to append to a database, and the append fails, I can normally retry. However, without overlap, I can't sit there doing retries since that will block future cron runs.

Timezones would be nice, "This helps avoid issues with time zones which observe daylight saving time." But it also causes issues with daylight saving time. I can't run something at 9 in the morning, I need to run it 1-2 hours before-hand, calculate the offset, and then queue a run 1-2 hours later. Or I can run 2 crons and have one or the other die early. Point being, all solutions become very hacky very fast.

It would be nice if an object was passed to the handler that had a targetDate for the ideal start time would be, so runs can be easily labeled and separated.

Yes I could round the Date.now() to the last minute, however, if Deploy ever goes over the minute boundary, that's all kaput.

In a similar vein: Systemd timers have some nice features, AccuracySec/RandomizedDelaySec/FixedRandomDelay, some options similar to that would be nice (of course, with minute resolution instead) (and of course, fixed delay can be pre-calculated, but it would be nice to just say 30m and have deno runtime manage that for me)

https://www.freedesktop.org/software/systemd/man/latest/syst...


When using Deno Deploy, which region does a cron job run in? Is there a way to configure it?


It currently runs in us-east by default. Specifying a region is on our roadmap.


Nice, years ago I wrote a TypeScript (originally CoffeeScript re-written to TypeScript) library to generate schedule times for a cron between two time points, should be easy to write a service like this with it.

https://github.com/romansky/JsCron


Vercel is it you? Seems like Deno Runtime is implementing what Deno Deploy would sell. While I understand it from a business perspective it totally makes me uninterested, I’d rather keep my dysfunctional marriage with AWS


How long does the job get to run?

Would be really awesome if this could be used to offload long lived jobs from the request.

Defer.run is building this for vercel and it’s really cool.


You can use Queues for this :)

https://deno.com/blog/queues


I wish this had a built in rate limit, I wanted to hit an api with lots of test data, I didn't need to actually wait for the response and I didn't really care how long they took.

I just needed to limit how fast the http requests went.

I guess I could do this with the delay and calculate how long it would need to wait.


I want to love Deno. It seems to really modernize TypeScript development. I just haven't had good experiences with it.

I spent a day or two migrating a TypeScript project [-1] over to Deno from NodeJS. Here's what I had to do:

* Change all of my local imports to something that would work with Deno. That meant appending `.ts` or `index.ts` for folders, except in some cases where Deno requires `.js`

* Modify my monorepo to play nice with Deno -- an import map does this easily. Deno has documentation around import maps, but I had to figure out the solution myself. Also, import maps are currently broken in JetBrains IDEs.

* Change my NPM imports to something that would work with Deno. The most straightforward thing to do was just change `import "foo"` to `import "npm:foo"`, but this felt hacky so eventually I used https://esm.sh, which worked for some packages but not others.

* Figure out how to get Lodash working with TypeScript. It's not simple. [0]

* Use a hack to get typeorm with sqlite working. [1]

* Try out `deno compile`, only to determine that it somehow works differently than `deno run`. My project simply wouldn't work with `deno compile`, probably because my project has some system dependencies that don't get properly linked/included.

* Setup my scripts to properly lint my project. Deno has formatting/linting built-in, but it's split across many commands with different usages. For example, I can run `deno fmt` to format my entire project, but I have to give Deno a path to run `check` or `lint`, e.g. `deno check src/index.ts `

* Patch a third-party library that was setting an HTTP header to `null`. NodeJS handles this case just fine, but Deno throws an error [2].

* Attempt to build my UI (astro + react) with Deno. It seems some people have gotten this partially working, but I gave up and stayed on NodeJS for building my UI. This led to me:

* Using dnt [3] to build a Deno package for consumption with NodeJS/npm frontend. This was actually surprisingly simple; kudos to the author of the dnt library.

After all of that work, I finally was able to use Deno in my project. It was really cool! Unfortunately, both VS Code and IntelliJ with Deno are essentially unusable [4]. Or, at least, unacceptably slow compared to what I had with NodeJS.

[-1]: https://github.com/shepherdjerred/glitter-boys/tree/sj/deno

[0]: https://stackoverflow.com/a/66073607

[1]: https://github.com/typeorm/typeorm/issues/6123#issuecomment-...

[2]: https://github.com/Sansossio/twisted/issues/97

[3]: https://github.com/denoland/dnt

[4]: https://github.com/denoland/vscode_deno/issues/895


Thank you for the detailed feedback. Deno 1.38.4 was just released with a partial fix for the VSCode issue you mentioned. We're fixing the twisted issue too.

https://github.com/denoland/deno/issues/21389 https://github.com/denoland/vscode_deno/issues/895

other fixes are being discussed.


yep, this is why i would stay far away for now, it's not NEARLY production ready

sure you can build and deploy something simply. the pain is felt when you try and actually use it on a real production app on a bigger codebase in a team. exactly as you wrote. the non-obvious but complete productivity-killing rough edges


Anyone here using Deno in a production workload? Genuinely curious about your experience.


It depends on what you mean by production! I am using Supabase in a hobby-level project that's "in production" (aka live on the internet). Supabase uses Deno to deploy functions. I am currently using Supabase functions (which are Deno Deploy functions) for both an API (interfacing with data not in a Supabase database) as well as some web-hook listener fuctions that keep Supabase accounts in sync with Stripe user IDs.

Overall, no issues or complaints. It's always a bit odd coming from npm/node into something like Deno, but the differences are really trivial. I believe Deno has become much more compatible with Node since I really had to update the project, so the differences are probably even smaller now.


Wrote similar when I was working on an API platform. Used http callbacks. https://m3o.com/cron/api#Schedule


This really seems to muddy the distinction between the data layer and the application layer. I'm sure they've put a lot of thought into this, but it seems like there could be some bizarre edge cases.


I love Deno. I’ve been playing with it for a long time now. But the fact that Deno Deploy still doesn’t have a “deploy” button but we’ve got cool crons just seems… backwards?


Does it work locally?



yes as of 1.38!


Would you mind showing how?


Wanted to ask the same, because didn't find it in the article


Have the team at Deno not heard of systemd timers?


I agree. "0 * * * *" to schedule something hourly is a poor for developer experience. systemd timers use a more human readable "hourly". "0 1 * * *" to run at 1:00 daily becomes "1:00". systemd timer calendar events read like actual timestamps.


This is pretty neat, I can see this maybe being useful for database cleanup/housekeeping, what other example use cases are there?


pulling from an API / scraping data, sending emails/notifications/reports, backing up databases/snapshots, checking availability of various services, pinging website, pre-warm up apps/scale applications, various maintenance tasks.


Excited to use this, nice work Deno team!


What I see is yet another way that the backend JS world is finally achieving something .NET had over 10 years ago[0].

Node/Deno/Bun/etc. + npm sounds super straightforward (and it is at first). But I've thought for years that it's far easier to be productive on the backend on .NET in Visual Studio, since it's simpler to design, deliver, and maintain infrastructure.

[0] https://www.hangfire.io/


To be fair, Visual Studio is completely optional (and subjectively much worse for publishing/deployment than using CLI).

Some developers are moving over to macOS with Rider + Visual Studio Code combo nowadays.


If you like this, Elixir will make your brain explode :)


Better to call it adenocron.


while this looks useful it certainly shows what they are most concerned about which is making money off their cloud service. I don’t think they have much interest in being a Node alternative anymore.


My first question when I am considering a product like this is how can I get an email when there's an error in my application. Why isn't that in the top level feature list of everything like this, or am I unusual in thinking that this is an essential feature of any hosting system?


I've started tossing https://ntfy.sh/ alerts into my Deno apps to get push notifications for things I'm interested in


My wife has had good luck using Pushover [1], which seems similar. I wonder how these services compare?

[1] https://pushover.net/


I actually use Pushover for a project but it just does the notification part and requires me to catch all errors and send them to Pushover. I'm looking for the hosting service to catch unhanded errors automatically



Pushover looks very similar to Ntfy, but I haven't tried it yet.


I think the answer to that is the same as the answer to "how do I send an email in Deno?", since this lets you run arbitrary code.

System level cron needs that feature built in because you're just telling it a command to run, and you're limited in how you deal with error and output handling of that command. That's not a problem when you're in the language you're using to define the action. Just catch your errors, or grab all STDOUT/STDERR with some solution and do with it what you want on success or error.


The downside is that when it has to be done on a job-by-job basis, you can’t rely on the cron system handling failure modes you didn’t anticipate.


It's code. There is not necessarily a single solution that makes sense. The thing you're calling could throw an exception, or it could return a failure value. If it fails, you may want to set off some extra routine that retries, or perhaps you want to handle some specific errors and retry or notify, but other errors are critical and cause failure, not just notification. Having it handle those automatically is not a feature in some cases, it's a problem.

System cron is simple, by design, because as a DSL there's a benefit to not complicating it. If you're already in Javascript/Typescript, a lot of the benefits of that are mitigated by the benefits of having much more control over exactly how it functions in every care.

As an example of this, there's a bunch of cron "helpers" to deal with the shortcomings of cron's simplistic approach, such as those in moreutils[1].

P.S. Personally I wouldn't have even called this implementation cron and use the cron syntax for it, since that just makes people assume cron usage and the cron scheduling format is not an asset if you're already in a language where you could just pass in a structure with the specific fields you want set by name.

1: https://rentes.github.io/unix/utilities/2015/07/27/moreutils...


Some hosting systems may support that out of the box but I don't know what they are. Typically you would use metrics, monitors and alerts and create a notification alert based on certain conditions. No reason they couldn't provide some out of the box, but it's not common. At the very least it would need to stop after a short number of alerts or they'd end up spamming customers if it crashes on a loop




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: