PyCon US 2025 was held in Pittsburgh, Pennsylvania from May 14–22, 2025. The event drew over 3,000 Python developers, researchers, and educators, with a packed schedule of talks, tutorials, and open spaces covering the Python 3.13 release cycle.
Python 3.13 and the uuid Module Update
Python 3.13 shipped in October 2024 with two additions to the uuid standard library module: uuid.uuid7() and uuid.uuid8(). PyCon US 2025 featured multiple talks and open space discussions on the practical implications — this was the first PyCon after the release, so developers came with real production questions.
The key change for most Python developers is simple: replace uuid.uuid4() with uuid.uuid7() in any context where the UUID will be used as a database primary key. The function signature and return type are identical — both return a uuid.UUID object. Only the version nibble and internal bit layout differ.
Django Integration
Sessions specifically addressed the Django ecosystem, where UUID primary keys are common. The recommended pattern for new Django projects on Python 3.13:
import uuid
from django.db import models
class Product(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid7, # was uuid.uuid4
editable=False,
)
The underlying uuid column type is unchanged — Django generates a migration that alters only the default callable, not the column. Existing rows keep their UUID v4 values permanently.
Talks also addressed the DRF (Django REST Framework) serializer behaviour: UUIDField serializes to the standard hyphenated UUID string regardless of version, so API responses require no changes when switching from v4 to v7.
FastAPI and Pydantic v2
For FastAPI developers using Pydantic v2, UUID v7 drops in without any model changes:
import uuid
from pydantic import BaseModel
class OrderCreate(BaseModel):
product_id: uuid.UUID
class Order(BaseModel):
id: uuid.UUID = Field(default_factory=uuid.uuid7)
product_id: uuid.UUID
Pydantic v2’s uuid.UUID type accepts any UUID version for input validation and serializes to the hyphenated string format. No custom validator is needed for v7.
SQLAlchemy and Alembic
PyCon 2025 talks on SQLAlchemy covered UUID v7 for async applications using SQLAlchemy 2.x with asyncpg. The pattern:
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
import uuid
class Base(DeclarativeBase):
pass
class Order(Base):
__tablename__ = "orders"
id: Mapped[uuid.UUID] = mapped_column(
primary_key=True,
default=uuid.uuid7,
)
SQLAlchemy maps uuid.UUID to PostgreSQL’s native uuid type automatically. Alembic-generated migrations detect the default change and emit ALTER TABLE … ALTER COLUMN … SET DEFAULT statements for the server-side default when using PostgreSQL 18’s uuidv7() function.
Asyncio and Clock Safety
A well-attended open space discussed UUID v7 clock safety in async Python. The concern: in a high-throughput asyncio application, many coroutines may call uuid.uuid7() within the same millisecond. RFC 9562 recommends a monotonic counter in this case to ensure within-millisecond ordering.
Python 3.13’s implementation uses the system clock without a monotonic counter — rapid successive calls within the same millisecond will have equal timestamps and independent random bits. For applications requiring strict within-millisecond ordering, attendees discussed wrapping uuid.uuid7() in a counter-backed generator, or using the uuid6 package which includes a monotonic counter implementation.
Related Python Resources
- Python 3.13 uuid module documentation
- uuid6 PyPI package — UUID v7 with monotonic counter for Python 3.9–3.12
- Django UUIDField documentation
- FastAPI documentation
- RFC 9562 — UUID v7 standard
Frequently asked questions
Was UUID v7 covered at PyCon US 2025?
Yes. PyCon US 2025 in Pittsburgh included sessions on Python 3.13's new uuid.uuid7(), Django UUIDField migration patterns, FastAPI integration with Pydantic v2, and asyncio clock-safety for high-throughput UUID generation. The PyCon US schedule archives the full talk list.
How do I generate UUID v7 in Python?
In Python 3.13+, use uuid.uuid7() from the standard library. For Python 3.9–3.12, install the uuid6 package (pip install uuid6) and use uuid6.uuid7(). Both return a uuid.UUID object with the same interface as uuid.uuid4().
Do UUIDs hurt database index performance?
UUID v4 does — its randomness causes every insert to land at a different leaf page, leading to page splits and poor cache locality. UUID v7 embeds a millisecond timestamp so consecutive inserts cluster together, behaving like an auto-increment integer for B-tree purposes.
When was uuid.uuid7() added to Python?
uuid.uuid7() was added to Python's standard library in Python 3.13, released in October 2024. It is part of the uuid module alongside the existing uuid.uuid4(). For Python 3.9–3.12, use the uuid6 package as a drop-in.
Can I use UUID v7 with FastAPI?
Yes. FastAPI uses Pydantic for request/response models, and Pydantic v2 accepts uuid.UUID objects regardless of version. Use default_factory=uuid.uuid7 in a Pydantic model field, or generate in the route handler. The FastAPI documentation covers UUID fields in request bodies and path parameters.