Discord Bots

Migrating Your Discord Bot From Replit, Heroku or Railway

A step-by-step plan for moving a Discord bot off Replit, Heroku, Railway or Render — inventory, data export, environment variables, cutover and cleanup.

On this page
  1. Why bots outgrow general-purpose platforms
  2. Step 1: Take an inventory
  3. Step 2: Clean up platform-specific code
  4. Step 3: Export your data
  5. Step 4: Set up the new server
  6. Step 5: Cut over without duplicates
  7. Step 6: Move scheduled jobs
  8. Step 7: Clean up
  9. Common migration problems
  10. Summary

Plenty of bots start on a general-purpose platform — Replit, Heroku, Railway, Render — and move once the limits start to bite: idle sleeping, keep-alive hacks, usage-based bills that are hard to predict, or resources that don’t fit a long-running bot. Migrating sounds daunting, but for most bots it takes well under an hour. This guide gives you a plan that avoids downtime and duplicate responses.

Why bots outgrow general-purpose platforms

These platforms are excellent at what they were designed for, which is mostly web applications. Bots have different needs:

  • A bot must run continuously. Services that sleep when they receive no HTTP traffic disconnect your bot from Discord’s gateway. That’s why so many Replit bots include a tiny web server and an external pinger — a workaround, not a solution.
  • Free tiers change. Heroku removed its free dynos in November 2022, and other platforms have adjusted free allowances over time.
  • Usage-based pricing is great for spiky web traffic, but a bot that runs 24/7 pays for every hour.
  • Ephemeral filesystems. Some platforms reset local files on every deploy or restart, so SQLite databases and JSON files quietly disappear.

A host built for long-running processes removes all four problems. More background is in free PaaS platforms vs dedicated bot hosting.

Step 1: Take an inventory

Before touching anything, write down what your bot depends on. You’ll need:

Item Where to find it
Runtime and version package.json engines, .python-version, runtime.txt, or the platform’s settings
Start command Procfile (e.g. worker: node index.js), .replit run = line, or platform settings
Environment variables Platform dashboard → Secrets / Config Vars / Variables
Data files SQLite files, JSON “databases”, uploaded assets
External database Heroku Postgres, Replit DB, Railway Postgres or MySQL, a third-party database
Scheduled jobs Heroku Scheduler, cron add-ons, platform cron
Webhooks or dashboards Any HTTP endpoint the bot exposes

Copy the environment variable names and values somewhere safe and private. You’ll recreate them on the new host.

Step 2: Clean up platform-specific code

Most bots have a little platform glue worth removing:

  • Keep-alive servers. The Flask keep_alive() file or Express “ping” server exists only to stop the platform sleeping. On an always-on host, delete it and cancel the external pinger.
  • Replit DB. Replit’s key-value database only works on Replit. Export it (below) and move to SQLite or MySQL.
  • Hard-coded paths. Replace paths like /home/runner/... with paths relative to your project.
  • Platform environment names. Code that checks for platform-specific variables (like REPL_ID) to decide behaviour should use your own variable instead, such as NODE_ENV=production.

Make sure dependencies are complete: every package in package.json or requirements.txt. Replit in particular sometimes installs packages automatically on import, which hides missing entries until you deploy elsewhere.

Step 3: Export your data

Heroku, Railway or Render PostgreSQL

pg_dump "$OLD_DATABASE_URL" --no-owner --no-acl -Fc -f bot.dump
pg_restore --no-owner --no-acl -d "$NEW_DATABASE_URL" bot.dump

MySQL

mysqldump --single-transaction -h old-host -u user -p botdb > bot.sql
mysql -h new-host -u user -p botdb < bot.sql

Migrating a database with mysqldump and pg_dump covers flags and pitfalls in detail. Every Kerit Cloud plan includes a MySQL database (paid plans also offer PostgreSQL), and the team can handle a database migration for you if you open a ticket.

Replit DB

Write a short script that runs on Replit and dumps every key to a JSON file, then download it:

import json
from replit import db

with open("export.json", "w") as f:
    json.dump({k: db[k] for k in db.keys()}, f)

On the new host, import the JSON into SQLite or MySQL with a one-off script.

Files

Download SQLite databases and any data files while the bot is stopped, so you don’t copy a file mid-write.

Step 4: Set up the new server

On Kerit Cloud:

  1. Create a server on the free tier or a Discord bot plan, choosing the same runtime version you used before.
  2. Link your GitHub repository for push-to-deploy, or upload your files via the file manager or SFTP.
  3. Recreate every environment variable in the panel.
  4. Set the start command — the part after worker: in your Procfile is usually exactly right.
  5. Upload data files (SQLite databases, JSON) to the same relative paths.

Don’t start it yet if the old bot is still running.

Step 5: Cut over without duplicates

If both copies run with the same token, both connect to Discord and your bot answers every command twice — or they fight over interactions and fail with “already acknowledged”. Cut over in this order:

  1. Stop the bot on the old platform.
  2. Take the final data export (so no writes are lost).
  3. Import the data on the new host.
  4. Start the bot on the new host and watch the console for the ready line.
  5. Test your main commands in a server.

The gap is usually a minute or two. For bots where even that matters, schedule the switch during your quietest hour.

Step 6: Move scheduled jobs

Heroku Scheduler and similar add-ons don’t come with you. Either move the schedule into the bot itself (a setInterval, node-cron, or discord.ext.tasks loop) or, on a VPS, use cron. Schedules inside the bot should store their state so a restart doesn’t skip or repeat a run — see cron jobs and scheduled tasks.

Step 7: Clean up

Once the bot has run happily for a day or two:

  • Delete the old deployment so it can’t start accidentally.
  • Remove old environment variables from the platform, and rotate any secrets that were stored there if you’re closing the account.
  • Cancel the external uptime pinger if you only used it as a keep-alive — or repoint it at a proper health check.
  • Update your README with the new deploy process.

Common migration problems

The bot runs but data is missing. The data export happened before the old bot stopped, or files were uploaded to the wrong path. Check paths relative to your working directory.

Cannot find module or ModuleNotFoundError. A dependency the old platform installed automatically isn’t in your dependency file.

Different behaviour on a different Node or Python version. Match the version you used before, then upgrade deliberately later.

It answers twice. The old copy is still running somewhere. Stop it and reset the token if you can’t find it.

Summary

Migrating a bot is mostly bookkeeping: list the runtime, start command, environment variables and data; remove keep-alive hacks and platform-specific storage; export your database and files; recreate the setup on the new host; then stop the old bot before starting the new one. With a bit of preparation, the whole move takes minutes, and the result is a bot that stays online without workarounds.