Storage, Formats and Data Rates

Data volume per day, text against binary, compression, SD card endurance, databases, file rotation and retention.

How much data?

Estimate the volume before choosing hardware or format. The data rate is channels × bytes per sample × samples per second; multiply by 86 400 for a day.

bytes per day = channels × bytes per value × samples per second × 86 400

Megabytes per day, 8 channels × 16 bits at 100 samples per second0100200300400500CSV text, ISO timestamp57 bytes per rowCSV text, ISO timestamp: 492.5 MB per day492 MBBinary, 4-byte timestamp each row20 bytes per rowBinary, 4-byte timestamp each row: 172.8 MB per day173 MBBinary, fixed rate (no timestamps)16 bytes per rowBinary, fixed rate (no timestamps): 138.2 MB per day138 MB
Data volume depends on the channels, the rate and the format.

Worked example: eight channels at 100 Hz

  • 8 channels × 2 bytes × 100 Hz = 1.6 kB/s (1 600 bytes/s).
  • In a day: 1 600 × 86 400 = 138.2 MB; in a year 50.46 GB.
  • A 32.00 GB card holds 231 days of that raw data, before adding time stamps, headers and file overhead.

File formats compared

FormatSizeStrengthsWeaknesses
CSV / textLarge (3 to 10 × binary)Opens anywhere; readable; easy to repair; one line per sampleSlow to write and parse; no types; time zone and units are your job
Binary, fixed recordSmallestFast, constant row size so you can seek by index; ideal for microcontrollersNeeds a documented layout and the right tools to read; endianness
HDF5 / NetCDFCompact, compressedSelf-describing, metadata and many channels in one file, chunked accessLibrary needed; not for small microcontrollers; a crash can corrupt the file
Parquet / ArrowCompact, columnarFast analysis with pandas and Spark; typed; compressedWritten in blocks, so unsuitable for streaming a crash-safe log
JSON lines (NDJSON)LargeOne record per line; flexible fields; easy for web toolsLarger and slower than CSV for numbers
Time-series databaseCompact on diskQueries, downsampling, retention and dashboards built inA service to run, update and back up
SQLiteModerateOne file with SQL; transactions; good for small loggersWrite rate and flash wear need care
TDMS, WAV, vendor formatsCompactUsed by instruments and tools you may already ownTied to one ecosystem

File parsing code (Python, C, pandas) is in Data, Files and Parsing. For a first design: CSV for slow data, fixed-record binary for fast data, a database for fleets of loggers.

Worked example: sizes

The same data in text and binary

  • One CSV row (an ISO time, eight values with three decimals): 2026-10-31T10:40:00.250Z,23.456,23.456,23.456,23.456,23.456,23.456,23.456,23.456 is 81 bytes with the newline.
  • One binary row: a 4-byte time count plus 8 × 2 bytes = 20 bytes, 4.1 times smaller.
  • Per day at 100 Hz: CSV 699.8 MB; binary 172.8 MB.
  • A 32.00 GB card lasts 46 days as CSV or 185 days (about 6.1 months) as binary.
  • Integer counts with a documented scale are smaller than floats (uint16 against 4-byte float) and lose nothing if the ADC is 16 bits or fewer.
// 20-byte fixed record on a microcontroller (little-endian, packed)
struct __attribute__((packed)) Record {
    uint32_t t;          // seconds or ticks since the file start
    uint16_t ch[8];      // raw ADC counts
};
static_assert(sizeof(Record) == 20, "record size");
// Write whole records only; add a small header (version, scale, start time) at the start of each file.

Compression

Slowly changing data compresses very well because neighboring values are similar. Delta coding (store the difference from the previous value) followed by a general compressor often shrinks a trend log by 4 to 10 times; random-looking noise hardly compresses.

Worked example: compress the day

At 4:1, the 172.8 MB binary day becomes 43.2 MB. Compression is best applied to closed files (for example, gzip each day’s file at midnight) so that a crash does not lose the compressed stream. A lossless compressor changes nothing in the data; lossy compression (rounding, dropping low bits) must be a deliberate decision that you record.

  • Round to the real resolution: storing 23.4561234 °C from a ±0.5 °C sensor wastes space and suggests accuracy that is not there.
  • Store changes, not levels, when the signal is steady (see Logging Strategies: Triggers, Deadbands and Aggregation).
  • Columnar formats (Parquet) compress each channel on its own and work well for analysis.

Storage media and endurance

MediumStrengthsCautions
SD / microSD cardCheap, large, removable, simpleWear-limited; corrupts if power fails during a write; quality varies. Use industrial or high-endurance cards for continuous logging
eMMC / SSDFast, reliable, larger enduranceNeeds a proper host; SSDs can lose data on sudden power loss unless they have power-loss protection
Serial flash / FRAM (on board)Tiny, cheap; FRAM has near unlimited writesSmall capacity; flash must be erased in blocks
USB stickEasy to collectPoor endurance, fragile connector, inconsistent quality
Network storage / cloudLarge, backed up, remoteNeeds a connection and buffering (see Telemetry, Databases and Dashboards)
Hard diskCheap per terabyteMoving parts; shock and vibration; slow to start

Worked example: how long will an SD card last?

  • Flash is erased in large blocks. Writing 2 000 bytes once a second to a card with 4 096-byte pages still costs a full page program each time: the write amplification is about 2.0 ×, because each write uses only 49 % of a page. Buffer to full pages and write less often.
  • Endurance. A good card might survive about 3 000 program-erase cycles. Ideal wear leveling on a 32.00 GB card allows about 96.00 TB of writes; at 172.8 MB a day that is 1 522 years in theory. Cheap cards, a nearly full card and poor wear leveling cut this by 10 times or more.
  • The bigger risk is power loss during a write, which can corrupt the file system, not just the last record. Write in whole sectors, close or sync files regularly, use a supercapacitor, and design the format so that a partly written file can still be read.
  • Keep the card under about 70 % full; a full card has fewer blocks to level the wear across.

File handling: rotation, flushing and recovery

  • Rotate files (a new file per hour or per day, named by UTC time, cr1_2026-10-31T10.csv): a damaged file loses only a short span, and old files can be moved, compressed and deleted without touching the live one.
  • Flush on a schedule, not every sample and not only at the end: flush() + fsync() (or f_sync() on FatFs) every few seconds trades a small loss on power failure for far less wear and delay.
  • Write a header in every file: logger ID, firmware, start time, channel names, units and scaling, so that each file is complete without the others.
  • Append-only, never rewrite earlier data. If you must update an index, write it to a second file.
  • Include a counter or checksum per record or per block, so that damage is detected (see Data Quality, Analysis and Reporting and the CRC examples in Embedded Systems).
  • Check free space and stop or rotate gracefully rather than failing silently when the card is full; log the event.
  • On restart, start a new file; do not append to a file whose last record may be incomplete.

Databases

A database handles many loggers, many users, queries and retention. A time-series database (InfluxDB, TimescaleDB, Prometheus) stores each measurement against its time and compresses well; a relational database (PostgreSQL, MySQL) suits events, metadata and reports. Row-by-row inserts are slow: batch the writes.

Worked example: database load

  • 8 channels at 100 Hz is 69 120 000 rows a day. At 40 bytes per row (with index overhead) that is 2.76 GB a day.
  • Inserting one row at a time at 800 rows/s is hard on most databases; batching 100 rows per insert cuts the number of transactions to 8 a second.
  • Downsample for storage: keep the raw high-rate data in files, and put one-minute min/mean/max in the database for dashboards (see Telemetry, Databases and Dashboards).
  • Store tags and metadata separately from values, so the units and calibration history are recorded once (see Planning a Logging System).

Retention and backup

Worked example: a tiered retention plan

TierResolutionKept forSize (8 channels)
Raw100 Hz30 days5.18 GB
One-minute min/mean/max1 per minute365 days61.0 MB
Hourly min/mean/max1 per hour10 years10.2 MB

Total about 5.26 GB, against 630.72 GB for ten years of raw data. Choose tiers by what questions will be asked, and write the plan down.

  • Back up off-site and test a restore; a backup that has never been restored is a hope.
  • Keep the original raw files for anything legal, regulatory or contractual; summaries are for convenience.
  • Plan for the data to outlive the logger: document the format, keep a reader program, and prefer open formats (CSV, HDF5, Parquet).

Related

FAQ

CSV or binary?

CSV for slow data and anything people will open in a spreadsheet; fixed-record binary for fast data on microcontrollers; a database or HDF5/Parquet for large, queryable archives. Write a header with units and scaling whichever you choose.

How big a card do I need?

Channels × bytes × rate × 86 400 × the days between collections, doubled for margin. A card should stay under about 70 % full.

Why did my SD card corrupt?

Most often because power was lost during a write. Flush on a schedule, write whole sectors, use a supercapacitor to finish writing, and start a new file at every restart.

How long should I keep data?

As long as it may be needed: keep raw data for weeks to months, summaries for years, and anything with a legal or contractual requirement for the required period.

References

  • SD Association, Physical Layer Simplified Specification; manufacturers’ industrial SD endurance notes.
  • The HDF Group, HDF5 documentation; Apache Parquet documentation; InfluxData and Timescale documentation on retention and downsampling.
  • Kleppmann, M., Designing Data-Intensive Applications (storage and durability).

Last reviewed: October 2026. Card endurance and database sizes are typical and vary widely between products: check the datasheet and measure.