Production-ready GraphQL API framework for PostgreSQL with CQRS, JSONB optimization, and type-safe mutations
Project description
FraiseQL
๐ You are here: Main FraiseQL Framework (v1.0.0) - Production Stable
Version Status: See VERSION_STATUS.md for complete version roadmap and recommendations
The fastest Python GraphQL framework. In PostgreSQL Everything.
Pre-compiled queries, Automatic Persisted Queries (APQ), PostgreSQL-native caching, error tracking, and observabilityโall in one database.
2-4x faster than traditional GraphQL frameworks โข In PostgreSQL Everything โข $300-3,000/month savings โข Zero external dependencies
๐ Project Versions & Navigation
Version Overview
| Version | Location | Status | Purpose | For Users? |
|---|---|---|---|---|
| v1.0.0 | Root level | Production Stable | Stable release | โ Recommended |
| Rust Pipeline | fraiseql_rs/ |
Integrated | Included in v1.0+ | โ Stable |
| v0.11.5 | Superseded | Legacy | Use v1.0.0 | โ ๏ธ Migrate |
New to FraiseQL? โ Getting Started โข Project Structure โข Documentation
๐ฅ Is This For Me?
FraiseQL is designed for production teams building GraphQL APIs with PostgreSQL. Here's how to know if it's right for you:
โ You Should Use FraiseQL If:
- Building GraphQL APIs with PostgreSQL
- Need sub-millisecond query performance
- Want database-native caching and monitoring
- Prefer zero external dependencies
- Team size: 2-50 developers
โ Consider Alternatives If:
- Not using PostgreSQL as your primary database
- Need multi-database support
- Prefer traditional ORM approaches
- Building simple CRUD APIs (consider REST)
๐ Choose Your Path
Prerequisites: Python 3.13+, PostgreSQL 13+
๐ Brand New to FraiseQL?
๐ First Hour Guide - 60 minutes, hands-on
- Progressive tutorial from zero to production
- Builds complete blog API
- Covers CQRS, types, mutations, testing
- Recommended for: Learning the framework thoroughly
โก Want to See It Working Now?
โก 5-Minute Quickstart - Copy, paste, run
- Working API in 5 minutes
- Minimal explanation
- Recommended for: Evaluating the framework quickly
๐ง Prefer to Understand First?
๐ง Understanding FraiseQL - 10 minute read
- Conceptual overview with diagrams
- Architecture deep dive
- No code, just concepts
- Recommended for: Architects and decision-makers
๐ Already Using FraiseQL?
๐ Quick Reference - Lookup syntax and patterns ๐ Full Documentation - Complete guides and references
New here? โ Start with First Hour Guide Need help? โ See Troubleshooting
For Contributors:
git clone https://github.com/fraiseql/fraiseql
cd fraiseql && make setup-dev
Learn more: Audiences Guide โข Getting Started
๐ Why FraiseQL?
๐๏ธ In PostgreSQL Everything
One database to rule them all. FraiseQL eliminates external dependencies by implementing caching, error tracking, and observability directly in PostgreSQL.
Cost Savings:
Traditional Stack:
- Sentry: $300-3,000/month
- Redis Cloud: $50-500/month
- Total: $350-3,500/month
FraiseQL Stack:
- PostgreSQL: Already running (no additional cost)
- Total: $0/month additional
Operational Simplicity:
Before: FastAPI + PostgreSQL + Redis + Sentry + Grafana = 5 services
After: FastAPI + PostgreSQL + Grafana = 3 services
PostgreSQL-Native Stack:
- Caching: UNLOGGED tables (Redis-level performance, no WAL overhead)
- Error Tracking: Automatic fingerprinting, grouping, notifications (like Sentry)
- Observability: OpenTelemetry traces + metrics in PostgreSQL
- Monitoring: Grafana dashboards querying PostgreSQL directly
โก Blazing Fast Performance
- Automatic Persisted Queries (APQ): SHA-256 hash lookup with pluggable storage backends
- Memory & PostgreSQL storage: In-memory for simplicity, PostgreSQL for enterprise scale
- JSON passthrough optimization: Sub-millisecond cached responses (0.5-2ms for simple queries)
- Pre-compiled queries: TurboRouter with intelligent caching (2-4x faster than standard GraphQL)
- Real production benchmarks: 85-95% cache hit rate for stable query patterns
๐ Performance Guide - Methodology, realistic expectations, and benchmark details
๐๏ธ Database-First Architecture
- CQRS by design: Commands via PostgreSQL functions, queries via views
- JSONB-powered: Flexible schema evolution with full type safety
- View-based queries:
v_*for real-time,tv_*for materialized performance - PostgreSQL does the heavy lifting: Joins, aggregations, transformations in-database
๐ง Developer Experience
- Type-safe: Full Python 3.13+ type hints with automatic GraphQL schema generation
- Automatic documentation: Python docstrings become GraphQL descriptions in Apollo Studio
- One command setup:
fraiseql init my-api && fraiseql dev - Intelligent WHERE clauses: Automatic type-aware SQL optimization for network types, dates, and more
- Hybrid table support: Seamless filtering across regular columns and JSONB fields
- Built-in security: Field-level authorization, rate limiting, CSRF protection
๐ How It Works
Request Flow: GraphQL โ PostgreSQL โ Rust โ Response
Every GraphQL request follows this optimized path:
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ GraphQL โโโโโถโ FastAPI โโโโโถโ PostgreSQL โโโโโถโ Rust โ
โ Query โ โ Resolver โ โ View โ โ Transform โ
โ โ โ โ โ โ โ โ
โ { users { โ โ @query โ โ SELECT โ โ jsonb โ โ
โ name โ โ def users: โ โ jsonb_build_ โ โ GraphQL โ
โ } } โ โ return db โ โ object โ โ Response โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
- GraphQL Query arrives at FastAPI
- Python Resolver calls PostgreSQL view/function
- Database returns pre-composed JSONB
- Rust Pipeline transforms to GraphQL response
๐ Detailed Request Flow Diagram - Complete lifecycle with examples Deep dive: Understanding FraiseQL - 10-minute visual guide to the architecture
CQRS Pattern: Reads vs Writes
FraiseQL implements Command Query Responsibility Segregation:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ GraphQL API โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโค
โ QUERIES โ MUTATIONS โ
โ (Reads) โ (Writes) โ
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ v_* views โ fn_* functions โ
โ tv_* tables โ tb_* tables โ
โโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโ
Queries use views for fast, fresh data. Mutations use functions for business logic.
๐ CQRS Pattern Details - Read vs write separation explained
๐ Quick Start
Prerequisites: Python 3.13+, PostgreSQL 13+
# Install FraiseQL
pip install fraiseql
# Create your first project
fraiseql init my-api
cd my-api
# Start development server
fraiseql dev
Your GraphQL API is live at http://localhost:8000/graphql ๐
๐ Detailed Installation Guide - Multiple installation options, troubleshooting, and platform-specific instructions
๐ง Core Concepts
FraiseQL uses innovative patterns that might be new if you're coming from traditional frameworks:
CQRS (Command Query Responsibility Segregation)
Separate reading data from writing data - like having separate lines for ordering food vs. picking it up.
- Commands (writes):
tb_*tables for data changes - Queries (reads):
v_*/tv_*views for data access
JSONB Views
Pre-packaged data as JSONB objects for GraphQL - like meal kits ready to serve.
v_*views: Real-time JSONB computationtv_*tables: Pre-computed JSONB for speed
Trinity Identifiers
Three types of identifiers per entity for different purposes:
pk_*: Internal fast joins (never exposed)id: Public API identifier (UUID)identifier: Human-readable slug (SEO-friendly)
Database-First Architecture
Design your API starting from PostgreSQL, not the other way around. Business logic lives in database functions.
Learn more about these concepts โ
๐ Automatic Persisted Queries (APQ)
FraiseQL provides enterprise-grade APQ support with pluggable storage backends:
Storage Backends
from fraiseql import FraiseQLConfig
# Memory backend (default - zero configuration)
config = FraiseQLConfig(
apq_storage_backend="memory" # Perfect for development & simple apps
)
# PostgreSQL backend (enterprise scale)
config = FraiseQLConfig(
apq_storage_backend="postgresql", # Persistent, multi-instance ready
apq_storage_schema="apq_cache" # Custom schema for isolation
)
How APQ Works
- Client sends query hash instead of full query
- FraiseQL checks storage backend for cached query
- JSON passthrough optimization returns results in 0.5-2ms
- Fallback to normal execution if query not found
Enterprise Benefits
- 85-95% cache hit rates in production applications (99.9% for highly stable query patterns)
- 70% bandwidth reduction with large queries
- Multi-instance coordination with PostgreSQL backend
- Automatic cache warming for frequently used queries
โก APQ Cache Flow Details - How persisted queries work
๐ฏ Core Features
Enterprise Security & Compliance
- Unified Audit Logging with Cryptographic Chain: Tamper-proof audit trails with SHA-256 hashing and HMAC signatures
- PostgreSQL-native crypto: No Python overhead for event creation and verification
- Multi-tenant isolation: Per-tenant cryptographic chains for SOX/HIPAA compliance
- Field-level authorization: Decorator-based access control with role inheritance
- Row-level security: PostgreSQL RLS integration for data isolation
Advanced Type System
Specialized operators for network types, hierarchical data, and ranges:
query {
servers(where: {
ipAddress: { eq: "192.168.1.1" } # โ ::inet casting
port: { gt: 1024 } # โ ::integer casting
macAddress: { eq: "aa:bb:cc:dd:ee:ff" } # โ ::macaddr casting
location: { ancestor_of: "US.CA" } # โ ltree operations
dateRange: { overlaps: "[2024-01-01,2024-12-31)" }
}) {
id name ipAddress port
}
}
Unified Rust-First Execution All queries follow the same high-performance path:
PostgreSQL โ Rust โ HTTP (0.5-5ms response time)
- Always Fast: No mode detection or branching logic
- Field Projection: Rust processes JSON 7-10x faster than Python
- Zero Python Overhead: Direct RustResponseBytes to FastAPI
Supported specialized types:
- Network:
IPv4,IPv6,CIDR,MACAddresswith subnet/range operations - Hierarchical:
LTreewith ancestor/descendant queries - Temporal:
DateRangewith overlap/containment operations - Standard:
EmailAddress,UUID,JSONwith validation
Intelligent Mutations
PostgreSQL functions handle business logic with structured error handling:
from fraiseql import input, mutation
from typing import Optional
@input
class CreateUserInput:
name: str
email: str # Email validation handled by PostgreSQL
@mutation
def create_user(input: CreateUserInput) -> Optional[User]:
"""Create a new user."""
pass # Implementation handled by framework
Multi-Tenant Architecture
Built-in tenant isolation with per-tenant caching:
from fraiseql import query
from typing import List
# Automatic tenant context
@query
def users() -> List[User]:
"""Get all users for current tenant."""
pass # Implementation handled by framework
Table Views (tv_*)
Denormalized projection tables for instant GraphQL responses:
-- Transform table (actually a TABLE, not a view!)
CREATE TABLE tv_user (
id INT PRIMARY KEY,
data JSONB GENERATED ALWAYS AS (
jsonb_build_object(
'id', id,
'first_name', (SELECT first_name FROM tb_user WHERE tb_user.id = tv_user.id),
'user_posts', (SELECT jsonb_agg(...) FROM tb_post WHERE user_id = tv_user.id LIMIT 10)
)
) STORED
);
from fraiseql import type, query
from typing import List
# Type definition
@type(sql_source="tv_user", jsonb_column="data")
class User:
id: int
first_name: str # Rust transforms to firstName
user_posts: List[Post] # Embedded relations!
# Query (0.05ms lookup + 0.5ms Rust transform)
@query
def user(id: int) -> User:
"""Get user by ID."""
pass # Implementation handled by framework
Benefits:
- 0.05-0.5ms database lookup time (10-100x faster than complex JOINs for nested data)
- Embedded relations (no N+1 queries)
- Always up-to-date (generated columns + triggers)
- Rust field projection (7-10x faster than Python JSON processing)
๐ Performance Comparison
Framework Comparison (Real Measurements)
| Framework | Simple Query | Complex Query | Cache Hit | APQ Support |
|---|---|---|---|---|
| FraiseQL | 1-5ms | 5-25ms | 85-95% | Native |
| PostGraphile | 50-100ms | 200-400ms | N/A | Plugin |
| Strawberry | 100-200ms | 300-600ms | External | Manual |
| Hasura | 25-75ms | 150-300ms | External | Limited |
Test conditions: PostgreSQL 15, 10k records, standard cloud instance. See Performance Guide for methodology.
FraiseQL Optimization Layers
| Optimization Stack | Response Time | Use Case |
|---|---|---|
| Rust Pipeline + APQ | 0.5-2ms | Production applications |
| Rust Pipeline only | 1-5ms | Development & testing |
Real production benchmarks with PostgreSQL 15, 10k+ records
๐๏ธ Architecture
FraiseQL's Rust-first architecture delivers exceptional performance through unified execution:
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ GraphQL โ โ โ PostgreSQL โ โ โ Rust โ
โ Request โ โ JSONB Query โ โ Transform โ
โ โ โ (0.05-0.5ms) โ โ (0.5ms) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ APQ Hash โ โ โ Storage โ โ โ HTTP โ
โ (SHA-256) โ โ Backend โ โ Response โ
โ โ โ Memory/PG โ โ (0.5-2ms) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
Optional Cache FraiseQL Cache Instant Response
Key Innovations
- Exclusive Rust Pipeline: PostgreSQL โ Rust โ HTTP (no Python overhead)
- Rust Field Projection: 7-10x faster JSON transformation than Python
- Table Views:
tv_*tables with generated JSONB for instant queries - APQ Storage Abstraction: Pluggable backends (Memory/PostgreSQL) for query hash storage
- Zero-Copy Path: Sub-millisecond responses with zero Python serialization
๐ฆ When to Choose FraiseQL
โ Perfect For:
- Cost-conscious teams: Save $300-3,000/month vs Redis + Sentry
- High-performance APIs: Sub-10ms response time requirements
- Multi-tenant SaaS: Per-tenant isolation and caching
- PostgreSQL-first teams: Already using PostgreSQL extensively
- Operational simplicity: One database for everything
- Enterprise applications: ACID guarantees, no eventual consistency
- Self-hosted infrastructure: Full control, no SaaS vendor lock-in
โ Consider Alternatives:
- Simple CRUD: Basic applications without performance requirements
- Non-PostgreSQL databases: FraiseQL is PostgreSQL-specific
- Microservices: Better suited for monolithic or database-per-service architectures
๐ PostgreSQL-Native Observability
FraiseQL includes a complete observability stack built directly into PostgreSQLโeliminating the need for external services like Sentry, Redis, or third-party APM tools.
Error Tracking (Alternative to Sentry)
from fraiseql.monitoring import init_error_tracker
tracker = init_error_tracker(db_pool, environment="production")
await tracker.capture_exception(error, context={...})
# Features:
# - Automatic error fingerprinting and grouping
# - Full stack trace capture
# - Request/user context preservation
# - OpenTelemetry trace correlation
# - Issue management (resolve, ignore, assign)
# - Custom notification triggers (Email, Slack, Webhook)
Caching (Alternative to Redis)
from fraiseql.caching import PostgresCache
cache = PostgresCache(db_pool)
await cache.set("key", value, ttl=3600)
# Features:
# - UNLOGGED tables for Redis-level performance
# - No WAL overhead = fast writes
# - Shared across instances
# - TTL-based expiration
# - Pattern-based deletion
OpenTelemetry Integration
# All traces and metrics stored in PostgreSQL
# Query for debugging:
SELECT * FROM monitoring.traces
WHERE error_id = 'error-123' -- Full correlation
AND trace_id = 'trace-xyz';
Grafana Dashboards
Pre-built dashboards included in grafana/:
- Error monitoring dashboard
- OpenTelemetry traces dashboard
- Performance metrics dashboard
- All querying PostgreSQL directly
Migration Guides:
- v1 to v2 Migration - Unified Rust-first architecture
- Monitoring Migration - From Redis and Sentry
๐ ๏ธ CLI Commands
# Project management
fraiseql init <name> # Create new project
fraiseql dev # Development server with hot reload
fraiseql check # Validate schema and configuration
# Code generation
fraiseql generate schema # Export GraphQL schema
fraiseql generate types # Generate TypeScript definitions
# Database utilities
fraiseql sql analyze <query> # Analyze query performance
fraiseql sql explain <query> # Show PostgreSQL execution plan
๐ค Contributing
We welcome contributions! See CONTRIBUTING.md for:
- Development setup and testing
- Architecture decisions and patterns
- Code style and review process
๐ Learn More
- Documentation - Complete guides and API reference
- Examples - Real-world applications and patterns
- Architecture - Design decisions and trade-offs
๐ Acknowledgments
FraiseQL draws inspiration from:
- Strawberry GraphQL - Excellent Python GraphQL library ("Fraise" = French for strawberry)
- Harry Percival's "Architecture Patterns with Python" - Clean architecture and repository patterns
- Eric Evans' "Domain-Driven Design" - Database-centric domain modeling
- PostgreSQL community - For building the world's most advanced open source database
๐จโ๐ป About
FraiseQL is created by Lionel Hamayon (@evoludigit), a self-taught developer and founder of รvolution digitale.
Started: April 2025
I built FraiseQL out of frustration with a stupid inefficiency: PostgreSQL returns JSON โ Python deserializes to objects โ GraphQL serializes back to JSON. Why are we doing this roundtrip?
After years moving through Django, Flask, FastAPI, and Strawberry GraphQL with SQLAlchemy, I realized the entire approach was wrong. Just let PostgreSQL return the JSON directly. Skip the ORM. Skip the object mapping.
But I also wanted something designed for the LLM era. SQL and Python are two of the most massively trained languagesโLLMs understand them natively. Why not make a framework where AI can easily get context and generate correct code?
FraiseQL is the result: database-first CQRS where PostgreSQL does what it does best, Python stays minimal, and the whole architecture is LLM-readable by design.
Full disclosure: I built this while compulsively preparing for scale I didn't have. But that obsession led somewhere realโsub-millisecond responses, zero N+1 queries, and a framework that both humans and AI can understand.
Connect:
- ๐ผ GitHub: @evoludigit
- ๐ง lionel.hamayon@evolution-digitale.fr
- ๐ข รvolution digitale
Support FraiseQL:
- โญ Star fraiseql/fraiseql
- ๐ฌ Join discussions and share feedback
- ๐ค Contribute to the project
๐ License
MIT License - see LICENSE for details.
Ready to build the fastest GraphQL API in Python?
pip install fraiseql && fraiseql init my-fast-api
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fraiseql-1.0.0.tar.gz.
File metadata
- Download URL: fraiseql-1.0.0.tar.gz
- Upload date:
- Size: 406.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b964969347fb0fd14509a4237ce3720ce286a29cd31f069bc96e861ebe8e3748
|
|
| MD5 |
604c528a0c78f32aadcbfa23017a29e4
|
|
| BLAKE2b-256 |
1170c60675a00aa18383950082e4fc57d351c41edf6297394d4fcb3fe8b14a5c
|
File details
Details for the file fraiseql-1.0.0-py3-none-any.whl.
File metadata
- Download URL: fraiseql-1.0.0-py3-none-any.whl
- Upload date:
- Size: 522.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27a4558e77cf865a84d8c6f91360ae704793508f0807f9c360e203665c71d554
|
|
| MD5 |
3e00aba0335259165b87b8643443dcd2
|
|
| BLAKE2b-256 |
2cd039b647b567ed1d6542631204f5f78bdda57b221afc6adfcbbcaba82aca8a
|