diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go
index fc342e821871667f3d4fe7aab18e5d50e225674a..580cce9887cee1874415258b7e0923158dd6f1e0 100644
--- a/protocols/bgp/server/fsm.go
+++ b/protocols/bgp/server/fsm.go
@@ -84,7 +84,7 @@ type FSM struct {
 	holdTimer          *time.Timer
 
 	keepaliveTime  time.Duration
-	keepaliveTimer *time.Timer
+	keepaliveTimer *time.Ticker
 
 	msgRecvCh     chan msgRecvMsg
 	msgRecvFailCh chan msgRecvErr
@@ -125,7 +125,7 @@ func NewFSM(peer *Peer, c config.Peer, rib *locRIB.LocRIB) *FSM {
 		holdTimer:          time.NewTimer(0),
 
 		keepaliveTime:  time.Duration(c.KeepAlive),
-		keepaliveTimer: time.NewTimer(0),
+		keepaliveTimer: nil,
 
 		routerID: c.RouterID,
 		remote:   c.PeerAddress,
@@ -458,7 +458,10 @@ func (fsm *FSM) openSent() int {
 				if fsm.holdTime != 0 {
 					fsm.holdTimer.Reset(time.Second * fsm.holdTime)
 					fsm.keepaliveTime = fsm.holdTime / 3
-					fsm.keepaliveTimer.Reset(time.Second * fsm.keepaliveTime)
+					if fsm.keepaliveTimer != nil {
+						fsm.keepaliveTimer.Stop()
+					}
+					fsm.keepaliveTimer = time.NewTicker(fsm.keepaliveTime)
 				}
 
 				fsm.processOpenOptions(openMsg.OptParams)
@@ -624,7 +627,6 @@ func (fsm *FSM) openConfirm() int {
 				fsm.connectRetryCounter++
 				return fsm.changeState(Idle, fmt.Sprintf("Failed to send keepalive: %v", err))
 			}
-			fsm.keepaliveTimer.Reset(time.Second * fsm.keepaliveTime)
 			continue
 		case c := <-fsm.conCh:
 			if fsm.con2 != nil {
@@ -782,7 +784,6 @@ func (fsm *FSM) established() int {
 				fsm.connectRetryCounter++
 				return fsm.changeState(Idle, fmt.Sprintf("Failed to send keepalive: %v", err))
 			}
-			fsm.keepaliveTimer.Reset(time.Second * fsm.keepaliveTime)
 			continue
 		case c := <-fsm.conCh:
 			c.Close()