Even in a single-host setup, it can be a problem because what happens if your process crashes and restarts just after a resource was created in the database but before the ID was sent to the client (with success message)? You would end up with a duplicate record in your DB after the retry since your newly restarted server would not have the UUID in its memory (even though the resource was in fact already created on the server a few milliseconds before the last crash).
With the Redis (or similar) solution, you need to make sure that the request UUIDs expire after some time and are cleaned up to avoid memory bloat which is a pain... I mean that complex solution probably uses up a lot more resources than just using UUIDs in the database as IDs.
If you add a column to store params as well then you can also do better validation:
> Responding when a customer changes request parameters on a subsequent call where the client request ID stays the same
> We design our APIs to allow our customers to explicitly state their intent. Take the situation where we receive a unique client request token that we have seen before, but there is a parameter combination that is different from the earlier request. We find that it is safest to assume that the customer intended a different outcome, and that this might not be the same request. In response to this situation, we return a validation error indicating a parameter mismatch between idempotent requests. To support this deep validation, we also store the parameters used to make the initial request along with the client request identifier.
https://aws.amazon.com/builders-library/making-retries-safe-...
One of the best things about UUIDs is that if your front end tries to create a resource and fails due to a bad connection, you can simply resend that exact same resource for creation again (with the same UUID) and you don't need to worry about duplicate records being inserted into the database since you would get an ID collision; it results in much simpler/cleaner code which is idempotent and deterministic by default.
With auto-incrementing IDs, if there is a connection issue or other failure, it's not possible to easily figure out if a resource was already created or not since only the database knows what the ID of that resource was; the client doesn't know it until the resource has been successfully created in the database and the ID was send back to the client.
Just because the client did not receive a successful response from the server, it does not mean that the resource was not created; and if it was, you cannot know since the client has no way of referencing that resource in a unique way. It just seems completely wrong that the client (which created the resource) cannot reference it until the database has inserted it.
It's a hack to pretend that resource creation starts in the database, when in fact, it starts on the front end.