UUID package coming to Go standard library
github.com215 points by soypat 9 hours ago
215 points by soypat 9 hours ago
> UUID versions 1, 2, 3, 4, 5 are already outdated.
Interesting comment, since v4 is the only version that provides the maximal random bits and is recommended for use as a primary key for non-correlated rows in several distributed databases to counter hot-spotting and privacy issues.
Edit: Context links for reference, these recommend UUIDv4:
https://www.cockroachlabs.com/docs/stable/uuid
https://docs.cloud.google.com/spanner/docs/schema-design#uui...
Yeah v4 is the goto, and you only use something else if you have a very specific reason like needing rough ordering
Really? Doesn’t v4 locally make the inserts into the B-Tree pretty messy? I was taught to use v7 because it allows writes to be a lot faster due to memory efficient paging by the kernel (something you lose with v4 because the page of a subsequent write is entirely random).
https://www.thenile.dev/blog/uuidv7#why-uuidv7 has some details: " UUID versions that are not time ordered, such as UUIDv4 (described in Section 5.4), have poor database-index locality. This means that new values created in succession are not close to each other in the index; thus, they require inserts to be performed at random locations. The resulting negative performance effects on the common structures used for this (B-tree and its variants) can be dramatic. ".
Also mentioned on HN https://news.ycombinator.com/item?id=45323008
In distributed databases I've worked with, there's usually something like a B-tree per key range, but there can be thousands of key ranges distributed over all the nodes in the cluster in parallel, each handling modifications in a LSM. The goal there is to distribute the storage and processing over all nodes equally, and that's why predictable/clustered IDs fail to do so well. That's different to the Postgres/MySQL scenario where you have one large B-tree per index.
v7 exposes creation date, and maybe you don't want that. So, depends on use-case
A slow day in Go-news land? :)
It is heathwarming to see such mundane small tech bit making front page of HN when elsewhere is is debated whether programming as profession is dead or more broadly if AI will be enslaving humanity in the next decade. :)
It’s nice to have a break from AI FUD. It reminds me of a time when I could browse HN without getting anxiety immediately, because nowadays you can’t open a comment section without finding a comment about how you ngmi.
Well fortunately you’re here to take what was a discussion completely unrelated to AI and drag it back around to AI again.
If you’re tired of talking about AI, why did you post this?
Man... I spent the last 6 months writing code using voice chat with multiple concurrent Claude code agents using an orchestration system because I felt like that was the new required skill set.
In the past few weeks I've started opening neovim again and just writing code. It's still 50/50 with a Claude code instance, but fuck I don't feel a big productivity difference.
I just write my own code and then ask AI to find any issues and correct them if I feel it is good advice. What AI is amazing at is writing most of my test cases. Saves me a lot of time.
I've seen tests doing:
a = 1
assert a == 1
// many lines here where a is never used
assert a == 1
Yes AI test cases are awesome until you read what it's doing.
To be fair, many human tests I've read do similar.
Especially when folks are trying to push % based test metrics and have types ( and thus they tests assert types where the types can't really be wrong ).
I use AI to write tests. Many of them the e2e fell into the pointless niche, but I was able to scope my API tests well enough to get very high hit rate.
The value of said API tests aren't unlimited. If I had to hand roll them, I'm not sure I would have written as many, but they test a multitude of 400, 401, 402, 403, and 404s, and the tests themselves have absolutely caught issues such as validator not mounting correctly, or the wrong error status code due to check ordering.
Yep. Especially for tests with mock data covering all sorts of extreme edge cases.
Don't use AI for that, it doesn't know what your real data looks like.
Majority of data in typical message-passing plumbing code are a combination of opaque IDs, nominal strings, few enums, and floats. It's mostly OK for these cases, I have found. Esp. in typed languages.
There has always been a difference on modality and substance.
This is the same thing as picking a new smart programming language or package, or insisting that Dvorak layout is the only real way forward.
Personally I try to put as much distance to the modality discussion and get intimate with the substance.
> voice chat ... required skill set
But we're still required to go to the office, and talking to a computer on the open space is highly unwelcome
Really? The past two weeks I've been writing code with AI and feel a massive productivity difference, I ended up with 22k loc, which is probably around as many I'd have manually written for the featureset at hand, except it would have taken me months.
A lot of people‘s business model is to to capitalize on LLM anxiety to sell their PUA-tier courses.
One thing I love about Go, not fancy-latest-hype features, until the language collapses or every upgrade becomes a nightmare, just adding useful stuff and getting out of the way.
Odd to me that the focus seems to be on the inactivity of Google's package when https://github.com/gofrs/uuid not only conforms to the newer standard but is actively maintained.
I get a kick out of publishing libs with no external deps. Regardless of reasoning, this change makes that easier.
While the uuid package is actively maintained, it hasn't had a release since 2024. Indeed, there's an open issue from June 2025 asking about it: https://github.com/google/uuid/issues/194
The RFC isn’t changing, is it?
I’m not sure of the state of that particular library, but yes, the RFC has changed significantly. For instance, the UUIDv7 format changed from the earlier draft RFC resulting in incompatibilities.
This is an example of an unmaintained UUID library in a similar situation that is currently causing incompatibilities because they implemented the draft spec. and didn’t update when the RFC changed:
https://github.com/stevesimmons/uuid7/issues/1
Any Python developer using the uuid7 library is getting something that is incompatible with the UUIDv7 specification and other UUIDv7 implementations as a result. Developers who use the stdlib uuid package in Python 3.14+ and uuid7 as a fallback in older versions are getting different, incompatible behaviour depending upon which version of Python they are running.
This can manifest itself as a developer using UUIDv7 for its time-ordered property, deploying with Python <=3.13, upgrading to Python 3.14+ and discovering that all their data created with Python 3.13 sorts incorrectly when mixed with data created with Python 3.14+.
A UUID library that is not receiving updates is quite possibly badly broken and definitely warrants suspicion and closer inspection.
Alternative take: don't put draft RFCs into prod
It hasn’t been a draft RFC for a couple of years:
https://datatracker.ietf.org/doc/rfc9562/
The problem is not that it is a draft RFC, the problem is that the library is unmaintained with an unresponsive developer who is squatting the uuid7 package name. It’s the top hit for Python developers who want to use UUIDv7 for Python 3.13 and below.
The problem here is a lack of namespaces. A problem the cargo bozos decided to duplicate
There have been committed 3 new features and a seemingly significant bug fix since the last release: https://github.com/google/uuid/compare/v1.6.0...HEAD
If the library just existed as a correct implementation of the RFC without bugs or significant missing features, that would be one thing. But leaving features and bug fixes already committed to the repository unreleased for years because the maintainer hasn't cut a new release since 2024 is a bad sign.
RFC changes aside, the go community has been bit by unmaintained UUID libraries with security issues. Consider https://github.com/satori/go.uuid/issues/123 as a popular example.
The open issue in Google's repo about the package being malicious is not a good look. The community concluded it's a false positive. If the repo was maintained they'd confirm this and close the issue.
Maintaince is much more than RFC compliance, although the project hasn't met that bar either.
Kotlin also added RFC 9562 (which includes the new UUID versions) support to the standard library in version 2.3 recently. It's a multi platform implementation too so it works on native, wasm, jvm and js. I think it makes a lot of sense to default to that now that the IETF RFC has been out for a few years.
So, it makes sense for Go to introduce support for this as well.
UUIDs are one of those useless things standards people create so they can plop it in other standards. They don't, have never and can never solve a real problem, only hypothetical meta problems. That Go team probably sees UUID v7 and LOL'd their underpants off, you couldn't get it right the first 6 times? GTFO
Based on the conversation, is it actually coming?
It's currently listed as a 'Likely accept' https://github.com/orgs/golang/projects/17/views/1
Generally means it'll be going in unless something new comes up which alters people's thinking.
Golang lack of support for basic stuff like this is quite annoying.
What's the language you're thinking of that has more of these decisions fixed in the standard library? I know it's not Ruby, Python, Rust, or Javascript. Is it Java? I don't think this is something Elixir does better.
Perhaps I’m misunderstanding, but the linked issue seems to address this directly:
> Would like to point out how Go is rather the exception than the norm with regards to including UUID support in its standard library.
> C#: https://learn.microsoft.com/en-us/dotnet/api/system.guid.new...
> Java: https://docs.oracle.com/javase/8/docs/api/java/util/UUID.htm...
> JavaScript: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/rand...
> Python: https://docs.python.org/3/library/uuid.html
> Ruby: https://ruby-doc.org/stdlib-1.9.3/libdoc/securerandom/rdoc/S...
You're answering the question of "which languages have UUIDs in their standard libraries" (Javascript is not one of them). That's not the question I'm asking. If you wrote a new Python program today that needed to make HTTP requests, would you rely on the stdlib, or would you pull in a dep? In a Java program, if you were encrypting files or blobs, stdlib or dep?
Is C# the language that gives the Go stdlib a run for its money? I haven't used it much. JS, Python, and Ruby, I have, quite a bit, and I have the sprawling requirements.txts and Gemfiles to prove it.
I asked the question I did upthread because, while there are a lot of colorable arguments about what Go did wrong, a complete and practical standard library where the standard library's functionality is the idiomatic answer to the problems it addresses is one of the things Go happens to do distinctively well. Which makes dunking on it for this UUID thing kind of odd.
> If you wrote a new Python program today that needed to make HTTP requests, would you rely on the stdlib, or would you pull in a dep?
For a short script, the standard "urllib.request" module [0] works pretty well, and is usually my first choice since it's always installed. For a larger program, I'll usually use a third-party module with more features/async support though, but I'll only do this if I'm using other third-party dependencies anyways.
> JS, Python, and Ruby, I have, quite a bit, and I have the sprawling requirements.txts and Gemfiles to prove it.
I checked the top 10 Go repositories on GitHub [1], and all but 1 of them have 30+ direct dependencies listed in their "go.mod" files (and many more indirect ones). Also, both C and JavaScript are well-known for their terrible standard libraries, yet out of all languages, JavaScript programs tend to use the most dependencies, while C programs tend to use the least. So I don't think that the number of dependencies that an average program in a given language uses says anything about the quality of that language's standard library.
Just claiming you'd use urllib is a concession. Yeah, I get it: for toy programs, you'd use the stdlib's HTTP.
That's not what happens in Golang.
Fair enough, but the quality/breadth of the standard libraries is fairly topic-specific in Go (and all languages, really). There's a reason that you picked networking and crypto for your examples, since the Go standard library is indeed really strong here—I don't even like Go, but if I had to write a program that did lots of cryptography and networking, then Go would probably be my first choice.
But lots of programs (and most of the programs that I write) don't use any cryptography, and only have trivial networking requirements, and outside those areas, I'd argue that the Python standard library [0] has broader coverage, supports more features, and is better documented than the Go standard library [1].
The Go standard library is still pretty great though, and is well ahead of most other languages; I just personally think that it's a little worse than Python's. But if you mostly write networking/crypto code, I can easily see how you'd have the opposite opinion.
Like, at this point, I feel like we share premises. We disagree, but, fine, seems like a reasonable disagreement. A better one than how annoying it is that Golang lacks "basic stuff" like a standard UUID interface.
[flagged]
I gave that example to refute the point that having worked on projects in other languages with tons of third-party dependencies implies that those languages have poor standard libraries. I certainly didn't intend to imply that that means that Go has a poor standard library or that small Go projects often use hundreds of third-party dependencies like JavaScript projects tend to do.
Go's package management is actually one of its strongest points, so I think that it's unsurprising/good that some projects have lots of dependencies. But I still stand by the point that you shouldn't judge a language based on how many dependencies most programs written in it use.
(Except for JavaScript, where I have no problem judging it by the npm craziness :) )
No one is debating whether Go is missing a uuid package from its standard library; the debate is about whether this is indicative of a general trend with the Go standard library (as the gp claimed above).
If you’re arguing as the grandparent did that Go regularly omits important packages from its standard library, then it’s not unreasonable to ask you for your idea of an exemplary stdlib.
My first, and primary, programming language was C# which includes probably too large a standard library. It was definitely a surprise to see how minimal/simple other standard libraries are!
Like Python though, while the batteries are included, many of them are dead.
It begs the question, why don't these languages put out a v2 stdlib?
Broadly speaking, maintaining a big std lib is a huge amount of work, so it makes sense that a language team is conservative about adding new surface to a stb lib which they will then have to maintain for a long time.
Why it is "huge amount of work" ? Do the code reliably breaks in every new python version ?
Yes, in python they break something at every release now. It's terrible. It mostly is because they remove modules from their standard library for no good reasons.
For example they've removed asyncore, their original loop-based module before the async/await syntax existed. All the software from that era needs a total rewrite. Luckily in debian for now the module is provided as a .deb package so I didn't have to do the total rewrite.
edit: as usual on ycombinator, dowvotes for saying something factually true that can be easily verified :D
I think the downvotes are because you did not answer the question you replied to, and instead gave a pretty unrelated rant.
Yes because the formats and protocols they are for have changed so much right? -_-'
the idea of what 'batteries included' means has changed a lot in the past twenty years, and like most Go quirks , probably Google just didn't need <missing-things>.
Huh? The universal idiomatic answer to "how to use UUIDs in Go programs" for the past decade has been to pull in a Google dep.
Google is the author of the de facto uuid library in Go, google/uuid. I’m very curious what people think is an exemplary “batteries included” stdlib?
UUID is just array of 16 bytes or two 64-bit ints. Generating UUIDv4 is like few lines of code. Is that a big deal? I don't think so.
16 random bytes is not a valid UUIDv4. I don’t think it needs to be in the standard library, but implementing the spec yourself is also not the right choice for 99% of cases.
Well that depends on your luck, it could be a valid one about 1/16th of the time.
1/64, actually, because RFC-compliant (variant 1) UUIDv4 requires fixed values for both the version nibble and two bits of the variant nibble.
The fact that we're discussing this at all is a reasonable argument for using a library function.
Let's call it a valid UUIDv0 - all bits randomized including the version bits :)
I think it saves labor and eventual bug hunting to include these in a stdlib. We should not be expected to look up the UUIDv4 spec and make sure you’re following it correctly. This feels like exactly what reasonable encapsulation should be.
It makes you look on GitHub for implementations, which later can be hijacked and used for malicious reasons
Go has one of the best stdlibs of any language. I'd go as far and say it's the #1 language where the stdlib is the most used for day to day programming. cut the bullshit
Open the python documentation if you're curious of why people are downvoting you.
I don't buy this for one moment. Python and breaking changes are lovers. Nobody I have ever worked with builds or tries to build stdlib python. Most Go devs to pride themselves on minimal dependencies.
Go is often the best part of my work day.
Every time I've implemented UUID's it's for a database and something like PostgreSQL would handle it. Still glad to see this feature being worked on, I would have utilized a random string generator instead of the full battle tested UUID specification.
what a bunch of drama in the comments.
It’s kind of ridiculous to argue against UUID being part of the standard package for a language largely aimed at servers. At that point why even have any crypto functions or any of the bigger stuff it already has if the argument is 3rd party libs are enough?
UUIDv7 didn't mature until long after the Go standard library was mostly settled. By that point, there was already an idiomatic 3p dep for UUIDs (the Google package), and as you can see from the thread, there were arguments in favor of keeping it 3p (it can be updated on an arbitrary cadence, unlike the stdlib).
They could have implemented the other types of uuid generation, as well as having the standard type. Then evolve.
UUIDs rarely get new versions. I don’t think it’d be too much to expect Go to stay relatively current on that.
People are weird. A few days ago someone on /r/Java was arguing that a basic JSON parser shouldn’t be in the standard library.
Anecdote: about 8 years ago, I was interviewing hundreds of candidates for a non-java shop but you could interview in java if desired. One java dev ever was able to figure out parsing json with ease. Every single other java interview the person struggled with json. It was weird.
Adding UUID to the standard library is defensible for a server-focused language, but making it part of the stdlib binds maintainers to long-term compatibility and support, so the debate should focus on API surface and long term maintenance rather than whether third-party packages exist.
If added, keep the scope small: implement RFC 4122 v4 generation using crypto/rand.Read with correct version and variant bit handling, provide Parse and String, MarshalText and UnmarshalText, JSON Marshal and Unmarshal hooks, and database/sql Scanner and Valuer, and skip v1 MAC and time based generation by default because of privacy and cross-platform headaches.
Basically one guy having a fit when people disagreed with him.
It would appear that person and OP are one in the same.
Damn. I missed that. But yeah OP didn't take it well when people poked hole into his proposed API.
But regardless of API ergonomics, I would love to have UUID v4 and v7 in the stdlib.
maybe the OP is trying but failing to drum up support for his unergonomic api proposal
Am I the only one who hates UUIDs and doesn't see the point of them?
Having any structure whatsoever in them is pointless and stupid. UUIDs should be 128 buts of crypto.Rand() and nothing else.
Argh.
UUIDs are recognizable, have a version field, can be sorted in the case of UUIDv7, a standardized format means easy interoperability (eg, encoding, validation, serialization etc), and databases can optimize storage and efficiency when using a native UUID type.
If just using random bytes, you still need to make decisions about how to serialize, put it in a URL, logging etc so you’re basically just inventing you’re own format anyway for a problem that’s already solved.
That the problem is already solved does not mean the solution is good. Or that you can’t solve it better.
A uuidv4 is 15.25 bytes of payload encoded in 36 bytes (using standard serialisation), in a format which is not conducive to gui text selection.
You can encode 16 whole bytes in 26 bytes of easily selectable content by using a random source and encoding in base32, or 22 by using base58.
I treat UUIDv4s as 128 random bits and it triggers ppl.
To be fair that’s literally just a waste of resources. If you want 128 random bits just get 128 random bits from the underlying source, unless your host langage is amazingly deficient it’s just as easy.
they should be prefixed with something human readable so you can tell a service bot api key from a human developer api key or whatever.
hahahaha as if humans wouldn't just give their hey to the bot
That misses the point. The point is for easy validation that the key was generated appropriately. Many api keys have a standard prefix for just this reason. It especially helps on documentation where the key name might be confused with the value: "your key starts with hnkey-"
I hate UUIDv4, don't care about the rest. UUIDv4 is just random bytes with hyphens inserted in random places and some bytes reserved to indicate that this is in fact a UUID. This is wasteful and stupid
You aren't supposed to store the hyphens, and that's the same for all versions.
What if I want an ID in the URL? Parse it back and forth? And what if for example, nodejs's UUID api only gives me the string representation of the ID?
To minimize the storage space while having a URL-safe representation, yeah you'd want to serialise/deserialise on the boundary of presenting it to API consumers. I think the same for any ID that has an efficient binary representation as well as needing to represent it in ASCII.
UUIDs aren't random by design, and the structure is not pointless. Calling something you don't understand "stupid" is probably not a good approach to life.
One example where UUIDs are useful is usage as primary keys in databases. The constraints provide benefits, such as global uniqueness across distributed systems.
The global uniqueness of a uuid v4 is the global uniqueness of pulling 122 bits from a source of entropy. Structure has nothing to do with it, and pulling 128 bits from the same source is strictly (if not massively) superior at that.
I stand corrected. I was thinking of the sequential nature of uuid 7, or SQL servers sequential id.
Every time I read these types of Go issues, I think I am reading a writeup of a highschool debate club. It's like there is debate just for the sake of debate.
I understand the defensiveness about implementing new features, and I understand the rationale to keep the core as small as possible. But come on, it's not like UUID is a new thing. As the opener already pointed out, UUID is essential in pretty much all languages for interoperability so it makes sense to have that in the standard language.
Anyways, I'm just happy we'll get generic methods after 10 years of debates, I suppose. Maybe we'll get an export keyword before another 10, too. Then CGo will finally be usable outside a single package without those overlapping autogenerated symbols...
I mean that's pretty common in most OSS projects just because you have free entry to the debate.
If you want to see go-uniquie highschool debate club, look at Go team attitude to fixing logging, where community proposed multiple ways of solving it, Go team rejected all of them and then made massive navel-gazing post that could be summed up "well, there is multiple proposals THAT MEANS PEOPLE ARE UNSURE ON THE ISSUE so we won't do shit"
...then removed every question related to go logging (that were common in previous ones) in their yearly survey
Which is why I changed from being on Gonuts during pre-1.0 days to only touch Go if I really have to.
However I would still advocate for it over C in scenarios easily covered by TinyGo and TamaGo.
It's called bikeshedding. It's highly annoying, but unfortunately every public mailing list or tracker is prone to it.
The maintainers did the right thing by just saying "no."