EdgeDB v5
To play with the new features, make sure to specify version 5.0 when initializing the project as pre-release versions are not considered stable and will not be automatically suggested:
$
edgedb project init
Upgrading
Local and Cloud instances
To upgrade a local project, first ensure that your CLI is up to date with
edgedb cli upgrade
. Then run the following command inside the project
directory.
$
edgedb project upgrade
Alternatively, specify an instance name if you aren’t using a project.
$
edgedb instance upgrade -I my_instance
The CLI will first check to see if your schema will migrate cleanly to EdgeDB 5.0. If the upgrade check finds any problems, it will report them back to you.
Hosted instances
To upgrade a remote (hosted) instance, we recommend the following dump-and-restore process.
-
EdgeDB v5.0 supports PostgreSQL 14 (or above). So check the version of PostgreSQL you are using before upgrading EdgeDB. If you’re using Postgres 13 or below, you should upgrade Postgres first.
-
Spin up an empty 5.0 instance. You can use one of our deployment guides.
Under Debian/Ubuntu, when adding the EdgeDB package repository, use this command instead:
Copy$
echo deb [signed-by=/usr/local/share/keyrings/edgedb-keyring.gpg] \ https://packages.edgedb.com/apt \ $(grep "VERSION_CODENAME=" /etc/os-release | cut -d= -f2) main \ | sudo tee /etc/apt/sources.list.d/edgedb.list
Use this command for installation under Debian/Ubuntu:
Copy$
sudo apt-get update && sudo apt-get install edgedb-5
Under CentOS/RHEL, use this installation command:
Copy$
sudo yum install edgedb-5
In any required
systemctl
commands, replaceedgedb-server-4
withedgedb-server-5
.Under any Docker setups, supply the
5.0
tag. -
Take your application offline, then dump your v4.x database with the CLI
Copy$
edgedb dump --dsn <old dsn> --all --format dir my_database.dump/
This will dump the schema and contents of your current database to a directory on your local disk called
my_database.dump
. The directory name isn’t important. -
Restore the empty v5.x instance from the dump
Copy$
edgedb restore --all my_database.dump/ --dsn <new dsn>
Once the restore is complete, update your application to connect to the new instance.
This process will involve some downtime, specifically during steps 2 and 3.
New features
EdgeDB + AI
We’ve added an ext::ai
extension for handling the integration of EdgeDB
with various AI backends such as: OpenAI, Mistral and Anthropic.
There is a special ext::ai::index
that can be used to delegate the search
functionality of EdgeDB objects to a specific AI search provider.
The function ext::ai::to_context(object: anyobject)
evaluates the
expression of the specific ext::ai::index
defined on the passed object
type and returns it.
The function ext::ai:search(object: anyobject, query: array<float32>)
searches the specified objects using the associated AI search provider and the
specified semantic query representation.
There are also two HTTP API points for interacting with the data:
-
/ai/embeddings
-
/ai/rag
EdgeDB branches
EdgeDB 5.0 adds branching functionality in order to help bridge the gap between the code (and schema) managed by version control systems and the actual development database.
The first thing to note is that we’re updating our terminology and replacing
the old (and potentially confusing) term database
with branch
. This
means that the old create database
and drop database
commands are
considered deprecated in favor of create empty branch
and drop branch
,
respectively. However, the new branch
commands provide more options and
functionality than the old database
commands:
-
create empty branch <newbranch>
The most basic command creates a new branch with an empty schema (exactly the same as
create database
). -
create schema branch <newbranch> from <oldbranch>
This command creates a new branch and copies the schema of an existing branch to it. Only the schema is copied; the data is still empty and needs to be populated separately.
-
create data branch <newbranch> from <oldbranch>
This command creates a new branch and copies both the schema and the data of an existing branch to it.
-
drop branch <oldbranch>
Removes an existing branch from the instance.
-
alter branch <oldname> rename to <newname>
The command to rename a branch.
The intent is to provide a mechanism that helps developers keep branches of the database corresponding to the code branches that introduce certain schema changes.
With these new commands, here’s how we envision developers using them to manage “feature” branches:
-
Create a new “feature” VCS branch (a clone of the “main” branch) and a corresponding “feature” EdgeDB branch.
-
Work on the “feature” branch, add migrations, etc.
-
When it is time to merge the feature work back into the main branch we want to arrange things so that the “feature” branch is in a state that is a simple fast-forward w.r.t the “main” branch.
-
In order to achieve the above state we need to make sure the “main” code branch as well as the EdgeDB branch are both up-to-date.
-
Then we want to rebase the “feature” branch code on top of the “main” branch code.
-
After that we need to replicate the same rebase operation with the EdgeDB branch. Our CLI tools may need to first clone the “main” branch with the data into a “temp” branch. Then we can introspect the migration histories of the “temp” and “feature” branches so that we can establish where they diverge. Take all the divergent migrations from the “feature” branch and apply them to the “temp” branch. If the operation is successful, drop the “feature” branch and rename “temp” to “feature”. We now have successfully rebased “feature” branch on top of “main”.
-
Since the state of “feature” is now a straightforward fast-forward w.r.t. the “main” branch we can finally merge “feature” back into main in VCS and then merge the EdgeDB branch as well (or rename the “feature” EdgeDB branch to “main”, if the old branch is no longer needed).
We’ve added edgedb branch commands to our CLI as well that create, copy, rename, drop, and rebase EdgeDB branches.
Updated pgvector extension
A new HNSW (Hierarchical Navigable Small Worlds) index has been added to the
pgvector
extension. Just like IVFFlat indexes there are three flavors of
HNSW corresponding to different operations:
-
ext::pgvector::hnsw_euclidean
-
ext::pgvector::hnsw_ip
-
ext::pgvector::hnsw_cosine
We have also updated the mechanism for tuning all of the indexes provided in
this extension. The probes
(for IVFFlat) and ef_search
(for HNSW)
parameters can now be accessed via the ext::pgvector::Config
object.
The current config values can be found by examining the extensions
link of
the cfg::Config
object. Notice that in order to see the specific extension
config properties you need to use the type filter [is
ext::pgvector::Config]
:
db>
select cfg::Config.extensions[is ext::pgvector::Config]{*};
{ ext::pgvector::Config { id: 12b5c70f-0bb8-508a-845f-ca3d41103b6f, probes: 1, ef_search: 40, }, }
Updating the value can be done using the configure session
command:
db> ...
configure session
set ext::pgvector::Config::probes := 5;
OK: CONFIGURE SESSION
It is also possible to restore the default config value:
db>
configure session reset ext::pgvector::Config::probes;
OK: CONFIGURE SESSION
Authentication
We’re bringing two popular “passwordless” authentication schemes to our
auth
extension: the Web Authentication API (commonly known as WebAuthn or
Passkeys), as well as email-based “magic links”.
We’ve also added two popular chat platforms to our list of supported OAuth providers: Slack and Discord.
We also have the following updates:
-
Allow passing WebAuthn
user_handle
in request body (#6942) -
Handle WebAuthn challenge having multiple factors (#6945)
-
Explicitly pass WebAuthn credential properties (#6975)
-
Return JSON for magic link register (#6974)
-
Ensure built-in UI verification redirect includes code (#6982)
-
Ensure WebAuthn redirect matches expected shape (#6987)
-
Fallback to PKCE RFC parameter names (#7034)
-
Add optional PKCE challenge in email verification (#7037)
Additional changes
Performance
The query compilation cache is now persisted across restarts, and cached queries are automatically recompiled after migrations are applied.
We’ve also improved processing of large schemas and migrations.
EdgeQL
-
Allow omitting
union
infor
if the body is a statement. (#6810)If the
for
query body involves a statement such asinsert
,update
,delete
, etc., you no longer need to write theunion
keyword and add parentheses around the statement expression:Copyfor name in {'Alice', 'Billie', 'Cameron'} union ( insert User { name := name } )
-
Add
administer vacuum()
command. (#6663)The command
administer vacuum()
can take a list of object types, multi properties, multi links or links with link properties. There is also a named only argumentfull
that reclaims storage to the OS rather than just to the database. All of the arguments can be omitted. In case no target types are specified, everything accessible to the user will be vacuumed.The vacuum command will use already allocated space better so that it will reduce the growth rate of the database, or will reclaim storage space to the operating system with
full
. Since certain aspects such as multi properties and links as well as links with link properties require additional underlying tables they can be listed separately when reclaiming storage space.If the
full
option is set totrue
, reclaimed storage is returned to the OS, but it can take much longer and will exclusively lock the underlying tables.For example, the following command will vacuum the
User
type reclaiming storage to the OS:Copyadminister vacuum(User, full := true)
-
Integer/UUID to bytes conversion. (#6553)
It is now possible to convert
int16
,int32
,int64
, anduuid
tobytes
and vice-versa using the corresponding conversion functions.Use the
to_bytes()
to convert values intobytes
:Copydb>
select to_bytes(<int32>31, Endian.Big);
{b'\x00\x00\x00\x1f'}
Copydb>
select to_int32(b'\x01\x02\x00\x07', Endian.Big);
{16908295}
Copydb>
select to_bytes(<uuid>'1d70c86e-cc92-11ee-b4c7-a7aa0a34e2ae');
{b'\x1dp\xc8n\xcc\x92\x11\xee\xb4\xc7\xa7\xaa\n4\xe2\xae'}
Copydb> ... ... ... ... ...
select to_uuid( b'\x92\x67\x3a\xfc\ \x9c\x4f\ \x42\xb3\ \x82\x73\ \xaf\xe0\x05\x3f\x0f\x48');
{92673afc-9c4f-42b3-8273-afe0053f0f48}
-
Add
bytes
option toarray_join
. (#6918)The
array_join()
can now operate onbytes
the same way it operates onstr
:Copydb>
select array_join([b'\x01', b'\x02', b'\x03'], b'\xff');
{b'\x01\xff\x02\xff\x03'}
-
Support closing all connections to a database on
drop database
. (#6780) -
Add a
std::get_current_branch()
function. (#7001) -
Add
cfg::Config.query_cache_mode
(#7158)
Bug fixes
-
Fix issues with empty sets leaking out of optional scopes (#6747)
-
Fix an SDL scalar type dependency bug
-
Suppress idle transaction timeout during migrations (#6760)
-
Use a consistent interface for
ext::auth
errors (#6751) -
Stop recording extension version in dumps (#6787)
-
For any index changes don’t attempt to update the index, drop and recreate instead (#6797, #6843)
-
Fix duration/memory config in config objects (#6827)
-
Properly report errors involving newly created types (#6852)
-
Changes to vector length in migrations result in suggesting a
drop
/create
(#6882) -
Report topological cycle errors in migrations as real errors (#6883)
-
Make constraint error details contain useful information for developers (#6796)
-
Fix interaction between DML and
if...then...else
(#6917) -
Don’t leak objects out of access policies when used in a computed global (#6926)
-
Allow grouping to have trailing comma (#7002)
-
Fix computed single scalar globals (#6999)
-
Fix ISE when creating an alias with a name that already exists (#6946)
-
Fix parser at unrecoverable errors (#7046)
-
Improve error when applying a shape to a parameter (#7044)
-
Skip creating @source/@target on derived views improving performance (#7051)
-
Fix issues with cached global shapes and global cardinality inference (#7062)
-
Add error when a constant set is used in singleton mode (#7065)
-
Fix update rewrites on types that are children of updated type (#7073)
-
Make escaping strings more consistent (#7059)
-
Allow an update to trigger an insert of the same type, and vice versa (#7082)
-
Set “Connection: close” for non-keep-alive requests (#7087)
-
Fix volatility of
fts::search
(#7106) -
Allow trailing commas and semicolons in most places (#6963)
-
Drop special handling of type intersection in cardinality inference (#7089)
-
Fix two issues directly reading pointers from a group (#7130)
-
Check singleton expressions in constraints and indexes (#7128)
-
Fix two bugs affecting unions in computed links (#7139)
-
Fix two
group
bugs involvingusing
clauses (#7143) -
Fix deserialization of persistent cache entries after upgrade (#7203)
-
Accept session changes in transactions (#7187)
-
Fix ISEs in constant detection for
fts::with_options
(#7192) -
pg_ext: don’t yield NoData in SimpleQuery (#7200)
-
Make changing
fts
andai
indexes work consistently in migrations (#7218) -
Include
fts
andai
shadow index columns in dumps (#7235)
5.1
5.2
-
Allow multiple authentication methods per transport in
--default-auth-method
. (#7224)We now allow multiple authentication methods to be tried in sequence (according to the specified order in
--default-auth-method
). -
Drop ad-hoc TLS requirement from
JWT
andPassword
auth (#7231) -
Reject
ai
indexes that have different parameters than in parent types (#7229) -
Allow except in link constraints. (#7250)
5.3
-
Force return cast on range get upper and lower functions. (#7251)
-
Prevent dump hangups from leaving stray Postgres queries. (#7262)
-
Switch
EDGEDB_DEBUG_EDGEQL_TEXT_IN_SQL
to encode string asjson
(#7267) -
Don’t inject exclusive conflict checks for updates without children. (#7271)
-
Fix doing a no-op
update
to an exclusive multi pointer with children. (#7272) -
Fix constraint handling when pointer has cardinality or computedness changed. (#7279)
-
Fix regression in using some
tuple
literals as a default. (#7281) -
Make link properties (including @source/@target) work in conflict selects. (#7284)
-
Create key derivation function for signing each different kind of JWTs in the
auth
extension (#7285)This avoids accidentally being able to use other (short-lived) JWT tokens as the
auth_token
JWT directly.
5.4
-
Improve error message when creating union with incompatible types. (#7278)
-
Fix handling of enums in arrays and multi properties for GraphQL. (#3990)
-
Fix modifying global that is used in a policy on a type it refers to. (#7310)
-
Fix a bug involving globals in a somewhat complex interaction with policies. (#7314)
-
Set content-type header for AI extension errors. (#7324)
-
Fix an
UNLESS CONFLICT
on links performance regression. (#7349) -
Fix
EDGEDB_SERVER_CONFIG
configuration of enum values. (#7350) -
Only decode url encoded slashes in db/branch name after splitting path into parts. (#7352)
-
Fix an issue with collection types that affected some migrations. (#7375)
5.5
-
Fix recompilation slowdowns after several migrations (#7099)
-
Fix dumps of types that have both AI and FTS indexes (#7405)
-
Fix single-tenant metrics not to filter by tenant (#7385)
-
Fix rewrite expressions using
__specified__
sometimes generating InvalidReferenceError. (#7392) -
Raise error when using query params in schema. (#7400)
-
Add expression to index friendly name. (#7401)
-
Treat target and link properties as different when expanding splats. (#7402)
-
Remove redundant primary key constraint on ‘id’. (#7418)
-
workflows: Use an explicit label when selecting runners for builds (#7416)
-
Log errors raised when handling ext::ai HTTP requests (#7436)
-
ai: Properly forward non-successful responses from non-streaming chat (#7440)
-
Fix ai::to_context duplication (#7464)
-
Support configuring more arguments with env vars (#7470)
-
Use SQL’s
ON CONFLICT
to implementUNLESS CONFLICT
more often (#7472) -
Fix a race condition where older database configs can overwrite newer ones (#7485)
-
Allow subdomains in redirects in the
auth
extension (#7488) -
Fix tenant shutdown in multi-tenant mode (#7495)
-
Fix migration creation when adding a new base class with certain constraints (#7508)
-
Fix
pg_dump
of an empty schema using the SQL adapter (#7445) -
Fix SQL adapter
COPY
command (#7446)
5.6
-
Fix interaction of implicit limit with explicit OFFSET (#7509)
-
Make persistent query cache work for queries that have no constant literals in them (#7237)
-
Add a
auto_rebuild_query_cache_timeout
config setting that controls how long the server will spend recompiling cached queries after a migration. The default is one minute. (#7518)