Why EdgeDB?
EdgeDB is a next-generation database built on top of PostgreSQL. It fixes PostgreSQL's pain points: no more JOINs for simple queries, no more ORMs, built-in schema migrations, and a powerful query language (EdgeQL) that's more intuitive than SQL.
EdgeDB Cloud free tier: 1 GB storage, 1 instance.
Getting Started
Install
curl --proto '=https' --tlsv1.2 -sSf https://sh.edgedb.com | sh
edgedb project init
Define Schema
# dbschema/default.esdl
module default {
type User {
required name: str;
required email: str {
constraint exclusive;
};
plan: str {
default := 'free';
};
multi posts := .<author[is Post];
created_at: datetime {
default := datetime_current();
};
}
type Post {
required title: str;
content: str;
required author: User;
published: bool {
default := false;
};
tags: array<str>;
views: int64 {
default := 0;
};
}
}
Migrate
edgedb migration create
edgedb migrate
EdgeQL (Better Than SQL)
# Insert with nested relation — no separate INSERT needed
insert User {
name := 'Alice',
email := 'alice@example.com',
plan := 'pro'
};
insert Post {
title := 'Getting Started with EdgeDB',
content := 'EdgeDB makes databases enjoyable...',
author := (select User filter .email = 'alice@example.com'),
published := true,
tags := ['edgedb', 'tutorial']
};
# Query with nested objects — NO JOIN!
select Post {
title,
views,
author: { name, email, plan }
}
filter .published = true
order by .views desc
limit 10;
# Aggregation
select User {
name,
post_count := count(.posts),
total_views := sum(.posts.views),
published_posts := count(.posts filter .published = true)
}
order by .total_views desc;
TypeScript Client (Fully Typed!)
import { createClient } from "edgedb";
import e from "./dbschema/edgeql-js"; // auto-generated query builder
const client = createClient();
// Type-safe query builder
const users = await e.select(e.User, (user) => ({
name: true,
email: true,
plan: true,
posts: (post) => ({
title: true,
views: true,
filter: e.op(post.published, "=", true)
}),
order_by: { expression: user.name, direction: e.ASC }
})).run(client);
users.forEach(u => {
console.log(`${u.name} (${u.plan}): ${u.posts.length} posts`);
});
// Or use EdgeQL strings
const result = await client.query(`
select Post {
title, views, author: { name }
} filter .published = true
order by .views desc
limit 5
`);
Python Client
import edgedb
client = edgedb.create_client()
# Query
users = client.query("""
select User {
name,
email,
post_count := count(.posts),
recent_posts := (
select .posts {
title, views
} order by .views desc
limit 3
)
}
filter .plan = 'pro'
""")
for user in users:
print(f"{user.name}: {user.post_count} posts")
for post in user.recent_posts:
print(f" - {post.title} ({post.views} views)")
EdgeDB vs Traditional ORMs
| Pain Point | SQL + ORM | EdgeDB |
|---|---|---|
| N+1 queries | Common trap | Impossible (nested by design) |
| Schema migrations | Manual/fragile | Auto-generated |
| Type safety | Runtime errors | Compile-time (query builder) |
| JOINs | Required | Not needed (computed links) |
| Setup | ORM + migration tool + DB | One tool |
Need data for your EdgeDB app? I build production-ready scrapers. Check out my Apify actors or email spinov001@gmail.com for custom data pipelines.
Have you tried EdgeDB? How does EdgeQL feel vs SQL? Share below!
Top comments (0)