I'm using an ESP8266 with deep sleep + wake up when RST pin goes low.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
WiFiClient client;
HTTPClient http;
RTC_DATA_ATTR int bootcount = 0;

void setup() {
    bootcount ++;
    WiFi.begin("MySSID", "password");
    while (WiFi.status() != WL_CONNECTED) {
    // here I send "bootcount" with HTTP request
void loop() {

Here RTC_DATA_ATTR int bootcount = 0; fails with RTC_DATA_ATTR unknown.

How to get the number of times the ESP8266 has woke up from deep sleep?

  • 1
    RTC_DATA_ATTR is for esp32
    – Juraj
    Dec 10, 2022 at 11:17
  • Thanks @Juraj, you're right, I think you can post this as an answer. Does this mean it's not possible to count the number of times the ESP8266 has resumed/rebooted from deep sleep? How to save/restore a number in RTC memory?
    – Basj
    Dec 10, 2022 at 14:26

1 Answer 1


The ESP8266 RTC has 512 bytes of RAM that persist across restarts but not during power outages. While this RAM isn't persistent across power outages it also doesn't have the write limitations that flash memory has, making it appropriate for frequent writes which don't need to survive power loss.

The ESP32's compiler and software framework make it easy to access similar memory on it using the RTC_DATA_ATTR attribute; unfortunately as you found and @Juraj pointed out, the ESP8266's doesn't.

Thankfully the Arduino core for the ESP8266 includes support for reading and writing this area of memory using methods in the ESP object.

ESP.rtcUserMemoryRead() reads RTC memory and ESP.rtcUserMemoryWrite() writes RTC memory. In your case you could do something like this:

void setup() {
  uint32_t bootcount;

  if(!ESP.rtcUserMemoryRead(0, &bootcount, sizeof(bootcount))) {
    Serial.println("RTC read failed!");


  if(!ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount))) {
    Serial.println("RTC write failed!");

  Serial.print("boot count is ");

void loop() {

Not quite as convenient as the RTC_DATA_ATTR attribute but it still gets the job done.

I changed the type of bootcount from your example to uint32_t because it should never be negative, and the size of uint32_t is independent of the size of int.

Because the Arduino core is open source, you can read the implementation of these functions if you want to know how they work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.