Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosAndroid Police: Samsung is smashing records! #shorts #tech #phones(21.09.2026 um 13:55 Uhr)
YouTube Security Videosheise & c't: Bundesnetzagentur wollte diesen Futterautomaten verbieten(21.09.2026 um 13:53 Uhr)
YouTube Security VideosNeil Patel: Your Google Traffic Isn't An Asset It's A Loan #shorts(21.09.2026 um 14:05 Uhr)
Windows Tipps & SecurityF-14 A Tomcat Top Gun endlich als Revell Klemmbausteinmodell erhältlich(21.09.2026 um 14:27 Uhr)
Sichere ProgrammierungShow the Hand-Back Sample Before Approving an Agent Score(21.09.2026 um 14:15 Uhr)
Sichere ProgrammierungHybrid retrieval in one Postgres query: RRF over tsvector + pgvector(21.09.2026 um 14:15 Uhr)
YouTube Security VideosAndroid Police: Samsung is smashing records! #shorts #tech #phones(21.09.2026 um 13:55 Uhr)
YouTube Security Videosheise & c't: Bundesnetzagentur wollte diesen Futterautomaten verbieten(21.09.2026 um 13:53 Uhr)
YouTube Security VideosNeil Patel: Your Google Traffic Isn't An Asset It's A Loan #shorts(21.09.2026 um 14:05 Uhr)
Windows Tipps & SecurityF-14 A Tomcat Top Gun endlich als Revell Klemmbausteinmodell erhältlich(21.09.2026 um 14:27 Uhr)
Sichere ProgrammierungShow the Hand-Back Sample Before Approving an Agent Score(21.09.2026 um 14:15 Uhr)
Sichere ProgrammierungHybrid retrieval in one Postgres query: RRF over tsvector + pgvector(21.09.2026 um 14:15 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Writing a million-row .xlsx from Dart without running out of memory

An FFI wrapper over libxlsxwriter, and the memory numbers that made me reach for it. I had a report endpoint that exported a table to .xlsx. It worked in testing. Then a customer with 400,000 rows hit it and the container OOM-killed the…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

An FFI wrapper over libxlsxwriter, and the memory numbers that made me reach for it.



I had a report endpoint that exported a table to .xlsx. It worked in testing. Then a customer with 400,000 rows hit it and the container OOM-killed the process.



The Dart package most people reach for is excel. It builds the whole workbook as an object graph in memory, serializes it at the end, and hands you the bytes. That is fine for a config sheet with 50 rows. It is the wrong model for a server generating large exports, and the package has had no release since 2024, so the memory behavior is not going to change. There is a maintained fork, excel_community, which is the one to use if you want pure Dart. It is better. It is still an in-memory model.






The measurement



I wrote 100,000 rows by 10 columns and measured peak RSS. Same data, four writers:




























Writer Peak memory

xlsxwriter, constant-memory mode
191 MiB

xlsxwriter, in-memory default
314 MiB
excel_community 614 MiB

excel (unmaintained)
1778 MiB


The single number matters less than the shape. Peak memory as the row count grows:




























Rows constant-memory in-memory default
10,000 ~191 MiB low
100,000 ~191 MiB 314 MiB
1,000,000 ~191 MiB 1433 MiB


The in-memory default climbs with the data. At a million rows it is at 1433 MiB and still going. The constant-memory mode does not move. It stays at ~191 MiB the whole way because it flushes each row to a temp file on disk as you write it, so the row you just wrote is not held anywhere. Nothing accumulates. That flat line is the reason the package exists.



Measured on Apple Silicon with Dart 3.11.






What it is



xlsxwriter is an FFI binding over libxlsxwriter, a mature C library for writing .xlsx. The C library does the XML and ZIP work. The Dart package is the type-dispatch layer and the resource management around it.



The API is close to the C one. You open a workbook, add a worksheet, write cells.




import 'package:xlsxwriter/xlsxwriter.dart';

void main() {
final workbook = Workbook('report.xlsx');
final sheet = workbook.addWorksheet('Data');

sheet.writeString(0, 0, 'Name');
sheet.writeString(0, 1, 'Amount');
sheet.writeString(1, 0, 'Widget');
sheet.writeNumber(1, 1, 12.50);

workbook.close();
}






For the row-at-a-time case there is writeRow, which takes a List<Object?> and dispatches each element by runtime type. String, int, double, bool, DateTime, and null each go to the right cell type.




final rows = queryLargeTable(); // Iterable, not materialized

final dateFmt = workbook.addFormat().numberFormat('yyyy-mm-dd');

var r = 0;
for (final row in rows) {
sheet.writeRow(r++, [
row.name, // String
row.count, // int
row.total, // double
row.active, // bool
row.createdAt, // DateTime, needs dateFmt
row.note, // may be null
], dateFormat: dateFmt);
}






To get the flat memory line, turn on constant-memory mode when you create the workbook. It changes the trade-off. Rows must be written top-to-bottom, because each one is flushed as you go and cannot be revisited.




final workbook = Workbook.constantMemory('big_report.xlsx');
final sheet = workbook.addWorksheet('Data');

var r = 0;
await for (final row in streamRowsFromDb()) {
sheet.writeRow(r++, row.toCells());
}
workbook.close();






You never hold more than one row.






Beyond plain cells



insertImage embeds a PNG or JPEG directly from bytes, so you can drop a chart you rendered elsewhere into a cell:




final logo = await File('logo.png').readAsBytes();
sheet.insertImage(0, 0, logo);






Conditional formatting is there too: cell rules, color scales, and data bars, the same three families libxlsxwriter exposes.






The honest comparison



The fair fight is not against the abandoned excel. It is against excel_community, the fork you would actually pick. Against that fork, xlsxwriter uses 3.2x less memory (191 MiB vs 614 MiB at 100k rows) and runs 1.7x faster.



On throughput alone the fork is close enough that speed would not, by itself, be a reason to switch. Memory is the reason. If your export runs on a box with headroom and never gets large, excel_community is pure Dart, reads as well as writes, and has none of the deployment friction below. That is a real advantage and I would use it there.






When not to use it





  • You need to read .xlsx. This package writes. It does not read. For reading, use excel_community.


  • You target the web. It is an FFI package. It does not run on web.


  • You cannot ship native code. FFI means you need libxlsxwriter present: a C toolchain to build it, or a prebuilt binary for your platform. On a controlled server that is a one-time setup. If your deployment cannot include a native library, use the pure-Dart fork.


  • Your sheets are small. At a few hundred rows none of this matters. Pick whatever reads and writes and stay pure Dart.



The narrow case this is built for is a server writing large .xlsx files where the process has a memory ceiling. That was my case. The flat 191 MiB line is what got the export off the OOM-killer.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Writing a million-row .xlsx from Dart without running out of memory

Thematisch verwandte Begriffe: Writing, millionrow, xlsx, from · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94097 | A vulnerability was determined in Netcore NBR200V2 1.3.241127.071246. Th…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick