What Hasura Does
- Instant APIs: Auto-generate GraphQL and REST APIs from any database table
- Real-time Subscriptions: Live query subscriptions for real-time data updates
- Access Control: Row-level and column-level permissions with session variables
- Relationships: Define relationships between tables for nested queries
- Event Triggers: Fire webhooks on database insert/update/delete events
- Remote Schemas: Stitch multiple GraphQL services into one unified API
- Actions: Extend GraphQL schema with custom business logic via webhooks
- Migrations: Version-controlled schema and metadata migrations
- Caching: Query response caching with configurable TTL
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Frontend │────▶│ Hasura │────▶│ PostgreSQL /│
│ (Any) │ │ Engine │ │ MySQL / │
│ GraphQL │ │ (Haskell) │ │ SQL Server /│
│ Queries │ └──────┬───────┘ │ MongoDB │
└──────────────┘ │ └──────────────┘
┌──────┴───────┐
│ Remote │
│ Services │
│ (Custom API) │
└──────────────┘Self-Hosting
Docker Compose
services:
hasura:
image: hasura/graphql-engine:latest
ports:
- "8080:8080"
environment:
HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://hasura:hasura@postgres:5432/hasura
HASURA_GRAPHQL_DATABASE_URL: postgres://hasura:hasura@postgres:5432/myapp
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_ADMIN_SECRET: your-admin-secret
HASURA_GRAPHQL_UNAUTHORIZED_ROLE: anonymous
depends_on:
- postgres
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: hasura
POSTGRES_PASSWORD: hasura
POSTGRES_DB: myapp
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
pg-data:How It Works
1. Connect Database
Point Hasura at your existing PostgreSQL:
Database URL: postgres://user:password@host:5432/mydbHasura reads your schema and instantly generates GraphQL types for every table.
2. Query via GraphQL
# Auto-generated queries
query {
users(where: {active: {_eq: true}}, order_by: {created_at: desc}, limit: 10) {
id
name
email
orders(order_by: {created_at: desc}) {
id
total
status
items {
product { name price }
quantity
}
}
}
}
# Mutations
mutation {
insert_users_one(object: {name: "John", email: "john@example.com"}) {
id
}
}
# Real-time subscription
subscription {
orders(where: {status: {_eq: "pending"}}) {
id
total
customer { name }
}
}3. Access Control
# Role-based permissions
- role: user
table: orders
permission:
filter:
customer_id: X-Hasura-User-Id # Users can only see their own orders
columns: [id, total, status, created_at] # Can't see internal fields
- role: admin
table: orders
permission:
filter: {} # Admins see all orders
columns: "*" # All columns4. Event Triggers
Table: orders
Event: INSERT
Webhook: https://api.example.com/new-order-handler
Payload:
{
"event": {
"data": {
"new": { "id": 123, "total": 99.99, "customer_id": 456 }
}
}
}Use cases: Send emails, update inventory, sync CRM, trigger notifications.
5. Actions (Custom Logic)
# Extend schema with custom mutations
type Mutation {
processPayment(orderId: Int!, paymentMethod: String!): PaymentResult
}
# Hasura forwards to your webhook
# POST https://api.example.com/process-payment
# Your code handles the business logicHasura vs Alternatives
| Feature | Hasura | PostgREST | Supabase | Directus |
|---|---|---|---|---|
| API Type | GraphQL + REST | REST | REST + Realtime | REST + GraphQL |
| Subscriptions | Real-time | No | Real-time | No |
| Access control | Row/Column level | Row level | Row level | Role level |
| Event triggers | Yes | No | Edge Functions | Flows |
| Remote schemas | Yes | No | No | No |
| Multi-database | PG, MySQL, MSSQL, MongoDB | PostgreSQL only | PostgreSQL only | Any SQL |
| Language | Haskell | Haskell | TypeScript | JavaScript |
FAQ
Q: Do I need to write backend code with Hasura? A: Not at all for simple CRUD — Hasura generates it automatically. Complex business logic is implemented via Actions (webhooks), where you only write the handler. It fits the 80% case that doesn't need a backend, plus the 20% that requires custom logic.
Q: How's the performance? Can it handle high concurrency? A: Hasura is written in Haskell and is extremely performant. A single instance can handle thousands of GraphQL requests per second. It supports query caching and horizontal scaling. Production deployments have handled tens of thousands of requests per second.
Q: Can I use an existing database directly? A: Absolutely. Hasura doesn't modify your database schema — it only reads schema information and generates an API. That's Hasura's biggest advantage: adding an API to an existing project takes just minutes.
Sources & Credits
- GitHub: hasura/graphql-engine — 31.9K+ ⭐ | Apache-2.0
- Website: hasura.io