Why Go is a great fit for Discord bots
Go compiles to a single static binary, starts in milliseconds, and idles at a fraction of the memory an interpreted bot needs. Goroutines map naturally onto Discord's event-driven gateway: each event handler runs concurrently without the callback ceremony of other ecosystems. The standard library choice is discordgo, a mature wrapper covering the full Discord API.
Step 1: A minimal discordgo bot
A working bot fits in one file. Note the token comes from the environment, never from source:
package main
import (
"os"
"os/signal"
"github.com/bwmarrin/discordgo"
)
func main() {
dg, _ := discordgo.New("Bot " + os.Getenv("DISCORD_TOKEN"))
dg.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Content == "!ping" {
s.ChannelMessageSend(m.ChannelID, "Pong!")
}
})
dg.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentMessageContent
dg.Open()
defer dg.Close()
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
}Initialise the module with go mod init yourbot and go mod tidy — the go.mod and go.sum files are what the host's build step reads.
Step 2: Choose your deployment stack
MonkeyBytes offers two Go stacks, both compiling server-side so you never cross-compile locally:
- Git stack: point the panel at your repository URL (and optionally a branch). The container clones it, compiles the application, and runs the resulting executable. Redeploying after a push is a restart away.
- Upload stack: upload your project — with
go.modat the container root — via SFTP or the file manager. The stack installs the Go toolchain into the server volume, builds your configured target, and runs the binary. Ideal when your code is not in a public repository.
In both cases set DISCORD_TOKEN in the panel's environment variables (details in the environment variables guide).
Step 3: Start and verify
Start the server and watch the build log in the console: module downloads, compilation, then your bot's own output. Common first-start issues:
- go.mod not found: the file must sit at the container root, not inside a subdirectory — move the project up a level.
- Missing intents: message content requires
IntentMessageContentin code and the toggle in the Discord Developer Portal. - 401 Unauthorized: check the token variable and remember the
"Bot "prefix indiscordgo.New.
The troubleshooting guide covers the rest. Once the bot is online, resource usage in the panel will look almost amusingly low — tens of megabytes is normal for a Go bot.
Production notes
Go's tiny footprint means the free plan's 2 GB RAM is effectively unlimited headroom for most bots, and the compiled binary restarts instantly after crashes or updates. Add graceful shutdown (as in the example's signal handling) so the gateway session closes cleanly on restart. If your bot reaches the scale where sharding matters, discordgo supports it natively — see our scaling guide for when and how.
Frequently asked questions
Can I host a Go Discord bot for free?
Yes. MonkeyBytes hosts Go Discord bots free with 2 GB RAM, 2 GB SSD and 300% CPU. Either point the panel at your git repository or upload a project with a go.mod file — the build happens server-side and the compiled binary runs 24/7.
Do I need to compile my Go bot before uploading?
No. MonkeyBytes compiles server-side: the git stack clones and builds your repository, and the upload stack installs the Go toolchain into your server volume and builds the configured target. You never need to cross-compile locally.
How much memory does a Go Discord bot use?
Very little. A typical discordgo bot idles in the tens of megabytes because Go compiles to a static binary with no interpreter or virtual machine, so the 2 GB free allocation leaves enormous headroom.