Is NVS iteration order maintained?

Bryght-Richard
Posts: 98
Joined: Thu Feb 22, 2024 3:59 pm

Is NVS iteration order maintained?

Postby Bryght-Richard » Fri Dec 19, 2025 2:59 pm

After writing key+values into NVS, is the iteration order maintained across power cycles? Across defrags? Across deletions and insertions?

Examples:
  • If I write keys "A", "B", "C", would the iteration order then be "A", "B", "C"?
  • If I write keys "A", "B", "C", then delete "B", would the iteration order then be "A", "C"?
  • If I write keys "A", "B", "C", then write key "D", would the iteration order always be "A","B","C","D"?

Context: I need to implement a nonvolatile ring buffer - if `nvs_entry_find()/next()` always return keys in insertion order, it simplifies locating the oldest object for garbage collection. I've tried a few, and it seems ok, but not to the point I'd rely on it. It seems possible, since NVS is a log-structured filesystem(ish).

nopnop2002
Posts: 347
Joined: Thu Oct 03, 2019 10:52 pm
Contact:

Re: Is NVS iteration order maintained?

Postby nopnop2002 » Thu Dec 25, 2025 1:45 am

I think you can use nvs_get_blob/nvs_set_blob.

Here is example.
https://github.com/espressif/esp-idf/tr ... vs_rw_blob

ESP_rrtandler
Posts: 53
Joined: Wed May 31, 2023 6:54 pm

Re: Is NVS iteration order maintained?

Postby ESP_rrtandler » Mon Jan 05, 2026 4:00 pm

Hi @Bryght-Richard ,

NVS doesn't guarantee the order of iterator.

To write and read as if it was ring buffer, you can introduce "iterable" naming convention for keys of your individual buffer entries.
For example for buffer of length n, keys would be like "0", "1", "2"...."n-1". Keep your actual write and read pointers under predefined keys like "wp" and "rp" as for example u8 (unsigned 8 bit, if n<256) value.
Instead of iteration using NVS iterators, you derive the key to be directly read from (written to) by sprintf-ing the value obtained from "wp" or "rp" by calling nvs_get_u8. After writing (or reading) the data, you advance (and wrap over the ring buffer size) the respective pointer value and update it using nvs_set_u8. Using integers also helps detecting the number of unread messages.

Who is online

Users browsing this forum: No registered users and 3 guests