senn-techsenn-tech
Self-Hosting
Self-Hosting2026-10-14· By Franz Senn

Appwrite 2.5 self-hosted: passkeys and interval schedules for functions

Appwrite is an open-source backend for your own apps: authentication, databases, file storage and functions behind APIs and SDKs, which you can run yourself with Docker Compose. Version 2.5 adds passkeys and a new schedule type for functions. heise reported on 14 October, and the 2.5.0 release notes carry the details.

Appwrite logo
The heise report and the 2.5.0 release notes agree in the main points; the release notes give more detail. We have not run Appwrite 2.5 ourselves. (Quelle: Simple Icons, file appwrite.svg (CC0))

Passkeys per project

In the console you can now enable passkeys for a project. For web apps you pick a domain from the registered web platforms; for native Android apps the binding goes through the signing certificate. The release notes add a new database column for Android fingerprints.

One limit concerns the console itself. With console version 1.2.74, signing in to a self-hosted console offers only email and password; the OAuth and passkey buttons are gone. So passkeys are for the users of your own app, not for the admin login. Anyone who signed in through OAuth until now should set up a password account before the upgrade.

Functions every N minutes

Functions can now start at a fixed distance of N minutes, with no cron expression. Appwrite assigns each function a fixed slot inside the interval based on its ID, so hourly jobs do not all begin on the hour, which flattens load spikes. If a job must run at exactly 00:00, keep the cron expression. The setting is under Settings, Executions.

Other changes according to heise and the release notes:

  • The executor moves from 0.29.0 to 1.1.2. Untracked runtimes are removed on startup, which could previously cause restart loops.
  • The usage worker batches writes into the bundled ClickHouse instead of issuing one INSERT per request.
  • On TablesDB, getRow returns the stored row after a transaction commit, no longer a stale version or a 404.
  • PostgreSQL gets a trigram index for startsWith, contains and endsWith. Other backends reject this index type.
  • Operators on encrypted columns answer with HTTP 400 instead of corrupting the stored value.

Upgrading from 2.4

Upgrade from 2.4.0 to 2.5Backupsave the dataInstaller upgradeupgrade entrypointCheck executorimage 1.1.2, only with--use-existing-configMigrationdocker compose exec appwritemigrateTestfunction and login
Order as given in the release notes. The migration adds columns for function intervals and Android fingerprints, and runs longer the more projects exist. (Quelle: Appwrite 2.5.0 release notes)

According to heise, the installer keeps docker-compose.override.yml, custom HTTP and HTTPS ports and the HTTPS setting. With --use-existing-config you have to set the executor image to openruntimes/executor:1.1.2 yourself, otherwise the old executor stays in use. When the new executor starts, runtime containers are removed and cold-start on their next execution, so the first run after the upgrade will probably take longer.

The release notes list no change marked as breaking ("Removed: Nothing"). Two things are still worth knowing beforehand: the changed console login and the gaps when moving projects.

Moving projects

When you move a single project to another installation or to Appwrite Cloud, the release notes say the passkey policy, the password rotation policy and Android fingerprints do not come along. Set them again at the destination. Team memberships receive new IDs, and custom membership IDs are not kept. If your own code stores membership IDs, check that before the move.

Run the migration on a copy before production, especially since its runtime grows with the number of projects.

Further reading

Questions?
How do I upgrade a self-hosted Appwrite from 2.4 to 2.5?+

Per the release notes you run the installer with the upgrade entrypoint, then run docker compose exec appwrite migrate. A backup is recommended first. If you use --use-existing-config, set the executor image to openruntimes/executor:1.1.2 by hand.

What changes for functions?+

A function can run every N minutes instead of using a cron expression. Appwrite derives a fixed slot inside the interval from the function ID, so hourly jobs do not all start at :00. You set the interval in the Settings tab under Executions.

What is lost when I move a single project?+

According to the release notes, the passkey policy, the password rotation policy and Android certificate fingerprints are not carried over and must be set again at the destination. Team memberships get new IDs.