Migrate from Appwrite Cloud to self-hosted Appwrite

A planning guide for moving a complete Appwrite project from Appwrite Cloud to your own infrastructure, covering what transfers, the cutover sequence, and what drives effort.

On this page

How to migrate from Appwrite Cloud to self-hosted Appwrite

A team usually moves an Appwrite project off Appwrite Cloud because it needs the data, users and backend logic inside its own infrastructure, whether for residency, tighter control or cost. The work is normally led by a platform or backend engineer acting as migration lead, with help from whoever owns the database, networking and backups. The effort is set mostly by how much preparation the target install needs, not by the copy itself. Appwrite Migrations can transfer a complete project in either direction, so the risk sits in what surrounds the transfer: databases, storage, functions, domains and client configuration. Confirm the exact project scope the Migrations feature covers in the Appwrite Migrations docs before you plan the cutover.

Start with the target. Install Appwrite on infrastructure you control, using the Docker or Helm route described in the self-hosting documentation, and size it for the project you are moving. Two decisions matter most. First, choose the database engine: new installs provision PostgreSQL by default, with MariaDB and MongoDB also supported, and the choice should match the data you are moving and your team's operating skills. Second, decide where production datastores live. The Helm chart documentation says the built-in PostgreSQL, Redis, ClickHouse and object storage each run a single replica without failover, so plan managed services or operators for production. Also confirm the Appwrite version on both sides, since a mismatch can block the import. Ask the migration lead to record the target version and the Cloud project ID in the runbook before the first test run.

Plan the cutover around three checks. Run at least one full test migration into a non-production install, then compare user counts, database documents, file counts and function deployments against the Console on Appwrite Cloud. Re-point every client SDK endpoint and any webhooks, OAuth redirect URLs and custom domains to the new host, and test sign-in from each platform. Finally, verify that functions run on your Open Runtimes executor and that files in storage open correctly. Keep Appwrite Cloud available in read-only form until these checks pass, and confirm with your own security team how logs, backups and access roles will be handled on the new install, since those controls become yours to run.

Which Appwrite Cloud capabilities move cleanly to self-hosted Appwrite

This table maps each capability listed in the Appwrite README to its status after a project moves to self-hosted Appwrite, marked clean, needs rework or gap. Cloud-only plan mechanics such as resource limits, project freezing, overage alerts and budget caps do not carry over, so set your own capacity monitoring. DocumentsDB and VectorsDB ship disabled in Appwrite 2.0 until their PostgreSQL or MongoDB engines are enabled.

CapabilityStatus on self-hosted AppwriteWhat to confirm or rework
AuthCleanUsers and sessions move with the project transfer. Confirm password hash types and re-enter OAuth provider credentials on the new install.
DatabasesNeeds reworkNew installs default to PostgreSQL. Match the engine to your schema, and enable DocumentsDB or VectorsDB only after their engines are deployed.
StorageCleanFiles transfer with the project. Plan your own object storage capacity and backups, since the Helm chart's built-in object storage runs one replica.
FunctionsNeeds reworkFunctions run on the Open Runtimes executor. Recheck runtime versions, and re-enter environment variables and secrets.
SitesNeeds reworkTest the self-hosted build and hosting path for your frameworks and domains before cutover.
MessagingNeeds reworkEmail, SMS and push need your own provider credentials. Cloud sending limits do not carry over.
FirewallGapConfirm which Firewall rules are available self-hosted, then rebuild any rules you rely on at the edge or proxy.
RealtimeCleanSubscriptions run through the realtime service. Test client reconnects after you re-point SDK endpoints.
MCPGapConfirm availability and endpoint behavior on your self-hosted version before using it for agent access.

What data, users and integrations to move and rebuild

A project move covers more than rows and files. Users, password hashes, functions, buckets and client endpoints each follow a different path, and some pieces have no export at all. Treat each of the cards below as a separate workstream with its own check before cutover.

Complete projects through Appwrite Migrations

Appwrite Migrations is the documented path for moving a whole project, so start there and inventory what it carries before you assume anything is covered. Compare the migrated project's databases, collections, buckets, functions and users against the Cloud Console, item by item. Record anything the migration does not transfer, because that list becomes your manual rebuild backlog. Confirm the Appwrite version on the target matches what the migration tooling expects.

User password hashes via the Users API

Moving users without forcing password resets depends on the hash algorithm. Appwrite's Users API accepts imported Scrypt modified, bcrypt, Argon2, MD5, PHPass, Scrypt and SHA hashes, along with their parameters. Before cutover, confirm which algorithm each source user record uses and that you can supply every parameter the import needs. Test a sample login on the target with a known account, and plan a forced reset for any hash type you cannot import.

Functions and their runtimes

Functions are not a simple data copy. Each deployment depends on a runtime version, environment variables and secrets that Cloud may hold in a way you cannot export directly. Check that the self-hosted executor supports every runtime your functions use, and redeploy them from source you control. Record each function's triggers, schedules and execution permissions, since these settings are easy to lose during a rebuild.

Storage buckets and file permissions

Buckets and their files move with the project, but the permission rules, file size limits and encryption settings should be verified rather than assumed. Compare object counts and checksums for a sample of files in each bucket after the copy. Confirm that file previews and any server-side transforms your app relies on behave the same on the self-hosted instance. Plan for the storage backend you chose during install, since it sets where files physically live.

SDK endpoints and client configuration

Every client app points at a Cloud endpoint and project ID, and those values live in builds, environment files and mobile releases. Change the endpoint in each Web, Flutter, Apple, Android, React Native and Unity client, and in each server SDK, before the cutover date. Mobile apps already in the store cannot be changed remotely, so decide whether they need a dual-endpoint period. Test sign-in, reads, writes and realtime subscriptions against the new endpoint.

Webhooks and third-party integrations

Webhooks, payment providers, email services, analytics and CI jobs that call the Cloud API are the integrations most often forgotten. Build an inventory from your code, your secrets store and your vendor dashboards, then recreate each webhook against the self-hosted URL with a new signing secret. Confirm which integrations accept an endpoint change and which need their own reconfiguration. Assign an owner to each item so none is left pointing at the old project.

Migration sequence from inventory to decommissioning Appwrite Cloud

This sequence moves one Appwrite Cloud project at a time into a self-hosted Appwrite install, proving the path on a pilot before users are moved and ending with a documented retirement of the Cloud project. Each step produces a written artifact that the next step depends on.

  1. Inventory every Cloud project and its dependencies

    Start by listing each project in the Appwrite Cloud organization, with its plan, databases and collections, storage buckets, functions and deployed sites, auth methods enabled, messaging providers, and custom domains. Record current plan usage against limits, including monthly active users, storage and bandwidth, so you know which projects are close to a freeze or overage. Note which SDK clients point at each project endpoint, because those changes are needed at cutover. The output is a written inventory list, reviewed by the application owners, that marks which projects are in scope and which are retired instead of moved. Confirm with Appwrite which project data Appwrite Migrations transfers in each direction before you rely on the list.

  2. Prepare the target Appwrite install

    Build the self-hosted target from the installation guide, which lists 2 CPU cores, 4 GB of RAM, 2 GB of swap and Docker Compose version 2 as the starting point, and confirm the image tag matches the Cloud release line you intend to run. Decide the database engine (new 2.0 installs provision PostgreSQL by default, with MariaDB and MongoDB also supported), and plan replication, backups and object storage for production, since the Helm chart docs state the built-in datastores run a single replica without failover. Set up DNS, TLS and SMTP for the new endpoint. The output is a signed-off target environment with a tested restore of its backups, documented in a build record.

  3. Run a pilot project on the target

    Choose one low-risk project with a representative mix of auth users, collections, buckets and at least one function, then migrate it to the target with Appwrite Migrations. Compare user counts, document counts, file counts and checksums or sampled records against the Cloud source, and test the password hash path: confirm that imported users can sign in without a reset where the source hash format is supported. Deploy a function, verify its environment variables and runtime behavior, and check that file downloads and permissions match. The output is a pilot report listing every mismatch, its cause and its fix, and a decision to proceed or to re-run the pilot.

  4. Run a parallel period with Cloud still live

    For each production project, keep Appwrite Cloud serving users while the self-hosted copy is brought up to date and tested with a staging client build pointed at the target endpoint. Schedule incremental syncs or re-migrations as your process requires, and rerun the comparison checks from the pilot against the latest data. Test sign-in, realtime subscriptions, webhooks, email delivery, file uploads and function triggers on the target. Track every write path that could still hit Cloud so none are missed. The output is a parallel-run checklist signed by the application owner, showing each check passed, the known gaps and who accepted them.

  5. Execute the cutover from a runbook

    At the agreed window, freeze writes on the Cloud project, run the final migration delta, and verify the counts and sampled records again. Ship the client update that changes the SDK endpoint to your self-hosted domain, along with any server-side SDK keys, and update functions and webhooks that call the old endpoint. Point DNS or the reverse proxy at the new install and watch error rates, sign-in success and storage requests. Keep a rollback path to Cloud documented until the new install has run stably. The output is a cutover runbook with timestamps, the final verification results, the client release versions and the rollback decision.

  6. Decommission Appwrite Cloud and record the retirement

    After the agreed stability period, export any remaining records you must keep, remove or disable the Cloud project and its custom domains, revoke API keys and webhooks that still point at Cloud, and confirm that no client or service still calls the old endpoint. Check the billing state for the organization, including any Pro overage or budget settings, so no charges continue for retired projects. Where your compliance process requires it, retain logs and evidence of the migration. The output is a retirement record for each project listing the data disposition, key revocations, billing confirmation and the owner who approved closure.

How the migration changes by project size and starting point

A single project on the Free or Pro plan is the simplest case. The project has one set of users, a modest database and a handful of storage buckets or functions, so the migration usually runs as one Appwrite Migrations job into a freshly installed instance. The installation floor is modest: the installation guide lists 2 CPU cores, 4 GB of RAM, 2 GB of swap and Docker Compose version 2, and the setup wizard runs on port 20080 after a docker run command using the appwrite/appwrite:2.5.0 image. Free-plan projects that reach a resource limit freeze in read-only mode on Appwrite Cloud, so plan the cutover before that happens.

  • Install on a single host: A Docker Compose install on one server is enough to validate the migration.
  • Confirm the plan limits: Check your current usage against the pricing page before you schedule the cutover.
  • Test users first: Import a small set of accounts and sign in with each password hash type.
  • Keep the Cloud project read-only for a window: This prevents writes that would be missing from the copy.

Before cutover, confirm that the single host has the resources the installation guide lists and that you have a tested backup of the new instance's data.

What the self-hosted target must provide before cutover

The stock Docker Compose install and the official Helm chart run their built-in PostgreSQL, Redis, ClickHouse and object storage as single replicas, and Appwrite's Helm chart documentation states these run without replication or failover. Before cutover, decide which of these components move to managed services or operators that you can back up, fail over and patch on your own schedule. The database is the first decision, because the migrated users, documents and file metadata all land there. Confirm the current default datastore layout and replica behavior against the Appwrite self-hosting installation guide and the Kubernetes chart docs for the exact version you are deploying, since defaults change between releases.

Restore testing matters more than backup scheduling. Take a full backup of every datastore the target uses, restore it into a separate environment, and confirm that users can sign in, that storage objects open with their original permissions, and that function deployments still execute. Repeat this restore test after the migration dry run, not only before it. Monitoring should cover API and worker health, realtime connections, database connection saturation, disk growth on storage and ClickHouse, and TLS certificate expiry on the custom domain you will re-point SDKs to. Alert routes should reach the people who will be on call after cutover, not only the migration team.

Plan upgrades across the 2.x line before you go live. Appwrite 2.0 changed the underlying engine and new installs provision PostgreSQL by default, while existing 1.9.x installs need a migration path. Appwrite 2.5.0 followed on October 13, 2026, so your target version will likely move again within weeks of cutover. Write down who runs each upgrade, how you rehearse it against a restored copy, and how you roll back if a worker or database migration fails. Keep DocumentsDB and VectorsDB disabled unless you have deployed the PostgreSQL and MongoDB engines they require. Track changes through the Appwrite GitHub releases page.

What drives the cost and duration of the move

The effort of moving from Appwrite Cloud depends less on the Appwrite install itself than on what sits inside each project. Projects, files, functions, user records and integrations each add work, and some of that work is one-time while the cost of running the target stack recurs.

Projects, databases and collections

Each Appwrite project is migrated as a unit, so the number of projects, databases and collections sets how many migration runs, schema checks and permission reviews you need. Count them first and note which projects share naming, roles or API keys. Confirm with your Appwrite contact whether a single migration run can cover several projects in your environment, or whether each project needs its own pass.

Storage volume and file transfer

Files in Appwrite Storage move over the network and must land in your own object storage backend. Total size, file count and bandwidth available between the two environments all shape the transfer window. Note that the Pro plan lists 150 GB of storage per project, so a project near that figure is a larger job than a small one. Plan a verification step that compares file counts and checksums on both sides.

Functions and their runtimes

Each function needs its runtime, dependencies, environment variables and triggers confirmed on the self-hosted side. Functions that call third-party APIs need their secrets re-entered and their outbound network paths tested. Functions are often the least documented part of a project, so inventory them with their owners before estimating. Check that the runtimes you rely on are available in the Open Runtimes executor of your target install.

Auth methods and password hashes

Users who sign in with passwords can keep their logins only if the password hash type is accepted by the import path. Appwrite's Users API accepts several hash families, but the source format on the Cloud side determines whether you can migrate without forced resets. Count users per login method, including OAuth and magic links, and test a sample of each before cutover. Users who cannot be migrated cleanly will generate support work after the switch.

Integrations, residency and staff time

Webhooks, SDK clients in mobile apps, CI pipelines and third-party services each need a new endpoint or credential. Residency and network rules may require the target install to sit in a specific region or behind a private network, which affects hosting choices and firewall changes. Staff time covers the platform team, the application owners who test, and the security reviewers who approve the new data path. Estimate each group separately in your project plan.

One-time work and recurring run costs

Migration work, test cycles, cutover planning and rollback rehearsal are one-time costs. Servers, storage, backups, managed PostgreSQL or operators, upgrades and on-call coverage recur every month and every release cycle. Appwrite releases move quickly, so budget for upgrade work across the life of the install, not only for the first move. Ask any quote to separate one-time and recurring lines, and to state which items are included in the written scope.

What usually goes wrong when moving Appwrite projects and how to prevent it

Will users be forced to reset passwords after moving from Appwrite Cloud?

Users are forced to reset passwords only when their password hashes cannot be imported into the target install. Appwrite's Users API accepts several imported hash types, including Scrypt modified, bcrypt, Argon2, MD5, PHPass, Scrypt and SHA, so check which algorithm and parameters your existing users use before you start. Export the hashes from the source project, confirm each algorithm is on that list, and test a sample login on the target install. Users whose hashes cannot be carried over will need a reset flow, so plan a message and a fallback path for them. Ask the team that owns authentication to produce a count of users per hash type before the cutover date.

What breaks when client apps still point at the Cloud endpoint?

Client apps keep calling Appwrite Cloud after cutover if the endpoint is hardcoded in builds, environment files or mobile releases. The fix is to move the endpoint, project ID and any allowed platform or hostname entries into configuration that you can change without a new store release. Check CORS and platform registrations on the new install for every web origin, mobile bundle ID and package name, because a missing origin fails in the browser while the same call may work from a server. Keep the old project read-only for a defined period so older app versions fail visibly rather than writing somewhere unexpected. Test each client build against the target before the switch.

Why do functions fail after moving to self-hosted Appwrite?

Functions usually fail because they depend on settings, variables or external services that exist only in the Cloud project. Inventory every function, its runtime, its environment variables, its scheduled executions and any secrets or third-party API keys it reads. Rebuild those values in the target install, and confirm the Open Runtimes executor in your deployment can run each runtime version the functions declare. Check outbound network access from the executor, since a firewall rule that was never needed on Cloud can block an API call. Run each function against test data and compare its output with the Cloud result before you rely on it.

How do I confirm storage files arrived intact?

A migration that reports success does not prove every file is present, readable and attached to the right record. Compare file counts and total sizes per bucket between source and target, then sample files by checksum and open a representative set of them through the client SDK. Check file permissions as well, because a bucket that was public or private on Cloud must keep the same access rules on the new install. Verify that documents referencing file IDs still resolve after the move. Record the comparison results in a sign-off document so the storage owner can accept the transfer in writing.

Is a single-replica Appwrite install safe for production data?

A single-replica install is not suitable for production data unless you accept downtime and data loss on node failure. Appwrite's Helm chart documentation states that the built-in PostgreSQL, Redis, ClickHouse and object storage each run a single replica without replication or failover, and recommends managed services or operators for production data. Decide before the migration which datastores will be managed or operated with replication, and document the recovery point and recovery time your business needs. Restore a backup into a separate environment at least once before go-live, because an untested backup gives no assurance. Ask your platform team who is on call for each datastore after cutover.

What goes wrong when Cloud and self-hosted run in parallel?

Running both platforms in parallel without a write rule splits data between them, and records created on one side never appear on the other. Choose a single system of record for each collection and user population, then freeze writes on the other side during the final sync. Be explicit about which clients write where during the overlap, and route any remaining traffic through a single configuration switch. After cutover, reconcile documents created during the overlap window and confirm no users hold sessions that conflict with the new install. Assign one owner to approve the freeze and the reconciliation check.

Can our own team run this migration, or do we need outside help?

A team with Docker or Kubernetes operations experience and a clear test plan can run a small Appwrite migration without outside help, provided it has time to rehearse the move. The effort depends on the number of projects, users, functions, storage volume and client apps, plus how many datastores need replication or managed services. DeployOpen plans, implements, integrates, hardens, backs up, documents and supports self-hosted platforms in your own infrastructure, and most engagements are fixed-scope with scope, deliverables and timelines agreed in writing before work starts. DeployOpen does not publish a price list, so ask for a quote based on a written scope that lists the projects, datastores and client apps involved.

How DeployOpen scopes and runs the migration

DeployOpen plans, implements and hardens the self-hosted Appwrite install inside your own cloud account, data center or air-gapped network, then runs the migration of your Appwrite Cloud project and supports the cutover. Our work covers the target install itself (the Docker or Helm deployment, the database engine choice, backups, TLS, access control and the functions executor), the Appwrite Migrations run, validation of users, documents, storage buckets and functions against the source project, and the change to SDK endpoints in your client apps. Most engagements are fixed-scope, so the scope, deliverables and timelines are agreed in writing before any work starts, and a quote follows from that written scope.

The written scope is where the decisions get made. Expect it to settle which Appwrite release you target, which database engine backs the install, whether production data sits on managed PostgreSQL or an operator instead of the single-replica built-in datastores described in the Helm chart documentation, how Appwrite Cloud users with password hashes move across, and who signs off on the cutover window and rollback point. Your own team typically owns access to the Appwrite Cloud project, the DNS and certificate records, and the approval of each validation result. Ask DeployOpen to list these owners and their dependencies in the scope document so that delays do not surface mid-migration.

Once the migration is live, ongoing support, upgrades and continuous testing are available as retainers, so the patch and release cadence of Appwrite does not have to fall on an internal team alone. Confirm the retainer terms, response expectations and upgrade handling in writing with the quote, not from this page. DeployOpen prepares the systems, controls and evidence your auditors will ask for, but it does not issue audit reports, attestations or certifications; independent auditors and certification bodies do that work.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.