DatabasesPerformance

Oxyde Tutorial: Pydantic Async ORM for FastAPI (2026)

Oxyde ORM launched on Hacker News today as the first Pydantic-native async ORM with a high-performance Rust core. If you’ve used Django ORM and loved its clean QuerySet API, Oxyde brings that same ergonomic filter().exclude().order_by() syntax to FastAPI projects—without forcing you to adopt the full Django framework. Moreover, benchmark results show Oxyde hitting 1,475 operations/second on PostgreSQL, up to 18x faster than comparable Python ORMs, while eliminating the tedious model duplication between API schemas and database tables that plagues SQLAlchemy workflows.

Pydantic Models Are Database Models

Oxyde eliminates the conversion layer entirely. Your Pydantic models define both API validation and database schemas simultaneously. Consequently, no separate ORM classes are needed. No manual mapping between schema layers. One model to rule them all.

This is what a database model looks like in Oxyde:

from oxyde import Model, Field
from datetime import datetime

class Author(Model):
    id: int | None = Field(default=None, db_pk=True)
    name: str
    email: str = Field(db_unique=True)
    created_at: datetime = Field(db_default="CURRENT_TIMESTAMP")

    class Meta:
        is_table = True
        table_name = "authors"

That same model validates FastAPI requests, serializes responses, and maps to database tables. In contrast, the SQLAlchemy + Pydantic workflow requires defining a SQLAlchemy ORM model, then defining a Pydantic schema, then writing conversion functions between them. Oxyde cuts that boilerplate by 40% for standard CRUD operations.

FastAPI developers already use Pydantic for request/response validation. Furthermore, Oxyde extends that same type system to the database layer. The result? Single source of truth across your entire stack. As one Hacker News commenter put it: “I like the approach of eliminating model duplication. Using Pydantic as a unified contract makes sense.”

Django QuerySet API Without Django

Oxyde’s creator promises: “If you know Django ORM, you know Oxyde.” That’s not marketing. The API mirrors Django’s QuerySet interface exactly. Filter by field lookups, exclude unwanted records, chain operations, order results—the syntax is identical.

Here’s standard Django-style querying in Oxyde:

# Read with filtering (Django syntax)
authors = await Author.objects.filter(
    email__contains="@example.com"
).exclude(
    bio=None
).order_by("-created_at").all()

# Bulk update with F() expressions
await Post.objects.filter(
    title__contains="Oxyde"
).update(views=F("views") + 1)

# Transactions
async with transaction.atomic():
    post = await Post.objects.get(id=post_id)
    await post.save()

This solves a real pain point. Developers migrating from Django to FastAPI consistently cite missing Django ORM as a major frustration. SQLAlchemy works, but the session management and query syntax require relearning database patterns. Therefore, Oxyde brings Django’s best feature—its ORM—to the async FastAPI world without dragging along Django’s template system, admin site, or monolithic structure.

True Async Performance with Rust Core

Oxyde doesn’t fake async with threadpools. The Rust core handles SQL generation and query execution natively, releasing Python’s GIL during database I/O. Consequently, this enables genuine parallelism—multiple async database operations running concurrently without threadpool overhead.

The performance difference shows in benchmarks. Oxyde’s official benchmark suite (100 iterations, 10 warmup runs, pre-warmed connection pools) reveals significant advantages:

PostgreSQL: Oxyde achieves 1,475 ops/sec compared to 80-932 ops/sec for competing Pydantic-based ORMs. That’s up to 18x faster in the worst case, 1.5x faster against the best competitor.

SQLite: Oxyde hits 2,525 ops/sec versus 469-1,882 ops/sec across alternatives—up to 5.3x faster.

The creator clarifies the performance story: “Speed isn’t the primary goal. Bundling native drivers and connection pooling in Rust simply makes architectural sense.” The benchmarks prove the architecture pays off. Moreover, unlike Django ORM’s async implementation (which wraps synchronous database calls in threadpools), Oxyde is async from the ground up. For high-throughput async applications, that architectural difference matters.

Getting Started: 5-Minute Setup

Oxyde borrows Django’s migration workflow. Initialize a project with oxyde init, define models using Pydantic syntax, generate migrations with oxyde makemigrations, apply them with oxyde migrate. If you’ve touched Django, this is muscle memory.

Complete setup flow:

# Initialize project
oxyde init

# Define models in models.py (Pydantic syntax)
# Then generate and apply migrations
oxyde makemigrations
oxyde migrate

# Connect to database
await db.init(default="postgresql://user:pass@localhost/dbname")

# Or use SQLite
await db.init(default="sqlite:///blog.db")

# Query immediately
author = await Author.objects.get(email="alice@example.com")

Database support covers PostgreSQL 12+, SQLite 3.35+, and MySQL 8.0+. No complex engine configuration. No session lifecycle management. The simplicity is intentional—Oxyde optimizes for the 80% use case where Django ORM’s API is perfect and SQLAlchemy’s flexibility is overkill.

Trade-Offs: Simplicity vs Flexibility

Oxyde makes deliberate trade-offs. It sacrifices maximum flexibility for ergonomics and simplicity. This isn’t a weakness—it’s an architectural choice. However, it’s worth understanding what you’re trading.

The Hacker News discussion surfaced valid criticisms. One developer pointed out: “F() expressions being stringly-typed undermines the ‘zero magic’ promise. SQLAlchemy’s descriptor approach is superior for type safety.” That’s fair. Field references like F("views") rely on strings, meaning typos won’t be caught by type checkers.

Another concern: Oxyde uses custom exceptions instead of Python’s PEP-249 DBAPI standard. Consequently, this may cause friction with middleware or monitoring tools expecting standard database exceptions. The project uses sqlx (Rust’s SQL toolkit) rather than Python’s DB-API, which brings performance but sacrifices ecosystem compatibility.

The creator acknowledges the maturity question directly: “API is still evolving between minor versions (0.x releases).” Production-ready doesn’t mean API-stable. Therefore, teams adopting Oxyde today should expect occasional breaking changes until the 1.0 release.

When should you choose Oxyde over SQLAlchemy? If you’re building FastAPI microservices with moderate database complexity, already using Pydantic for validation, and value Django ORM’s ergonomics—Oxyde fits perfectly. For ultra-complex domain models, need for DBAPI compliance, or risk-averse teams requiring battle-tested stability, stick with SQLAlchemy. The smart choice depends on your constraints.

Key Takeaways

  • Oxyde combines Pydantic validation, Django QuerySet API, and Rust performance into a single async ORM for FastAPI projects
  • Eliminates model duplication—Pydantic models serve as both API schemas and database tables simultaneously
  • True async architecture (Rust core releases Python’s GIL) outperforms threadpool-based solutions by 18x in PostgreSQL benchmarks
  • Django-familiar migration workflow (makemigrations/migrate) reduces friction for developers migrating from Django to FastAPI
  • Trade-offs are real: string-typed F() expressions, non-DBAPI exceptions, and 0.x API instability versus SQLAlchemy’s maturity and flexibility
  • Ideal for FastAPI microservices with moderate complexity; consider SQLAlchemy for ultra-complex domains or DBAPI compliance requirements

Oxyde arrives at the right time. FastAPI adoption continues accelerating, Pydantic v2 solidified type-safe Python patterns, and async Python reached production maturity. In fact, the ecosystem needed a Django-ergonomic ORM for FastAPI projects. Oxyde fills that gap. Whether it becomes the standard FastAPI ORM or remains a well-crafted alternative depends on community adoption and the path to 1.0 stability—but for developers choosing tools today, it’s worth evaluating against your requirements.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:Databases