Generate UUID in Go
github.com/google/uuid is the Go standard — maintained by Google, backed by crypto/rand (OS CSPRNG). uuid.New() for v4, uuid.NewString() for a string directly, uuid.NewV7() for time-ordered.
Quick Reference
| Function | Version | Sortable | Use Case |
|---|---|---|---|
| uuid.New() | v4 | No | General purpose — returns uuid.UUID type |
| uuid.NewString() | v4 | No | Returns string directly — convenience wrapper |
| uuid.NewV7() | v7 | Yes | Time-ordered — database PKs, event logs |
| uuid.Parse() | any | — | Parse and validate — returns error on invalid input |
Primary Implementation
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
// UUID v4 — random, crypto/rand-backed, zero unsafe
id := uuid.New()
fmt.Println(id)
// → f47ac10b-58cc-4372-a567-0e02b2c3d479
// As a string directly (convenience)
idStr := uuid.NewString()
// uuid.UUID is [16]byte — value type, no heap allocation
var raw [16]byte = id
// Parse and validate an existing UUID string
parsed, err := uuid.Parse("f47ac10b-58cc-4372-a567-0e02b2c3d479")
if err != nil {
fmt.Printf("Invalid UUID: %v\n", err)
return
}
fmt.Printf("Version: %d\n", parsed.Version()) // → 4
// Generate multiple
ids := make([]uuid.UUID, 5)
for i := range ids {
ids[i] = uuid.New()
}
}
All UUID Versions
UUID v4 — Random (recommended default)
import "github.com/google/uuid" // Returns uuid.UUID ([16]byte) — value type, no heap allocation id := uuid.New() fmt.Println(id.String()) // → "550e8400-e29b-41d4-a716-446655440000" // Or get a string directly idStr := uuid.NewString()
UUID v7 — Time-ordered (database PKs)
import "github.com/google/uuid"
// Millisecond-precision timestamp prefix — sorts chronologically
id, err := uuid.NewV7()
if err != nil {
log.Fatal(err)
}
fmt.Println(id.String()) // → "018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a"
UUID v5 — Deterministic / Namespace-based
import "github.com/google/uuid"
// SHA-1 hash of namespace + name — same inputs always produce the same UUID
id := uuid.NewSHA1(uuid.NameSpaceDNS, []byte("example.com"))
fmt.Println(id.String()) // → always "cfbff0d1-9375-5685-968c-48ce8b15ae17"
Real-World Use Cases
1. gRPC interceptor — request tracing ID
import (
"context"
"github.com/google/uuid"
"google.golang.org/grpc"
)
func UnaryRequestIDInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
requestID := uuid.NewString()
ctx = context.WithValue(ctx, "requestID", requestID)
return handler(ctx, req)
}
2. GORM model with UUID primary key
import (
"github.com/google/uuid"
"gorm.io/gorm"
)
type Order struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey"`
CreatedAt time.Time
Name string
}
// Auto-assign UUID before create
func (o *Order) BeforeCreate(tx *gorm.DB) error {
o.ID = uuid.New()
return nil
}
3. Distributed tracing — correlation ID
import (
"net/http"
"github.com/google/uuid"
)
func RequestIDMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestID := uuid.NewString()
w.Header().Set("X-Request-ID", requestID)
ctx := context.WithValue(r.Context(), "requestID", requestID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
Common Mistakes
Using fmt.Sprintf to build UUID strings
Manually constructing UUID strings with fmt.Sprintf("%x-%x-4%x-...", ...) is error-prone and almost always produces non-compliant UUIDs. Use uuid.New() or uuid.NewString().
Not handling errors from uuid.Parse()
uuid.Parse() returns an error for invalid input. Always check the error — ignoring it means you may silently use a zero-value UUID (00000000-0000-0000-0000-000000000000).
Storing uuid.UUID as a string in structs
uuid.UUID is a [16]byte value type — no heap allocation. Storing it as a string in structs wastes memory and loses type safety. Convert to string only at the boundary.
How It Works
The google/uuid package uses Go's crypto/rand package for entropy, which calls the OS CSPRNG — /dev/urandom on Linux/macOS and CryptGenRandom on Windows.
uuid.UUID is defined as type UUID [16]byte — a value type. Passing it around copies 16 bytes on the stack with zero heap allocation.
Output Formats
id.String()
f47ac10b-58cc-4372-a567-0e02b2c3d479
uuid.NewString()
f47ac10b-58cc-4372-a567-0e02b2c3d479
id[:] — []byte (16 bytes)
[0xf4 0x7a 0xc1 0x0b ...]
Best Practices
Store uuid.UUID in structs — only call .String() at API/DB boundaries.
Always handle the error from uuid.Parse() — never ignore it.
Use uuid.NewV7() for database PKs — sequential inserts avoid B-tree fragmentation.
Performance
Go generates roughly 5–10 million UUIDs/second. The uuid.UUID type is [16]byte — zero heap allocations when stored in structs.
The .String() call allocates a string. For high-throughput scenarios, use uuid.NewString() which combines generation and formatting in one call.
Installation
go get github.com/google/uuid
Requires Go 1.16+. The package is maintained by Google and has no transitive dependencies.
Security
Entropy source: crypto/rand → OS CSPRNG (/dev/urandom on Linux/macOS, CryptGenRandom on Windows). Cryptographically secure.
Suitable for session tokens, CSRF tokens, and API keys. Never use math/rand for UUID generation.