Skip to content
SimpleTools24

How to Generate a GUID in C# and .NET

By SimpleTools24Published 3 min read

To generate a GUID in C#, call Guid.NewGuid(). It returns a new random version 4 GUID, which you can convert to a string with .ToString(). On .NET 9 and later, Guid.CreateVersion7() creates a time-ordered version 7 GUID, which is often a better fit for database keys. Both return the System.Guid struct, a 128-bit value that formats as xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx by default.

Generating a GUID

csharp
using System;

Guid id = Guid.NewGuid();
Console.WriteLine(id);            // e.g. 3f2b8c1e-9d4a-4f6e-8b1a-2c7d5e9f0a13

string text = Guid.NewGuid().ToString();

Guid.NewGuid() produces a version 4 GUID with 122 random bits. It's suitable for unique identifiers but not for secrets such as passwords or security tokens; use RandomNumberGenerator for those.

Time-Ordered GUIDs (.NET 9+)

csharp
Guid v7 = Guid.CreateVersion7();                       // uses the current UTC time
Guid v7At = Guid.CreateVersion7(DateTimeOffset.UtcNow); // or a specific timestamp

Version 7 GUIDs start with a millisecond Unix timestamp, so values created later generally sort later. That reduces index fragmentation when GUIDs are used as keys; GUID as a primary key explains why that matters. Note that ordering across machines depends on their clocks.

Formatting GUIDs

ToString() accepts a format specifier:

Guid.ToString() format specifiers
SpecifierOutputUse
"D" (default)3f2b8c1e-9d4a-4f6e-8b1a-2c7d5e9f0a13Standard hyphenated form
"N"3f2b8c1e9d4a4f6e8b1a2c7d5e9f0a13Compact, 32 hex digits
"B"{3f2b8c1e-9d4a-4f6e-8b1a-2c7d5e9f0a13}Registry, COM, many Microsoft tools
"P"(3f2b8c1e-9d4a-4f6e-8b1a-2c7d5e9f0a13)Parentheses
"X"{0x3f2b8c1e,0x9d4a,0x4f6e,{0x8b,...}}C-style structure

.NET writes lowercase hex. For uppercase, call .ToString().ToUpperInvariant(). Case doesn't change the value; the UUID standard accepts either.

Parsing and Validating

csharp
if (Guid.TryParse(input, out Guid parsed))
{
    // valid: parsed holds the value
}

Guid exact = Guid.ParseExact("3f2b8c1e9d4a4f6e8b1a2c7d5e9f0a13", "N");

Guid.TryParse accepts the D, N, B, P and X forms, so it's lenient about braces and hyphens. Use ParseExact or TryParseExact when your API should accept only one format. Note that parsing checks the format, not whether the version and variant bits match the standard; how to validate a UUID covers stricter checks.

Guid.Empty

Guid.Empty is the all-zero GUID (00000000-0000-0000-0000-000000000000), the same as the nil UUID. It's the default value of an uninitialised Guid field, which makes it a common bug: a record saved with Guid.Empty because nobody assigned an ID.

csharp
if (order.Id == Guid.Empty)
    order.Id = Guid.NewGuid();

Nil UUID and max UUID explains how special values are used across languages.

Byte Order: A .NET Quirk

Guid.ToByteArray() writes the first three groups in little-endian order, so the bytes don't match the order of the hex string. Systems that expect big-endian (network) order can end up with a scrambled value. .NET 8 added a constructor and TryWriteBytes overload with a bigEndian flag for this. The existing GUID vs UUID guide covers byte order in detail.

Common Mistakes

  • new Guid() creates Guid.Empty, not a new random GUID. Use Guid.NewGuid().
  • Using GUIDs as secrets. They're unique, not unguessable by design.
  • Storing as strings in databases. Use a native uniqueidentifier or uuid column: 16 bytes instead of 36 or more characters.
  • Comparing strings with different case or braces. Compare parsed Guid values instead.

Generating GUIDs Without Code

For test data, configuration files or quick lookups, you don't need to open Visual Studio. The GUID generator creates version 4 or version 7 GUIDs in bulk (up to 1,000), with uppercase, braces or compact styles, and lets you copy or download them as TXT, CSV or JSON. Everything is generated in your browser using the Web Crypto API.

GUIDs in Entity Framework Core

When an entity's key is a Guid, EF Core can generate values for new entities on the client before saving. If you prefer database generation, configure a default value in the model, for example NEWSEQUENTIALID() on SQL Server. Check the provider's documentation for how it generates values, since behaviour differs between SQL Server, PostgreSQL and SQLite providers.

csharp
public class Order
{
    public Guid Id { get; set; } = Guid.CreateVersion7(); // .NET 9+
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

Assigning in the property initialiser makes the ID available immediately, which is useful for building related objects before saving.

Performance Notes

Guid.NewGuid() is fast enough for almost any application. If you need very large batches, generating them in a loop is fine; there's no need to cache or pre-generate. The bigger performance consideration is how GUIDs behave as database keys, which GUID as a primary key covers.

Frequently Asked Questions

Is Guid.NewGuid() random?

Yes. It produces version 4 GUIDs with 122 random bits. They're unique for practical purposes but aren't meant as security tokens.

What's the difference between new Guid() and Guid.NewGuid()?

new Guid() is the all-zero Guid.Empty. Guid.NewGuid() generates a new random value.

How do I generate a GUID without hyphens?

Use Guid.NewGuid().ToString("N").

Which .NET version added CreateVersion7?

.NET 9.

Summary

Use Guid.NewGuid() for random GUIDs and Guid.CreateVersion7() on .NET 9+ for time-ordered ones, format with D, N, B or P, parse with TryParse, and watch out for new Guid() and byte-order surprises.

Sources