Yes, the offline UUID is generated based on their username, so it stays the same. The chance of a collision is rather low, it is assumed safe for identification. Internally, MD5 of the lowercased username is used for the offline UUIDs.
The non-blocking MojangAPI has not been implemented yet. There's even no issue for it on GitHub, I just created it:
https://github.com/cuberite/cuberite/issues/3640
Anyway, if you only query UUIDs of players who have already connected to your server, even the synchronous API is kinda safe, because the UUIDs are cached, so it returns the UUID from cache, rather than making a network request.
Theoretically, you could even implement the MojangAPI requests in your plugin using cNetwork or cUrlClient functions, but it's like "preinventing" the wheel
The non-blocking MojangAPI has not been implemented yet. There's even no issue for it on GitHub, I just created it:
https://github.com/cuberite/cuberite/issues/3640
Anyway, if you only query UUIDs of players who have already connected to your server, even the synchronous API is kinda safe, because the UUIDs are cached, so it returns the UUID from cache, rather than making a network request.
Theoretically, you could even implement the MojangAPI requests in your plugin using cNetwork or cUrlClient functions, but it's like "preinventing" the wheel