HomePlaygroundExpressionsDocsDriversBlogStatusRoadmapChangelog GitHub

🪝 QAIL

The AST Protocol

One query language. Every layer.

QAIL replaces REST endpoints, GraphQL resolvers, and ORM abstractions with a single AST that flows from client to database — binary-encoded, type-safe, with built-in Row-Level Security.

QAIL AST
Qail::get("users")
    .select_all()
    .filter("active", Eq, true)
POSTGRESQL
SELECT * FROM users WHERE active = true
QDRANT
{ "must": [{ "key": "active", "match": true }] }
cargo install qail
zig fetch --save ...qail-zig/v0.2.0.tar.gz
Rust Python Go PHP Java Node C/C++ Rust Python Go PHP Java Node C/C++

Native Rust • Universal C-API • FFI Bindings

Real Benchmark: N+1 Battle Test

Same query. Same database. Same 50-row result set with 3 JOINs.
100 iterations, release build, buffer cache warmed.

QAIL AST
436µs
1 query
GQL + DataLoader
923µs
~3 queries
GQL Naive
18ms · 41× slower
~151 queries
REST Naive
16.8ms · 39× slower
~151 queries

QAIL sends 1 SQL JOIN. GraphQL/REST resolve N+1 with 151 round-trips to Postgres.

View all benchmarks →

The QAIL Stack

Four layers. One AST flows through all of them.

🧬

qail-core

THE AST

Parser, transpiler, type system. Queries are data structures, not strings. Schema validation at compile time.

get users fields id, email
  where active = true
  order by created_at desc
  limit 10
🔌

qail-pg / qdrant / redis

NATIVE DRIVERS

Direct wire protocol. Built-in RLS context per connection. No SQLx middleman. Facts + Meaning + Time.

let driver = PgDriver::connect_env().await?;
driver.set_rls_context(
    RlsContext::operator("op-456")
).await?;
driver.fetch_all(&cmd).await?
🚀

qail-gateway

AUTO-REST + BINARY PROTOCOL

Zero-code API from your schema. Auto-REST with FK expansion, policy engine, WebSocket subscriptions, binary AST wire format.

GET /api/bookings
    ?status.eq=confirmed
    &sort=created_at:desc
    &expand=routes,payments
    &limit=20
⚙️

qail-workflow

STATE MACHINES

Declarative multi-step orchestration. Database queries, notifications, and events in typed state machines.

Workflow::new("booking")
    .step("validate", validate_fn)
    .step("charge", payment_fn)
    .step("confirm", confirm_fn)
    .on_error(rollback_fn)

Every Entry Point → One Pipeline

REST params, text queries, or binary AST — all converge to the same struct. Policy injection and schema validation happen once, on the AST.

REST
GET /api/users?active=true
Text
get users where active = true
Binary
bincode::serialize(&cmd)
QAIL AST
Qail { action: Get, table: "users", cages: [Filter(active = true)] }
POLICY ENGINE
+ injects AND operator_id = 'op-456'
TRANSPILER
cmd.to_sql() → SELECT * FROM users WHERE active = true AND operator_id = 'op-456'
POSTGRESQL (with PG-native RLS)
1 query. 1 connection. Done.

Supported Databases

One AST. Three powerhouses. Facts + Meaning + Time.

PostgreSQL

PostgreSQL

Relational • Transactions • ACID

Production
Qdrant

Qdrant

Vector • AI/ML • Semantic Search

Production
Redis

Redis

Cache • Sessions • TTL

Production

Language Drivers

Native packages for your language. All powered by one Rust core.

Zig

Zig

Pure Zig • TLS • Pool v0.2.0
Rust

Rust

cargo add qail-core Cargo
PHP

PHP

31K q/s • 2.6x Eloquent GitHub
Go

Go

126K q/s • 4.2x GORM GitHub
Python

Python

130K rows/s COPY GitHub
Node.js

Node.js

FFI • Native Addon GitHub

View all drivers →

🛡️ The "Wait, Stop!" Feature

The only migration tool that reads your code before it touches your data.

Terminal
$ qail migrate up schema.qail --codebase ./src

🛑 BLOCKED: Safety Check Failed

You are dropping column 'status', but it is still used in:

   📄 src/queries.ts:25get portfolio fields status
   📄 src/api.rs:102Qail::get("portfolio").filter("status"...)

Fix your code first, or use --force to proceed.
🔍

Scans Before Running

Searches .rs, .ts, .js, .py for queries that reference changing columns

📍

Points to Line Numbers

Shows exactly where your code needs updating before migration

🎯

You're the Boss

Use --force to override when you know better

Skip REST. Skip GraphQL. Ship with QAIL.

One AST. Binary wire. Compile-time safety. Built-in RLS.