Retiring self-hosted apps without leaving loose ends
An application can disappear from your phone while its server keeps running. It may still restart after a crash, answer through a tunnel, hold an API key, or write backups nobody needs. Removing the client ends your use of the app. Retiring the service means closing the paths and dependencies that remain.
Treat retirement as a small change with a clear finish. Identify what belongs to the application, preserve what you may need, stop new activity, and verify the result. Keep shared infrastructure working throughout.
Start with the service and its dependencies
Write down the service name, where it runs, and who still uses it. Check the things that call it: scheduled jobs, webhooks, mobile clients, monitoring checks, and other applications. A quiet dashboard does not prove that nothing depends on its API.
Separate dedicated resources from shared ones. An app may have its own hostname and database but share a tunnel, reverse proxy, storage volume, or service account. Removing a shared component can turn a routine cleanup into an outage for unrelated services.
Set a short observation period if usage is uncertain. Look at relevant logs and ask known users. Choose a retirement date rather than leaving the app in an indefinite half-disabled state.
Preserve enough to recover deliberately
Export the configuration and any data you need to keep. Record the application version, storage locations, and a brief recovery procedure. Keep credentials out of ordinary notes; reference their protected storage instead.
A backup is useful only if you understand what it contains. An application with a database may need an application-aware export or a coordinated backup. Copying a live database directory does not automatically produce a usable recovery point.
Decide when retained data and backups should be deleted. Some records need longer retention; other data should not stay around just because storage is available. Use a stated purpose and retention date rather than “keep everything.”
Stop the work and close the access paths
Stop the application and disable its automatic restart mechanism. Check the service manager, container restart policy, scheduled tasks, and any supervisor that could bring it back. Remove or disable jobs and webhooks that would keep trying to call it.
Then remove the app's public routes: its DNS records, reverse-proxy entries, tunnel routes, and dedicated firewall exceptions. Check both IPv4 and IPv6 where relevant. Review access policies as a separate layer, after closing the routes that rely on them.
For Cloudflare Tunnel, a DNS record and a running tunnel are separate objects. Cloudflare documents that a tunnel DNS record can remain after the tunnel stops. Check the hostname and route explicitly. Remove only the retired application's entries when the tunnel serves other apps. See Cloudflare's tunnel DNS documentation.
Revoke dedicated credentials
Inventory the app's API keys, service tokens, database login, OAuth grants, and notification integrations. Revoke credentials dedicated to the retired app. Remove its grants from shared accounts without disabling access that other services still need.
If an app used a shared secret, first identify the other consumers. Move them to separate credentials where practical, then rotate the shared value in a planned change. Deleting a secret from your notes does not revoke it at the issuing system.
For example, Cloudflare provides explicit revocation for Access service tokens. Use the provider's revocation control and verify its documented effect rather than assuming that deleting a client configuration ends access. See Cloudflare's service-token documentation.
Verify from more than one place
Confirm the process is stopped and stays stopped. Check the public hostname after relevant DNS caches expire. An expected DNS failure or retired response is useful evidence, but also check that no alternate route still reaches the origin.
Test neighbouring services that shared the tunnel, proxy, or host. Update the inventory and remove obsolete alerts only after recording the retirement. State what was retained, where it is protected, and when it should be reviewed or deleted.
Retirement is finished when the app no longer runs or accepts traffic, its dedicated credentials are revoked, and its remaining data has an owner and a retention plan.