How to use the time.After() function in Go

The time.After() function in Go is used to create a channel that sends a signal after a specified duration. When the specified duration elapses, a value is sent on the channel, allowing you to use it for timing and triggering actions after a certain delay. Such triggering actions can be used, such as updating a status or sending notifications in a real-time application.

Syntax

The function time.After() is defined under the time package, so make sure that you import it before using it. We will see what parameters and return does the time.After() function offers.

func After(d Duration) <-chan Time
After function definition in Go

The parameter d is the time duration that will elapse before a value is sent on the channel. The function returns a channel of type <-chan time.Time, which sends the current time after the specified duration has elapsed.

Code

We will explore different ways in which we can use the time.After() in real Go applications. It is important to note that some distributed systems require triggering actions at certain times for which such functions are necessary.

Example 1

We will see an example of using the time.After() to trigger an action after a certain delay.

package main
import (
"fmt"
"time"
)
func main() {
startTime := time.Now()
fmt.Println("Start time:", startTime)
timer := time.After(1 * time.Second)
fmt.Println("Waiting for 1 second...")
endTime := <-timer
fmt.Println("Action triggered after 1 second at:", endTime)
}

In this example, the program sets a timer for 1 second using the time.After(1 * time.Second). After waiting for 1 second, it receives the value from the timer channel, representing the end time when the action is triggered. The action will be triggered after waiting for 1 second.

Example 2

In this example, we will see another use of the time.After() . You can use the time.After() in conjunction with a select statement to implement timeouts or perform periodic tasks at regular intervals.

package main
import (
"fmt"
"time"
)
func main() {
startTime := time.Now()
fmt.Println("Start time:", startTime)
// Create a timer for 2 seconds
timer := time.After(2 * time.Second)
// Create a channel to simulate some other event
otherEventChan := make(chan string)
// Simulate some other event that sends a value to the otherEventChan after 1 second
go func() {
time.Sleep(1 * time.Second)
otherEventChan <- "Other event occurred"
}()
// Use the select statement to wait for either the timer or the otherEventChan
select {
case <-timer:
fmt.Println("Timer fired after 2 seconds")
case msg := <-otherEventChan:
fmt.Println("Received message from otherEventChan:", msg)
}
endTime := time.Now()
fmt.Println("End time:", endTime)
}
  • Lines 1316: We have a timer channel created by the time.After(2 * time.Second) that triggers after 2 seconds, and a separate channel otherEventChan that simulates another event occurring after 1 second.

  • Lines 1922: A new goroutine (concurrent function) is created using the go keyword. The goroutine contains a function that simulates another event occurring after a delay of 1 second. A message is sent to the otherEventChan channel after 1 second.

  • Lines 25–30: We use the select statement to wait for either the timer channel or the otherEventChan to receive a value. Whichever event happens first will be handled, and the respective message will be printed to the console.

As noted, we'll be able to see that the otherEventChan will receive the message first because it contains a message after 1 second, whereas the timer channel will get a message after 2 seconds.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved