Auto restart mechanism for our Go programs


As a golang developer, ensuring that our Go programs run reliably and uninterrupted is paramount. One way to achieve this is by implementing an auto restart mechanism. However, unlike Node.js, Go does not have a popular process manager like pm2 that provides this functionality out-of-the-box. However, this doesn’t mean that Go developers are left without options. Thankfully, we can leverage the powerful Linux built-in service manager called systemd to achieve similar functionality.In this tutorial, we will explore how to use systemd to create a reliable and robust auto restart mechanism that restarts our Go programs on failure. So, let’s dive in!


  • Systemd overview and how it be of use in our case.
  • Create a test program.
  • Create a custom systemd service/unit file.
  • Load and start our service.

Systemd and it’s role?

Systemd is a powerful init system and service manager available in most Linux distributions. Although systemd can manage a variety of resources represented by units, in this tutorial our focus will be on systemd service units utilizing which we can define and manage services, including our Go programs, with features like auto restart upon failure. This will let us harness the capabilities of systemd to create a reliable auto restart mechanism for our Go programs.

Create a test golang server

An example scenario where an auto restart functionality could be necessary is when developing a server or REST API that needs to remain operational at all times. Therefore, for the sake of this tutorial we will keep things simple and create a basic http server that responds with “OK”. The process will be same for any other go program.

package main

import (

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "OK")

	if err := http.ListenAndServe(":8080", nil); err != nil {

Next we need to build our server

go build -o go_server

Create and define a systemd service

Now all systemd resources including services are represented by units and are configured using unit files, which include settings such as the program’s path, user privileges, restart conditions etc. Therefore, for systemd to be able to mange our go executable, we will need to first create what is known as a unit file of type service which defines our service. So, let’s call our service my_custom_server. Please note that all service unit files have a .service extension. So here the unit file for our my_custom_server service would be my_custom_server.service

Now a simple question that may come to our mind is where do we create our custom my_custom_server.service file? Well, for services that apply to the entire system, the convention is to place our custom .service file into /etc/systemd/system. So let’s create our unit file.

cd /etc/systemd/system
sudo nano my_custom_server.service
Description=My custom golang server



Basic service unit file overview

  1. [Unit]: – defines basic info about our service
    • Description: This line provides a brief description of the unit which in this case is “My custom golang server”

  2. [Service]: – defines our service
    • Restart=always

      This line specifies the restart behavior of the service. If the service fails or killed, systemd will automatically restart it. We can also use on-failure which will only restart in case of non-zero exit code.

    • WorkingDirectory=/root/myprogram

      This line sets the working directory for the service and ensures that the service executes in the specified directory. In this case, it’s set to /root/myprogram.

    • ExecStart=/root/myprogram/go_server

      This line defines the command to start the service. It specifies the executable file or command systemd will execute when starting the service. In this case, it points to the /root/myprogram/go_server executable.

  3. [Install]:

      This line specifies the target that the unit should be associated with during installation. The “” is a standard target in systemd that represents the normal multi-user system state. By specifying “,” the unit will be enabled and started when the system reaches the multi-user state during boot.

Load and start our service

To make systemd aware of our custom service file we just created, we will need to reload systemd daemon using the below command.

sudo systemctl daemon-reload

So with our systemd service activated, we will have control over starting, stopping, and restarting our Go program using systemd commands as shown below.

Start our service

sudo systemctl start my_custom_server

Check service status

sudo systemctl status my_custom_server
check my_custom_server service status
check my_custom_server service status

List our service

sudo systemctl list-units --type=service
list all our services
list all our services

Verify our auto restart mechanism

So to verify the effectiveness of our auto restart mechanism, we will intentionally terminate our my_custom_server service and observe whether systemd automatically restarts it. This test will provide assurance that our Go program remains reliable and resilient.

sudo systemctl kill my_custom_server
kill my_custom_server service
kill my_custom_server service

After sometime hopefully systemd will restart our service and it will up again.

my_custom_server service restarted by systemd
my_custom_server service restarted by systemd

Restart our service

sudo systemctl restart my_custom_server

Stop our service

sudo systemctl stop my_custom_server

Ensure our service starts on reboot

sudo systemctl enable my_custom_server
enable my_custom_server service
enable my_custom_server service


In this tutorial, we demonstrated how to implement an auto restart mechanism for our Go programs using systemd services by leveraging systemd’s capabilities. With the auto restart functionality in place, our Go programs will experience enhanced reliability, guaranteeing uninterrupted operation.

Leave a Reply

Back To Top