Matlab Choose Big Data Solution
MathWorksOfficialCreated by MathWorks
- Skill
- Guidelines
- Data and AI
- BSD-2-Clause
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured decision framework for handling large tabular data in MATLAB when standard in-memory functions like readtable fail. It guides users through selecting the appropriate datastore pattern based on data format and processing requirements, such as continuous dataset analysis via tall arrays or independent file-level processing via transform. It also covers advanced scenarios like building custom datastores for proprietary formats and migrating legacy in-memory code to scalable datastore-based workflows.
What it does
- Identifies the correct datastore type for CSV, Parquet, Excel, and MDF files.
- Determines whether to use tall arrays for continuous data or transform for per-file processing.
- Provides migration paths for code hitting out-of-memory errors.
- Guides the implementation of custom datastore classes for non-standard or proprietary formats.
- Advises on parallel execution strategies using parallel pools or mapreducer.
- Enforces a pre-flight check to prevent unnecessary complexity for small datasets.
When to use it
- When processing large tabular files that cause out-of-memory errors.
- When working with multiple tabular files that need to be treated as a single dataset.
- When you need to scale up existing in-memory data processing workflows.
- When you need to build a custom datastore for proprietary or non-standard file formats.
- When you need to process files independently (per-file or per-row-group).
Advantages
- Prevents out-of-memory errors by processing data in manageable chunks.
- Provides a unified interface for diverse file formats.
- Enables seamless scaling from local execution to parallel or cluster computing.
- Reduces development time by providing clear decision paths and code patterns.
- Ensures efficient data handling by avoiding unnecessary full-file loads.
Usage examples
- “My MATLAB code crashes with an out-of-memory error when reading a 20GB CSV file. How can I fix this?”
- The agent will guide you to use tabularTextDatastore combined with tall arrays to process the file in chunks without loading it entirely into memory.
- “I have a folder of 500 Excel files and I need to calculate the mean of each file independently. What is the best way?”
- The agent will recommend using spreadsheetDatastore with the transform function, setting the read granularity to file-level to process each file separately.
- “I have a custom binary file format that MATLAB does not support natively. How do I create a datastore for it?”
- The agent will provide a guide on subclassing matlab.io.Datastore and implementing the necessary methods to integrate your custom format into the datastore ecosystem.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/matlab/matlab-choose-big-data-solution/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-choose-big-data-solution.zip -d .agents/skills
Documentation by MathWorks
Choose Big Data Solution
Help users and agents select the right MATLAB tool for large tabular data in file-based formats (CSV, Parquet, delimited text, spreadsheets, MDF). The skill encodes a decision flowchart — recommend one clear path, not a menu of options.
When to Use
User or agent has large tabular data in file-based formats (CSV, Parquet, delimited text, spreadsheets, MDF)
User or agent says data is "large", "big", or "huge" (even without a specific size)
User or agent hits an out-of-memory error with
readtable,parquetread, or similarUser or agent has multiple tabular files to process as a single dataset
User or agent has multiple tabular files to process independently (per-file)
User or agent asks how to scale up an existing workflow on tabular file data
User or agent asks about datastores, tall arrays, or mapreduce
User or agent needs to build a custom datastore class for a proprietary or non-standard format
User or agent has large XML, JSON, HTML, or Word document files —
readtablesupports these formats but the built-in datastores do not. Scaling these requires a custom datastore (see "Formats Without a Built-in Datastore" and "Custom Datastores" sections below)
When NOT to Use
Single file that fits in memory (file-size-to-RAM ratio < 0.5) — see Pre-Flight Check and
matlab-import-export-dataskillUser or agent is working with MAT files —
matfileprovides partial I/O for large.matfiles, different workflowUser or agent is working with databases (SQL, ODBC) — use Database Toolbox. See the
matlab-use-databaseandmatlab-use-duckdbskills in thereporting-and-database-accesscategoryUser or agent needs GPU acceleration — different domain
Deep learning training workflows — datastore is correct for data loading, but use
minibatchqueuefor batching (not tall or transform)
Pre-Flight Check
ALWAYS run this check BEFORE recommending datastore or tall array patterns. Estimate the file-size-to-available-RAM ratio (accounting for in-memory expansion of the file format).
| Condition | Route | Rationale |
|---|---|---|
| Single file, ratio < 0.5 | Native MATLAB I/O (readtable, parquetread) | Fits in memory; datastore/tall adds unnecessary complexity |
| Single file, ratio ≥ 0.5, OR user/agent reports OOM | Continue to Decision Flowchart below | Data may not fit in memory |
| Multiple files | Continue to Decision Flowchart below | Datastore patterns provide unified multi-file access |
| Size unknown and user/agent describes data as "large", "big", or "huge" | Continue to Decision Flowchart below | Assume large until proven otherwise |
If the data fits in memory (single file, ratio < 0.5): recommend native I/O and stop. Mention that datastore and tall array patterns exist if the data grows beyond memory in the future, but do not implement them now.
Decision Flowchart
Follow this flowchart strictly. Present ONE recommended path, not multiple alternatives. Only mention alternatives if the situation is ambiguous.
Is the data described as "large" or causing OOM?
│
├── YES
│ │
│ ├── Is the goal to process all data as ONE continuous dataset?
│ │ │
│ │ └── YES → Datastore + Tall Arrays
│ │ Choose datastore by format:
│ │ CSV/delimited text → tabularTextDatastore
│ │ Parquet → parquetDatastore
│ │ Excel (.xlsx/.xls) → spreadsheetDatastore
│ │ MDF (.mf4/.mdf) → mdfDatastore (requires Vehicle Network Toolbox)
│ │ Other formats → Custom Datastore
│ │
│ └── Is the goal to process each unit INDEPENDENTLY?
│ │
│ ├── One read = one FILE
│ │ CSV/delimited text → tabularTextDatastore
│ │ Excel (.xlsx/.xls) → spreadsheetDatastore
│ │ Other formats → Custom Datastore or fileDatastore
│ │
│ └── One read = one ROW GROUP
│ Parquet → parquetDatastore
│
└── NO / UNCLEAR
└── STOP. Ask: (1) what is the file format? (2) do you need to process
all data as one dataset, or each file/unit independently?
Do NOT show code until these are answered.
Optional (requires Parallel Computing Toolbox):
├── Speed up tall arrays locally → Open a parallel pool
├── Speed up readall on transforms → UseParallel
└── Speed up tall arrays on Hadoop/Spark → mapreducer (also requires MATLAB Parallel Server)Critical rules:
When the processing goal is unclear (continuous vs per-file), STOP and ask before writing any code. Do not show code examples, do not generate scripts, do not demonstrate both approaches. Ask which applies and wait for the answer. The correct response to ambiguity is a short clarifying question, not a menu of options with code for each.
When data is described as "large", NEVER lead with
readtableorparquetreadFor per-file or per-row-group processing, NEVER suggest tall arrays (tall merges all data into one dataset and has no concept of file or row group boundaries)
For Parquet, the natural independent unit is the row group, not the file —
parquetDatastoredefaults toReadSize = "rowgroup". Do NOT forceReadSize = "file"on a Parquet datastore unless the workflow truly needs whole-file granularityFor parallelism, recommend parallel pool FIRST; mapreducer is only for Hadoop/Spark
Do NOT present manual chunking (while/read loops) as the first option — tall arrays handle chunking automatically
Do NOT present multiple options — follow the flowchart and recommend ONE clear path
Datastore + Tall Arrays (continuous dataset)
Use when: processing one large file OR multiple files as a single dataset. Use the datastore matching the format (see Decision Flowchart above).
% Single file
ds = tabularTextDatastore("largedata.csv");
tt = tall(ds);
% Multiple files
ds = tabularTextDatastore("data/*.csv");
tt = tall(ds);
% For example, compute statistics with the tall array and gather results.
% Tall handles chunking automatically. Specify DataVars to avoid errors
% on non-numeric columns.
result = groupsummary(tt, "GroupVar", {"mean", "std"}, "NumericVar");
result = gather(result);Key points:
Most common functions work on tall:
mean,std,min,max,groupsummary,sortrows,topkrowsCombine multiple gathers:
[a, b] = gather(tallA, tallB)
For effective tall usage — deferring evaluation to minimize passes, previewing
without exhausting memory, indexing rules, known-good workarounds when a function
does not support tall, and validating tall output against the in-memory result —
see references/tall-array-effective-use.md. Consult it before hand-rolling a
workaround for an unsupported operation: an incorrect workaround can silently
produce wrong results.
DuckDB alternative (R2026a+): When the goal is to filter, aggregate, deduplicate, or sample a large file down to a small in-memory result, a single DuckDB query may be faster than datastore + tall. DuckDB queries CSV/Parquet/JSON files directly without loading them into memory. Requires Database Toolbox.
conn = duckdb();
result = fetch(conn, "SELECT * FROM read_csv_auto('large.csv') WHERE Region = 'West'");
close(conn);For complex DuckDB workflows, see the matlab-use-duckdb skill in the
reporting-and-database-access category.
Migrating from readtable (OOM on large files):
% Before:
T = readtable("large.csv");
stats = groupsummary(T, "Category", "mean");
% After:
ds = tabularTextDatastore("large.csv");
tt = tall(ds);
stats = gather(groupsummary(tt, "Category", "mean"));tabularTextDatastore uses a stricter textscan-based parser. Key gotchas:
TextTypemust be set at creation time — read-only after constructionTrimNonNumericunsupported — read as%q, strip on the tall array%ferrors on non-numeric content — read as%q, convert withstr2doubleExtraColumnsRuledoes not exist — append"%*[^\r\n]"toTextscanFormatsdetectImportOptionsdoes not apply — configure via datastore properties directly
See references/readtable-to-datastore-migration.md for the full property mapping.
Migrating from parquetread: Replace with parquetDatastore + tall. Types
are preserved exactly — no format specifier issues. All parquetread options
map 1:1 to datastore properties. See references/parquetread-to-datastore-migration.md.
Datastore + Transform (per-file)
Use when: each file in a folder should be processed independently (per-file statistics, per-file transformations, file-level aggregation).
% Set up datastore to read one file at a time
ds = tabularTextDatastore("data/*.csv");
ds.ReadSize = "file";
% For example, compute statistics by transforming the datastore with a custom function.
tds = transform(ds, @computeFileStats);
results = readall(tds);
function out = computeFileStats(data)
numVars = vartype("numeric");
out = table( ...
min(data{:, numVars}, [], 1, "omitmissing"), ...
max(data{:, numVars}, [], 1, "omitmissing"), ...
mean(data{:, numVars}, 1, "omitmissing"), ...
VariableNames=["Min", "Max", "Mean"]);
endFor Excel files, use spreadsheetDatastore instead of tabularTextDatastore.
spreadsheetDatastore defaults to ReadSize = "file" so no override is needed.
For per-sheet processing (e.g., statistics per worksheet), set ReadSize = "sheet"
so each read returns exactly one sheet's data.
Key points:
For
tabularTextDatastore, setReadSize = "file"so eachreadreturns exactly one file's data. The defaultReadSizeis a row count, which can split a single file across multiple reads but it will not go across file boundariestransformapplies a function to each read — the datastore output contains only the transformed results, not the original data. The transform function does not need to return the same number of rows as its input (e.g., computing the mean of each variable produces a single row per read)readallon the transformed datastore collects all per-file resultsUse
"omitmissing"for missing-data flags (R2023a+). On R2022b and earlier, use"omitnan"instead.
Do NOT use tall arrays for per-file processing. Tall arrays treat all files as one continuous dataset — they have no concept of file boundaries.
Datastore + Transform (per-row-group, Parquet)
Use when: a Parquet dataset is partitioned by row group (e.g., one row group per item, sensor, region, or time bucket) and each row group must be processed independently. Row groups are the natural unit of independence in Parquet — data from different row groups should not be mixed when the partitioning encodes a meaningful grouping.
% parquetDatastore defaults ReadSize to "rowgroup" — one read = one row group.
% Do NOT set ReadSize = "file": that would mix row groups within the same file.
pds = parquetDatastore("data/");
% For example, compute statistics by transforming the datastore with a custom function.
tds = transform(pds, @computeRowGroupStats);
results = readall(tds);
function out = computeRowGroupStats(data)
out = table( ...
unique(data.item), ...
mean(data.val, "omitmissing"), ...
std(data.val, "omitmissing"), ...
VariableNames=["Item", "Mean", "Std"]);
endKey points:
parquetDatastoredefaults toReadSize = "rowgroup". Eachreadreturns exactly one row group — leave the defaultA row group is the smallest independently readable unit inside a Parquet file. Writers commonly assign one row group per partition key (item, sensor, day), so per-row-group processing preserves those boundaries
Do NOT set ReadSize = "file" on a Parquet datastore for this workflow —
it merges all row groups in a file into a single read and silently mixes data
that was meant to stay separate. Use file-level granularity only when each file
already contains exactly one logical group.
Parallelizing readall (transform workflows)
The readall call in both per-file and per-row-group transform workflows
supports parallel execution when Parallel Computing Toolbox is installed and
licensed. Suggest this only when the toolbox is available:
results = readall(tds, UseParallel=true);UseParallel=trueparallelizes reads across workers in an open parallel pool. If no pool is open, MATLAB opens one automaticallyOnly suggest
UseParallelif Parallel Computing Toolbox is available
Parallel Pool (local parallelism for tall arrays)
Use when: the goal is to speed up a tall array workflow with local cores. Only recommend if Parallel Computing Toolbox is installed and licensed.
% Start a thread or process pool
parpool("Threads");
% parpool("Processes");
ds = tabularTextDatastore("data/*.csv");
tt = tall(ds);
result = gather(mean(tt, "omitmissing"));Tall array computations automatically distribute across available workers when a parallel pool is open. No code changes needed beyond opening the pool.
Do NOT suggest parpool or parallel pool workflows unless Parallel Computing
Toolbox is available — parpool errors without it.
Mapreducer (Hadoop/Spark only)
Use ONLY when the user or agent explicitly has a Hadoop or Spark environment. Requires both Parallel Computing Toolbox and MATLAB Parallel Server.
mr = mapreducer(cluster);
ds = tabularTextDatastore("hdfs:///data/*.csv");
tt = tall(ds);
result = gather(mean(tt, "omitmissing"));Do NOT recommend mapreducer for local parallel processing — a parallel pool is simpler and sufficient for local multi-core execution.
Do NOT suggest mapreducer for Hadoop/Spark execution unless the user or agent
has Parallel Computing Toolbox and a Hadoop or Spark environment with MATLAB
Parallel Server installed and licensed.
Key Functions
| Function | Purpose | When to Use |
|---|---|---|
tabularTextDatastore | Multiple reads per file for CSV/text | Large CSV/text files |
parquetDatastore | Multiple reads per file for Parquet | Large Parquet files |
spreadsheetDatastore | Multiple reads per file for Excel | Large .xlsx/.xls files |
mdfDatastore | Multiple reads per file for MDF | Large .mf4/.mdf files (requires Vehicle Network Toolbox) |
tall | Lazy evaluation over a datastore | Continuous dataset processing |
gather | Execute deferred tall computations | Collect results into memory |
transform | Apply function to each datastore read | Per-file (text) or per-row-group (Parquet) processing |
groupsummary | Grouped statistics (tall-compatible) | Aggregation by category |
parpool | Open parallel worker pool | Speed up tall computations |
mapreducer | Connect to Hadoop/Spark cluster | Hadoop/Spark environments only |
Formats Without a Built-in Datastore
Built-in datastores (such as tabularTextDatastore, parquetDatastore,
spreadsheetDatastore, mdfDatastore) do NOT support JSON, XML, HTML, or Word
documents. If the user or agent has an OOM error with readtable on one of these formats,
do NOT recommend converting to Parquet/CSV first — readtable itself would OOM
during the conversion, creating a circular dependency.
Why not fileDatastore with readtable? A common instinct is to use
fileDatastore(@readtable) — but if readtable OOMs on the file, wrapping it
in fileDatastore does not help because the read function still loads the
entire file into memory.
Instead, recommend building a custom datastore that performs multiple
reads per file (chunked reading), processing it in manageable pieces without
loading it entirely into memory (e.g., reading N lines of XML at a time, or
parsing JSON arrays incrementally). A fileDatastore with such a read
function is one option; implementing the full matlab.io.Datastore interface
is another. See the "Custom Datastores" section below for implementation guidance.
A custom datastore can then be used with tall or transform just like the
built-in datastores.
Custom Datastores
If a file format is not supported by one of the built-in datastores, build a
custom datastore by subclassing matlab.io.Datastore. This applies to:
Proprietary binary formats
Non-standard text formats (custom log files, sensor dumps)
Formats requiring multiple reads per file (large XML, JSON, HTML)
Any format needing custom iteration, partitioning, or stateful reads
Before building a custom datastore, check whether fileDatastore with a
custom ReadFcn is sufficient (one file = one read, each file fits in memory,
no state needed). Set UniformRead=true at construction so readall returns
a concatenated table (read-only after construction). For partial reads within
a file, fileDatastore with ReadMode="partialfile" supports chunked
iteration (see references/custom-datastore/implementation.md for the
required 3-output ReadFcn signature). Only build a full custom datastore class
when those simpler patterns are insufficient.
For full implementation guidance, read references/custom-datastore/implementation.md.
It covers:
Decision flowchart (fileDatastore vs custom class)
Requirement gathering (mixins, FileSet vs BlockedFileSet)
Complete code patterns (FileSet and BlockedFileSet templates)
Common mistakes and conventions
Testing guidelines (
references/custom-datastore/testing-guidelines.md)Mixin API reference (
references/custom-datastore/mixin-decision-tree.md)
When the task asks for tests, always write a separate test-class file — do not
stop after delivering the datastore class. Read
references/custom-datastore/testing-guidelines.md first and follow its list of
required core tests.
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.1 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md18.8 KiB
- manifest.yaml576 B
- references/custom-datastore/implementation.md20.0 KiB
- references/custom-datastore/mixin-decision-tree.md7.0 KiB
- references/custom-datastore/testing-guidelines.md5.2 KiB
- references/parquetread-to-datastore-migration.md2.2 KiB
- references/readtable-to-datastore-migration.md3.7 KiB
- references/tall-array-effective-use.md8.4 KiB
references/readtable-to-datastore-migration.md
Migrating readtable to tabularTextDatastore
tabularTextDatastore uses a textscan-based parser that is stricter and less
forgiving than readtable. When migrating code that works on small data, watch
for these differences.
Property Mapping
Common readtable options and their datastore equivalents:
readtable option | tabularTextDatastore equivalent | Notes |
|---|---|---|
TextType="string" | TextType="string" | Must set at creation time — read-only after construction |
Delimiter | ds.Delimiter | Writable after creation |
NumHeaderLines | ds.NumHeaderLines | Writable after creation |
TreatAsMissing | ds.TreatAsMissing | Writable after creation |
DateLocale | ds.DatetimeLocale | Writable after creation |
opts.SelectedVariableNames | ds.SelectedVariableNames | Writable after creation |
setvartype(opts, var, type) | ds.TextscanFormats{col} | See format specifiers below |
TrimNonNumeric | Not supported | See "Numbers with units" below |
ExtraColumnsRule | Not applicable | See "Extra columns" below |
detectImportOptions | Not used — datastore auto-detects | Configure via properties instead |
Type Overrides via TextscanFormats
The setvartype idiom from import options maps to textscan format specifiers:
| readtable type | TextscanFormats specifier |
|---|---|
"double" | %f |
"char" / "string" | %q (reads as cell of char or string depending on TextType) |
"datetime" | %{dd-MMM-uuuu}D (format inside braces) |
"duration" | %T |
"categorical" | %C |
"logical" | No equivalent — read as %q, convert to logical after reading |
% Override a column type (e.g., force column 3 to categorical):
ds = tabularTextDatastore("data.csv", TextType="string");
ds.TextscanFormats{3} = '%C';Numbers with Units (TrimNonNumeric)
readtable with TrimNonNumeric can parse "34mm" as 34.
tabularTextDatastore cannot. Workaround: use %q to read the column as text,
then convert to numeric in a transform function or on the tall array, depending
on which workflow from this skill is being used. This handles mixed columns
(some values with units, some without) correctly because %q reads all values
as plain text regardless of content.
Missing or Malformed Data
readtable silently inserts NaN or missing for unparseable values.
tabularTextDatastore with %f errors on non-numeric content.
Workaround: read the column as %q (text), then convert with str2double or
double(string(...)) — either in a transform function or on the tall array.
This avoids the parse error but hurts performance due to the string-to-number
conversion.
Extra Columns
readtable has ExtraColumnsRule to handle rows with more columns than the
header. tabularTextDatastore has no equivalent and will error.
Workaround: append "%*[^\r\n]" to TextscanFormats at creation time — this
reads and discards all characters to the end of the line, ignoring extra columns.
The * means "ignore," which deselects the extra content from
SelectedVariableNames. This requires ReadVariableNames=false and
NumHeaderLines set manually so the datastore does not infer column count from
the header:
ds = tabularTextDatastore("data.csv", TextType="string", ...
ReadVariableNames=false, NumHeaderLines=1, ...
TextscanFormats={'%q', '%f', '%*[^\r\n]'});This approach works when extra columns are consistently present across rows. For files where the number of columns varies unpredictably between rows, a custom datastore or preprocessing step is required.
Copyright 2026 The MathWorks, Inc.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/matlab-data-import-and-analysis/matlab-choose-big-data-solution · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-choose-big-data-solution.zip