# Gadget is shutting down: a migration plan for Shopify app developers

> Moving off Gadget means replacing more than a database. Map your Shopify app to Postgres, application hosting, auth, scheduled jobs, and queues before the March 2027 shutdown.

Published: 2026-11-12
Canonical: https://layerbase.com/blog/gadget-shutting-down-shopify-migration

[Gadget announced its shutdown on November 9](https://gadget.dev/blog/gadget-wind-down). Existing apps can keep running until March 31, 2027. New app creation has stopped, first production deploys are allowed through the end of November, and regular support ends at year-end. After that, the team will concentrate on critical issues and keeping the service running. The announcement says migration guides and tools will follow.

If you maintain Shopify apps for clients, I would use the remaining support window to resolve export and authentication questions. March is the shutdown date; December is the more useful deadline for getting answers from the people who know the platform.

I run Layerbase, which can host the database part of the replacement. It is not a complete Gadget alternative: **Layerbase does not replace application hosting, Shopify OAuth, file storage, or Gadget's Shopify sync.** Those need their own migration work. Here is how I would split it up.

## Inventory the app before choosing replacements

For each client app, list its models, actions, scheduled tasks, connected shops, uploaded files, and external APIs. Trace one real operation through them. An order webhook might update a model, enqueue an action, fetch more Shopify data, and send an email. Moving the model does not move that behavior.

| What Gadget handled | Where it goes | Work you still own |
| --- | --- | --- |
| Application records | Managed PostgreSQL | Export, schema mapping, relationships, IDs, and validation |
| App server and actions | An application host you choose | Routes, action code, secrets, deployment, and monitoring |
| Shopify installation and API access | Your app's Shopify integration | OAuth or token exchange as appropriate, scopes, sessions, and uninstall handling |
| App-user login | An auth library such as Better Auth | Account migration, login routes, email delivery, and session policy |
| Shopify data sync | Webhook handlers and reconciliation workers | Initial backfill, retries, rate limits, and keeping records current |
| Scheduled database work | PostgreSQL scheduled jobs | SQL tasks on an awake database |
| Background HTTP work | A queue delivering to your app | Idempotent handlers and recovery procedures |
| Uploaded files | Object storage | Copying files, permissions, URLs, and references |

Ask Gadget which export paths cover your app's data and files. Do not assume access to a raw Postgres connection or a complete SQL dump. Rehearse the export and import with a disposable target before promising a client a cutover date.

## Move the records into Postgres

Layerbase offers [managed PostgreSQL](/create/postgresql) with standard connection strings. That gives your replacement app somewhere to store shops, orders, sync checkpoints, and its own business data. It does not recreate Gadget's generated APIs or model actions.

Keep original source IDs during the import. For Shopify records, make the shop part of your identity and authorization model so one merchant's records cannot be returned to another. Validate relationship counts and representative records, not just the number of imported rows.

The first import is a rehearsal. You still need a plan for changes made while the old app remains live: a final export during a controlled write pause, or a separately tested catch-up process. A successful import alone does not establish that you can switch traffic without losing updates.

## Separate SQL cron from application jobs

Layerbase's [scheduled jobs](/docs/scheduled-jobs#requirements) run SQL through pg_cron on a supported PostgreSQL version. They suit database-local work such as refreshing a summary table. They do not run your JavaScript actions, and pg_net is not supported, so they cannot call the Shopify API over HTTP.

**A schedule does not wake a sleeping database.** Missed runs are skipped, not replayed on wake. For work that must run on time, use a paid plan and pin the database always-on. Paying for a plan alone does not pin it. Configure that explicitly and verify the run history.

Put API calls, emails, and longer processing in your application runtime. Use that host's scheduler or another suitable scheduler to trigger recurring application work. Keeping SQL cron and application scheduling separate makes it much easier to identify which component failed when a client reports a stale dashboard.

## Valkey and VQueue cover different jobs

Valkey can hold cache data. [VQueue](/docs/vqueue), included with Layerbase Valkey even on Free, delivers HTTP jobs to a public endpoint in your app, with retries and a dead-letter queue. It supports a documented subset of the `@upstash/qstash` client, not every QStash feature and not Gadget action code.

VQueue delivery continues during database hibernation, unlike pg_cron. A stopped database or restricted account defers attempts. Queue records live outside the Valkey dataset and are not part of its database backups.

There is a material limit for a migration plan: **VQueue's host-loss recovery and failover are not yet qualified.** Do not make it the only record of an irreplaceable order-processing job. Keep reconstructable work in durable application records and build a reconciliation path, or choose a queue whose recovery guarantees meet the workload. Check the current usage and retention limits in the setup guide before switching.

## Better Auth does not replace Shopify OAuth

[Better Auth supports PostgreSQL](https://better-auth.com/docs/adapters/postgresql). It can handle login for your application's own users while storing auth records in a Layerbase database. Layerbase also offers an [auth setup flow](/docs/auth), but your application still runs the authentication routes and supplies its provider and email configuration.

Shopify app installation, merchant authorization, and access tokens are a separate concern. Verify what can be transferred from the existing app before assuming merchants will stay connected. Likewise, do not promise that existing passwords or sessions will survive a switch to Better Auth. Confirm the export format and compatibility; otherwise plan account recovery and a fresh sign-in.

## Rebuild sync around a recovery path

Consider a small order-reporting app. The replacement receives a Shopify webhook, authenticates it, records the event durably, and returns promptly. A worker updates the shop's order records and records completion. A reconciliation job finds missed changes and unfinished work.

Shopify documents [signature verification and duplicate delivery handling](https://shopify.dev/docs/apps/build/webhooks/verify-deliveries). Treat repeated events as normal: the second delivery must not send a second customer email or apply the same business operation twice. Keep enough state to retry safely, and test recovery after the worker stops between saving data and acknowledging completion.

Before switching, exercise an initial backfill, a duplicate webhook, a delayed event, a failed API request, and an uninstall. Compare the resulting app state with Shopify. The database can store the answers; your integration is responsible for obtaining and maintaining them.

## Budget for the whole replacement

Layerbase's [current plans](/pricing), checked November 12, are Free at $0, Solo at $5/mo, and Pro at $15/mo. Free includes two databases and 5 GB of storage with idle sleep. Solo includes two databases and capacity to keep one always-on. Pro includes up to ten databases sharing its included resource pool; ten databases is not ten dedicated servers.

Those are database-plan prices. Application hosting, object storage, transactional email, and any separate scheduler or queue are additional choices and costs. Shared plans have bandwidth fair-use allowances, so a flat bill does not mean unlimited transfer.

For a small app, start by rehearsing its data import into a [free Postgres database](/create/postgresql). Then prove one complete workflow on the replacement stack. Only after that should you schedule the production cutover, including a final catch-up, a rollback boundary, and someone watching failed jobs. Keep the old system available until you have verified the new one and reconciled writes made after the switch.
