Best Practice · OCPP · 7 min read

OCPP Heartbeat Interval: Best Practices

Cellular cost, battery life, CSMS load, NAT keepalive — how to pick the right Heartbeat interval for each deployment type, what happens when you set it wrong, and how to change it without a reboot.

Published · Reviewed against official OCA specification
RC
By Rodolfo Carrillo
Quick answer

The Heartbeat interval is set by the CSMS in the interval field of the BootNotification response. Best practice values: 60 s for cellular (keeps NAT mappings alive), 180–300 s for Wi-Fi, 300–600 s for Ethernet. Too short wastes bandwidth and CSMS resources; too long means slow offline detection and dropped carrier NAT sessions.

What Heartbeat does

In OCPP, the Heartbeat message serves two purposes simultaneously: it acts as an application-level keepalive that proves the connection is alive, and it performs clock synchronization — the CSMS returns its current UTC time in every Heartbeat response, allowing the Charge Point to correct any clock drift.

A Charge Point SHALL send a Heartbeat request if no other OCPP message has been sent during the configured interval. In other words, Heartbeat is a fallback keepalive: if the Charge Point is actively exchanging other messages (MeterValues, StatusNotification, etc.), those messages already prove the connection is alive and Heartbeat is suppressed (Open Charge Alliance, 2015, §4.6).

Purpose 1

Liveness signal

Proves to the CSMS that the Charge Point is connected and responsive. The CSMS uses it to detect when a charger goes offline.

Purpose 2

Clock sync

The currentTime in the response allows the Charge Point to keep its real-time clock aligned with the CSMS, which matters for transaction timestamps and billing accuracy.

How the interval is set

The Heartbeat interval is controlled entirely by the CSMS, not the Charge Point. There are two mechanisms:

  1. BootNotification response — initial value. The interval field in the BootNotification response sets the Heartbeat interval at the moment the Charge Point is accepted. See the BootNotification guide for the full response payload structure.
  2. ChangeConfiguration / SetVariables — runtime update. The CSMS can push a new Heartbeat interval at any time using ChangeConfiguration (OCPP 1.6) with the key HeartbeatInterval, or SetVariables (OCPP 2.0.1) targeting OCPPCommCtrlr.HeartbeatInterval. The change takes effect immediately — no reboot required.
OCPP 1.6 — CSMS pushes new HeartbeatInterval (300 s)
[ 2, "cfg-001", "ChangeConfiguration", "key": "HeartbeatInterval", "value": "300" ]

Message format

The Heartbeat request has the simplest possible payload — an empty object. There are no fields to send. The response contains only currentTime.

CALL — Heartbeat request
[ 2, "hb-001", "Heartbeat", ]
CALLRESULT — Heartbeat response
[ 3, "hb-001", "currentTime": "2025-05-12T10:05:00Z" ]

Too short vs too long

Interval Problems caused
Too short
(< 20 s)
  • Excessive cellular data consumption (each Heartbeat is ~160 bytes but at 10 s intervals it adds up on pay-per-MB SIMs)
  • Unnecessary CSMS CPU and database load — every Heartbeat may write a timestamp row
  • Higher battery drain on DC-powered-only Charge Points in low-power standby mode
  • Risk of triggering CSMS rate limits during burst reconnect events
Too long
(> 600 s on cellular)
  • Carrier NAT state expires — typically after 30–120 s on LTE networks — silently dropping the TCP connection
  • Slow offline detection — CSMS won't notice a failed charger until the dead-time window expires
  • Delayed clock sync — large time drift goes undetected between Heartbeats on devices without NTP
  • False "online" status for chargers that are actually unreachable

Recommended values by connection type

There is no single correct value — the optimal interval depends on the network type, the carrier's NAT timeout, the CSMS's offline-detection policy, and operational requirements. The table below gives production-tested starting points:

📡 LTE / 4G / 5G (cellular)

Most common for public charging, highway chargers, and parking facilities without wired infrastructure.

60 s
recommended
Keep below the carrier's NAT idle timeout (typically 60–90 s on major LTE carriers). At 60 s, NAT mappings stay alive and the CSMS detects offline chargers within ~2 minutes. Do not go below 30 s — cellular latency can cause Heartbeat response delays that look like timeouts.

📶 Wi-Fi (shared or dedicated SSID)

Common in retail, hospitality, and workplace charging. Network quality varies widely.

180 s
recommended
Wi-Fi NAT timeouts are longer than cellular (usually 5–30 minutes on a typical router). 180 seconds balances low traffic with acceptable offline detection speed. If the Wi-Fi network uses a strict firewall, drop to 60 s as a precaution.

🔌 Ethernet (wired LAN)

Fleets, depots, and large-site installations with dedicated wired infrastructure.

300 s
recommended
Wired connections are stable and don't have cellular NAT concerns. 300 seconds (5 minutes) is a reasonable default. Fleets with tight monitoring SLAs can use 60–120 s; depot environments where overnight detection is acceptable can go up to 600 s.

🔋 Battery-backed / solar Charge Points

Off-grid units, rural deployments, or portable charging stations on cellular.

60–120 s
cellular baseline
Cellular NAT timeout still governs the lower bound. To minimise battery drain while maintaining connectivity, use 60 s and implement firmware-level connection pooling or a sleep cycle that reconnects before the NAT expires.

CSMS offline detection

The CSMS dead-time window — the time it waits before marking a Charge Point offline — should be set to at least 2× the configured Heartbeat interval, ideally 3×. This gives the Charge Point two missed Heartbeat cycles before being flagged as offline, accounting for single-packet loss or transient network hiccups.

Mismatched intervals cause false offline alarms

If you change the Heartbeat interval on a Charge Point (via ChangeConfiguration) without updating the CSMS dead-time window, the CSMS will incorrectly mark the charger offline. Always update both values together.

A practical formula: if your Heartbeat interval is H seconds, configure the CSMS dead-time to 3H + 30 seconds. The extra 30 seconds absorbs clock skew and network jitter without producing false alarms.

OCPP 2.0.1 notes

The Heartbeat message is one of the very few things that did not change between OCPP 1.6 and 2.0.1. The request is still an empty object; the response still contains only currentTime. The mechanism for setting the interval changed:

  • Initial interval: still delivered in the interval field of the BootNotification response.
  • Runtime update: uses SetVariables targeting component OCPPCommCtrlr, variable HeartbeatInterval (instead of ChangeConfiguration with key HeartbeatInterval).
OCPP 2.0.1 — SetVariables: update HeartbeatInterval to 60 s
[ 2, "sv-001", "SetVariables", "setVariableData": [ "component": "name": "OCPPCommCtrlr" , "variable": "name": "HeartbeatInterval" , "attributeValue": "60" ] ]

How to test

  1. Validate the Heartbeat frame. The request is trivially simple — paste [2,"hb-001","Heartbeat",] into the Validator to confirm the CSMS accepts the schema. More usefully, validate your Heartbeat response format: paste your CSMS's CALLRESULT with currentTime into the Response tab.
  2. Simulate the full lifecycle. Open the Simulator, connect to a test CSMS, and watch the Heartbeat exchange in the message log. The Simulator shows the exact timestamp returned by the CSMS in each response, making it easy to verify clock sync.
  3. Test offline detection. Start the Simulator, let it send a few Heartbeats, then close the tab without a graceful disconnect. Observe how long your CSMS takes to mark the Charge Point offline — this tells you whether the dead-time window matches the configured interval.
  4. Simulate interval change. From your CSMS, send a ChangeConfiguration with a new HeartbeatInterval while the Simulator is connected. Verify the Simulator's Heartbeat frequency changes in the message log without a session restart.
RC

Rodolfo Carrillo

OCPP integration engineer and creator of OCPP Tools. All articles are verified against the official Open Charge Alliance specification and tested using the on-site tools.

Frequently asked questions

What does the OCPP Heartbeat message actually contain?
The Heartbeat request has an empty payload — no fields at all. The response contains a single field: currentTime, a UTC date-time string. This allows the Charge Point to synchronize its clock with the CSMS on every Heartbeat cycle.
Who sets the Heartbeat interval — the Charge Point or the CSMS?
The CSMS sets it, in two ways: first, via the interval field in the BootNotification response (initial value at boot); second, via a ChangeConfiguration (1.6) or SetVariables (2.0.1) command to update the HeartbeatInterval configuration key at any time during the session.
What happens if a Charge Point never sends Heartbeat?
The CSMS cannot distinguish a silent-but-connected Charge Point from one that has gone offline. Most CSMSes have a configurable dead-time window; once exceeded, the Charge Point is marked offline and may trigger alerts or session cancellation. If no other OCPP message is sent, the session appears frozen.
Does a MeterValues or StatusNotification message reset the Heartbeat timer?
Per OCPP 1.6 §4.6, a Charge Point SHALL send Heartbeat if no other message has been sent within the HeartbeatInterval. Any OCPP message resets the timer on the Charge Point side. However, some CSMS vendors only count explicit Heartbeat or BootNotification as a liveness signal — check your CSMS documentation.
What is the default HeartbeatInterval in OCPP 1.6?
OCPP 1.6 does not mandate a default value. The initial interval is whatever the CSMS returns in the BootNotification response interval field. If the CSMS returns 0, the Charge Point should not send Heartbeats. Common production defaults range from 60 to 300 seconds.
Can the CSMS push a new HeartbeatInterval without rebooting the Charge Point?
Yes. The CSMS sends a ChangeConfiguration (OCPP 1.6) or SetVariables (OCPP 2.0.1) command with key HeartbeatInterval and the new value in seconds. The Charge Point applies the new interval immediately without requiring a reboot.

Sources & further reading

  • · Open Charge Alliance. (2015). Open Charge Point Protocol 1.6, Edition 2, §4.6 — Heartbeat. https://openchargealliance.org/my-oca/ocpp/
  • · Open Charge Alliance. (2015). Open Charge Point Protocol 1.6, Edition 2, Appendix 1 — HeartbeatInterval configuration key. https://openchargealliance.org/my-oca/ocpp/
  • · Open Charge Alliance. (2020). Open Charge Point Protocol 2.0.1, Appendix H §H.1.4 — OCPPCommCtrlr.HeartbeatInterval. https://openchargealliance.org/my-oca/ocpp/
Last technical review: May 12, 2025

Continue learning