AFAIK, no: even if the recursive call was in tail position (which is not the case here), Julia does not perform automatic Tail Call Optimization.
However, it’s rather straightforward (at least in this case, but also in many others) to convert the recursion into a loop. In your example, this would yield:
julia> function f(x)
res = 1
for i in 2:x
res = sqrt(6+res)
end
res
end
f (generic function with 1 method)
julia> f(104475)
3.0
julia> f(104476)
3.0
The heavy lifting is done by IterTools.iterated(f,x) which repeatedly applies f on each iteration i.e. returns x, f(x), f(f(x))… This is wrapped by take from Base.Iterators which limits the items taken from an iterator. So starting with the innermost recursive call (in original recursive implementation), the value of x is 1.0 and then f is applied until the last time when the iterator value is similar to the recursive call output.
Finally, taking the last value of the iterator is not as simple as last(itr) alas, so foldl is used to discard all but last element.