Tickers
Fire repeatedly at a fixed interval with time.NewTicker; stop it to release resources.
A time.Ticker fires on a regular interval. Unlike a timer (which fires once), a ticker keeps ticking until you call Stop. Use it to drive polling loops, heartbeats, and periodic flushing.
Create a ticker that fires every 500 ms. Run it for 1.6 seconds by combining a select with a time.After stop signal, then call Stop to release the ticker's resources.
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
stop := time.After(1600 * time.Millisecond)
for {
select {
case t := <-ticker.C:
fmt.Println("tick at", t.Format("15:04:05.000"))
case <-stop:
fmt.Println("stopping")
return
}
}
}Tickers are commonly used for cache refresh, metrics flushing, or keepalive pings in a long-running goroutine:
func startHeartbeat(ctx context.Context, conn net.Conn) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
conn.Write([]byte("ping"))
case <-ctx.Done():
return
}
}
}In production
Tickers fire at wall-clock intervals regardless of how long the tick handler takes. If the handler takes longer than the interval, ticks queue (up to one) and then are dropped. For work that must not overlap, track the last run time and skip if the previous execution is still in flight - or use a timer that you reset after each handler completes rather than a ticker.
Enjoyed this? Get more essays on software craft delivered to your inbox.
Subscribe free