As reported on T88915, Parsoid goes into an infinite loop with e.g. [[Template:CircularRef]] containing "<ref>{{CircularRef}}</ref>". This is because Parsoid lacks circular template reference checks.
If there is no <ref>, then Parsoid is protected by the fact that MW's Parser::preprocess() will mangle invocations of circular references. But MW does not guarantee the absence of circular references in its output.
Note that there is no API call inside the loop . After the first iteration, further expansions hit Parsoid's pageCache.