# FlashDB: an embedded key-value and time series database for microcontrollers

> FlashDB is a C database for flash memory on embedded devices, offering a KV store and a time series store in one small library. It fits IoT firmware that needs configuration storage or sensor history without a file system.

**armink/FlashDB** — An ultra-lightweight database that supports key-value and time series data |  一款支持 KV 数据和时序数据的超轻量级数据库

- Repository: https://github.com/armink/FlashDB
- Stars: 2,856 · Forks: 563
- Language: C
- License: Apache-2.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/armink-flashdb

## What FlashDB solves for microcontroller firmware

FlashDB targets embedded products where a file system is too heavy and a plain array in flash is too fragile. The README frames it as an alternative to file-system-based databases: it combines the characteristics of flash and aims to extend flash life while keeping resource use low. It is written in C and licensed under Apache-2.0.

The project serves two distinct needs. The key-value mode stores product parameters, user configuration, and small files as key-value pairs. The time series mode stores timestamped structured data such as temperature and humidity readings, health data from wearables, and operation logs or alarm records. Both modes live in the same library, so a device can keep its settings and its sensor history without pulling in two separate storage stacks.

The audience is firmware engineers on IoT products. The README states that RAM usage is almost zero, which matters on parts where every kilobyte of SRAM is budgeted. The footprint table from an IAR build on stm32f4 lists fdb_kvdb.o at 4,584 bytes of read-only code and fdb_tsdb.o at 1,160 bytes, so the two modes can be adopted independently if code space is tight.

## How FlashDB stores data on raw flash

FlashDB does not sit on a file system. It talks to flash through a port layer, and the repository ships a port/ directory alongside src/ and inc/ for that purpose. The library is split into modules visible in the footprint table: fdb.o for core logic, fdb_kvdb.o for the key-value database, fdb_tsdb.o for the time series database, and fdb_utils.o for shared helpers.

The KV mode supports two value types, string and blob, which the README calls out as a convenience. It also supports incremental upgrade: after a firmware upgrade, the README states that KVDB content supports automatic upgrade, so stored keys are not lost when the schema changes between firmware versions.

The TSDB mode stores records in time sequence. Each record carries a timestamp, and the README notes that a record's status can be modified, which gives the application a way to mark entries as processed or invalid without rewriting history. Both modes support multiple partitions and multiple instances. When data volume grows, the README suggests refining partitions to reduce retrieval time, which is a design lever rather than an automatic optimization.

Two mechanisms address flash's physical limits. Wear leveling spreads writes so that erase cycles are not concentrated on one sector, extending flash life. Power-off protection is claimed for reliability, which matters on devices that can lose power mid-write.

## Installing FlashDB and running a first KV write

FlashDB is not distributed through a package manager in the README. The README points to the documentation site at https://armink.github.io/FlashDB/#/ for a Quick Start, a Porting document, a Configuration document, and an API document. The repository layout shows src/ and inc/ for the library, port/ for platform glue, and samples/ for example code.

A typical integration copies src/ and inc/ into the firmware tree, adds fdb_cfg.h for configuration, and implements the port callbacks for the target flash. The samples directory contains kvdb_basic_sample.c, kvdb_type_string_sample.c, kvdb_type_blob_sample.c, and tsdb_sample.c, which are the closest thing to runnable entry points. The README does not reproduce their source, so read those files directly for the exact call sequence.

For the time series mode, the README's benchmark output uses a shell command, tsl bench, which is part of the project's own test harness rather than a user-facing API:

```shell
msh />tsl bench
Append 1250 TSL in 5 seconds, average: 250.00 tsl/S, 4.00 ms/per
Query total spent 2218 (ms) for 1251 TSL, min 1, max 2, average: 1.77 ms/per
```

Those figures come from the README and describe a W25Q64 NOR flash part; they are not a guarantee for your hardware. A second run on stm32f2 on-chip flash reports 13,421 TSL appended in 5 seconds at 0.37 ms per insert and a query average of 0.12 ms per record.

## Where FlashDB is the wrong choice

FlashDB is a storage layer, not a query engine. There is no SQL, no joins, no aggregation, and no indexing beyond what the KV and time series structures provide. If your application needs ad hoc queries across related tables, FlashDB will not give you that.

It also assumes you can write a port. The repository has a port/ directory and a porting document, but the README does not publish a ready-made driver for every chip. If your flash controller has unusual erase granularity or a vendor SDK that hides the raw interface, the port is real work, and the README is silent on how long that takes.

The RAM claim of almost zero is a design goal, not a measurement you can assume. The footprint numbers in the README come from a specific IAR build on stm32f4; your compiler, optimization level, and enabled features will change them. Similarly, the performance figures come from two named flash parts, W25Q64 and stm32f2 on-chip flash. On a slow SPI flash or a part with large erase blocks, insert and query times will differ.

Finally, the README does not document rollback, migration failure handling, or what happens when a KV incremental upgrade meets an unexpected schema. If your product needs a formal migration story, that gap matters.

## FlashDB compared with SQLite and DuckDB

The related searches around FlashDB include SQLite-adjacent and analytical names, and the comparison is worth making explicit because the tools solve different problems.

SQLite is a relational database that runs on top of a file system and gives you SQL, transactions, and a mature query planner. It assumes an operating system with file I/O. FlashDB assumes the opposite: no file system, direct flash access, and a C API rather than a query language. On a Linux gateway or a Raspberry Pi class device, SQLite is the natural choice. On a Cortex-M part with 64 KB of RAM and a SPI flash chip, SQLite's file-system dependency is the obstacle FlashDB was built to avoid.

DuckDB is an analytical database aimed at columnar query workloads, typically on desktop or server hardware. It is not an embedded flash store and does not target microcontrollers. Mentioning it in the same breath as FlashDB only makes sense if the real question is how to analyze the data after it leaves the device, which is a different stage of the pipeline.

A closer alternative in spirit is a hand-rolled circular log in flash. That avoids the library entirely but leaves wear leveling, power-off recovery, and key lookup to you. FlashDB's value is that it packages those concerns behind a small API, at the cost of learning its port layer.

## Maintenance, licence, and upgrade cost

The repository is not archived, and the last push was on 2026-09-23, which is recent. Release 2.2.0 was published on 2026-03-23, following 2.1.1 in October 2024 and 2.1.0 in December 2023. The release cadence is irregular rather than frequent, so plan for the library to be stable rather than fast-moving.

The licence is Apache-2.0, which permits commercial use and modification with the usual attribution and notice requirements. That is a permissive licence, but it is not legal advice; read the LICENSE file and your own counsel's guidance if the product ships in a regulated context.

Upgrade cost is shaped by two features. KV incremental upgrade means stored keys can survive a firmware update, which reduces migration work. The port layer, however, is yours to maintain. If the upstream port interface changes between releases, you will need to adapt your driver. The README does not publish a compatibility policy, so pin to a release tag and read the release notes before moving.

## Conclusion

Adopt FlashDB if your firmware needs persistent key-value settings or time-stamped sensor records on raw flash and you can write a small port layer for your chip. Do not adopt it if you need SQL, relational joins, or a database that runs on a Linux filesystem, where SQLite or DuckDB is a better fit. Before committing, verify three things on your own hardware: that fdb_cfg.h matches your flash geometry, that your port implements the read, write and erase callbacks correctly, and that the wear-leveling behavior survives your expected write volume. The project's own docs are the only source for the porting contract, so read the porting document before writing the driver.

## FAQ

### Which platforms does FlashDB support?

The repository includes a port/ directory and a Zephyr directory, and the README's performance figures cover W25Q64 NOR flash and stm32f2 on-chip flash. There is no published list of supported chips in the README, so support depends on whether you can implement the port callbacks for your hardware.

### How do I install FlashDB in my project?

There is no package-manager install described in the README. The documentation points to a Quick Start and a Porting document, and the repository ships src/, inc/, port/, and samples/ for integration into a firmware tree.

### What is the difference between FlashDB's KVDB and TSDB modes?

KVDB stores data as key-value pairs and is intended for product parameters, user configuration, and small files. TSDB stores timestamped records in time sequence and is intended for sensor data, health data, operation logs, and alarm records.

## Sources

- [armink/FlashDB on GitHub](https://github.com/armink/FlashDB)
- [Issues](https://github.com/armink/FlashDB/issues)
- [License: Apache-2.0](https://github.com/armink/FlashDB/blob/master/LICENSE)
- [README](https://github.com/armink/FlashDB/blob/master/README.md)
- [Releases](https://github.com/armink/FlashDB/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/armink-flashdb
