Sign in with Discord, Google, GitHub, or email and password. Free hosting works with any sign-in method and requires a verified email address. Claim a free bot and choose JDA, or pick a paid plan if the bot needs a larger heap. Java processes spend part of the allocation on the runtime itself, so a free server is only comfortable for a small bot. Starter is $0.99 a month. Pro and Plus add memory and CPU. Every number on the pricing page is an allocated limit.
Build the jar
Use a current JDA release and a Java 21 toolchain locally so the bytecode matches the image. Package a single jar with the dependencies shaded in. Name it bot.jar, or change JAR_FILE to the name you upload. The token still belongs in BOT_TOKEN. In the main class, read the environment variable and pass it to JDABuilder. Do not store the token in application.properties inside the jar, because that file is easy to commit.
Enable the gateway intents JDA requests. If the builder enables the message content intent, the developer portal must enable it too, or login fails with a close code. A missing token fails fast. Leave that failure visible. Catching it and looping hides the problem and looks like a crash loop.
Step-by-step: deploy a JDA bot.
Start on the host
Upload the jar in the file manager, or connect a public GitHub repository and turn Auto update on. The next start clones it while keeping existing files. Press start. The console should show JDA's login line and then your own ready log. If the jar is missing, the Java process exits immediately. Check JAR_FILE and the working directory. If Gradle is enabled and gradlew is absent, the build step fails and the old jar, if any, is what you should inspect. Turn the build flag off when you upload a jar by hand.
Update from GitHub
Public GitHub deploy is included on Free; private repository tokens require a paid plan. The account page connects one repository and one branch to the server. GitHub sends a signed push to this host. The host checks the signature, ignores every event except a push to that branch, and restarts the server. On startup, auto-update must be 1. The script fetches the branch and resets tracked files to that commit, then prints DEPLOY_COMMIT. A Gradle project with BUILD_ON_START set to 1 rebuilds the shadow jar after the fetch. The token variable is not part of the git tree. An untracked data directory is left alone because the script does not clean untracked files.
Give GitHub only the push event and the application/json content type. Paste the secret from the connect page. If the signature does not match, nothing restarts. Replace the connection if you lose the secret. Debounced pushes collapse to the newest commit, so a burst of commits becomes one restart.
Operate it
Watch the memory graph after the first hour. A heap that sits on the limit will be killed. Move up a plan rather than disabling the limit. Back up any files you cannot rebuild, because a deleted free server does not keep them. See pricing before the bot outgrows the box it is in.