Why Does Stack Size Vary By Function (V8 Engine)?

I was just experimenting to see the max call stack size on my machine, and I discovered something very peculiar. I had the following two functions:

function fact(o) {
    if (o == 0) return 1;
    return o * fact(o - 1)
}
function k(o){
    if (o == 0) return;
    k(o - 1)
}

Calling fact(9644) is the highest number I can get to before a stack overflow. E.g., fact(9645) returns an error.

However, I can call up to k(10448) before I get a stack overflow. E.g., k(10449) returns an error.

I figured that the way in which I created my functions might affect the call stack size. So, I tried making fact a constant arrow function, and I tried changing it to a simple ternary evaluation, e.g.:

const fact = (o) => o == 0 ? 1 : o * fact(o - 1);
//OR
function fact(o) {
    return o == 0 ? 1 : o * fact(o - 1);
}

When assigning arrow functions, I also tried assigning them with let, e.g.:

let fact = (o) => o == 0 ? 1 : o * fact(o - 1);

I tried similar things with k. Results stayed the same no matter what I did.

(In case it matters, I’m running this in the Chrome Devtools console.)

Furthermore, after researching, I concluded that the V8 engine no longer does any tail recursion elimination, so I don’t think this could be the issue, either. But, please, correct me on this if I’m wrong.

So, my question is, can anybody tell me why this is happening?