How to deploy Discord bot JAR file on Heroku without boot timeout errors

I built a Discord bot and want to host it online for free. I found Heroku which seems perfect but I keep getting this error:

Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 90 seconds of launch

The bot works fine when I run it on my computer but fails on Heroku. I think the issue is that my bot doesn’t bind to Heroku’s port. I tried this in my Procfile but it didn’t work:

web: java $JAVA_OPTS -Dserver.port=$PORT -jar mybot.jar --host=0.0.0.0 --port=$PORT

I’m new to web hosting and ports. The bot connects to Discord successfully (I can see it in the logs) but Heroku still kills it after 90 seconds. How do I make my Discord bot work with Heroku’s port requirements? Is there a different approach I should take for hosting bots?

Another thing to check is whether you have any web server dependencies in your Discord bot code that might be causing conflicts. I ran into similar issues because my bot was accidentally trying to start an embedded web server even though it didn’t need one. If you’re using Spring Boot or similar frameworks, make sure you’re not including web starter dependencies unless you actually need them. Also double-check that your main method isn’t trying to bind to any ports or start HTTP listeners. Sometimes logging frameworks or monitoring libraries can inadvertently create port bindings. The worker dyno approach mentioned above is definitely the right solution, but cleaning up any unnecessary web-related code will make your deployment more reliable and use fewer resources on Heroku’s limited free tier.

The issue you’re encountering is actually quite common with Discord bots on Heroku. Your bot doesn’t need to bind to a port at all since it’s not a web server - it’s just a client that connects to Discord’s API. Change your Procfile to use a worker dyno instead of web:

worker: java $JAVA_OPTS -jar mybot.jar

Then go to your Heroku dashboard, turn off the web dyno completely, and enable the worker dyno. Worker dynos don’t have the 90-second boot timeout restriction that web dynos have. I made this exact mistake when I first deployed my bot last year and spent hours trying to figure out port binding when the solution was much simpler. Keep in mind that Heroku’s free tier has limited hours for worker dynos, so your bot might sleep after a period of inactivity.

yep worker dyno is definitly the way to go. had same probem with my first bot deploy and spent whole weekend debugging lol. just make sure you dont have any spring-boot-starter-web in your dependencies or it will still try to bind to port even as worker dyno