1) exposing in URLs (you can't scrape all data by iterating over IDs)
2) passing them around between microservices/systems (less confusion where an ID comes from when debugging/doing tech support, because you can check the ID in a few tables and be 100% sure that's exactly what you are looking for, because IDs are globally unique, unlike bigints)
3) useful in situations when data from several servers or DB shards is eventually aggregaged in one place (for example, for analytics) - with bigints you'd have collisions
Whether you should do anything else before the data has been persisted is a totally different discussion.
If you are doing async writes, as you alluded to, why bother with RDBMS in the first place? ACID is out the window.
- insert/then retrieve ID can easily result in duplicate records in some edge cases, and won’t necessarily be able to be easily fixed either. the inserted record doesn’t have a global ID until it’s inserted.
Can this generally be fixed using good transactions semantics? Yes usually. But it’s expensive. And in many cases you’ll have to default to failing writes instead of eventually consistent behavior.
- CRDT type behavior works better when things have a known valid unique ID from the get go. insert/update/ignore can happen quickly and easily without two way communication and in bulk, and edge cases have more easily modelable ‘eventual consistency’.
- generating unique IDs in the database forces serialization of certain processes in the database, which can cause scaling issues and high latency.
For instance, using the DB to create unique request IDs for web or API requests? Asking for problems.
Generating UUIDs for them at request time, and then putting those IDs where needed when later correlation/tracking is desirable? Much better.
Same can apply for other object ID creation, when there aren’t other natural keys that need to be checked first.