In short: JavaScript’s setTimeout breaks after ~25 days. I made setBigTimeout, a silly module to get around this problem. See the package on npm or the source code.
setTimeout is JavaScript’s way of delaying code. You provide a timeout, in milliseconds, and a function to call after that time has elapsed.1
setTimeout(() => {
console.log("This runs after 2 seconds");
}, 2000);
So far, so good.
In most JavaScript runtimes, this duration is represented as a 32-bit signed integer. That means the maximum timeout is about 2.1 billion milliseconds, or about 24.9 days. That’s plenty of time for most people, but not for freaks like me. If you try to set a bigger timeout, weird things happen.
For example, if you try setting a timeout to 40 days, the function runs immediately.
const FORTY_DAYS_IN_MILLISECONDS = 3.456e9;
setTimeout(() => {
console.log("This executes immediately!?");
}, FORTY_DAYS_IN_MILLISECONDS);
This feels like a bug to me. Shouldn’t this wait 40 days?
Enter setBigTimeout, a cursed module I made to address this.
setBigTimeout works just like setTimeout2 but it can take very big delays.
import { setBigTimeout } from "setbigtimeout";
const EIGHTY_FOUR_YEARS_IN_MILLISECONDS = 2.65e12;
setBigTimeout(() => {
console.log("It's been 84 years...");
}, EIGHTY_FOUR_YEARS_IN_MILLISECONDS);
You can also pass bigint delays to delay things for an extremely long time:
const ONE_MILLION_YEARS = 31536000000000000n;
setBigTimeout(() => {
console.log("JAVASCRIPT WILL NEVER DIE");
}, ONE_MILLION_YEARS);
It does this by chaining multiple shorter timeouts together—timeouts that fit under the limit. A pretty simple solution, but it works.
…or at least I think it does. I wrote automated tests that mock the clock, but I didn’t wait 84 years to see if it worked.
Give it a try by installing setbigtimeout from npm or checking out the source code.