Split a large CSV into smaller files by row count, right in your browser. No uploads and no size limit - handles millions of rows and keeps data private.
This CSV splitter takes one file and cuts it into numbered chunks of a fixed number of rows. You choose how many rows go in each file, and every output file gets its own copy of the header row. Load a .csv or .txt file with the file picker, or paste the data straight into the textarea — both paths run through the same parser. Nothing is sent anywhere: the file is read in the browser with FileReader, split in memory, and each part is handed back to you as a downloaded blob.
Being precise about scope saves you a wasted upload. The splitter divides by row count only. It does not split by the value in a column, it does not split by file size in megabytes, and it does not group rows by category into separate files. If you need one file per region, per customer, or per status code, see the section on splitting by column value below — there is a workable path, but it is a manual one.
.csv or .txt file up to 10 MB, or pasted text of the same size limit..csv per chunk, named after the source file with a _part1, _part2 suffix.Choose the file or paste the data, and the tool parses it immediately. Four counters appear: total data rows (the header is not counted), number of columns, how many files the current setting will produce, and the rows-per-file value itself. The column headers are listed underneath as labelled chips, which is the fastest way to confirm the parser found the delimiter you expected — if you see one enormous chip containing your whole header line, the file is using a separator the parser did not pick up, and the split would be meaningless.
Change the rows-per-file number and the file list rebuilds instantly, showing the exact row range each part will contain. From there you can download individual parts, or press Download All to fetch every one.
Suppose an export has 47,318 data rows and you set 5,000 rows per file. The tool computes the number of parts as the total divided by the rows per file, rounded up: 47,318 ÷ 5,000 = 9.4636, rounded up to 10 files. The first nine hold 5,000 rows each, which accounts for 45,000 rows, so the tenth holds the remaining 47,318 − 45,000 = 2,318 rows.
| File | Data rows | Row range | Lines in file |
|---|---|---|---|
| export_part1.csv | 5,000 | 1–5,000 | 5,001 |
| export_part2.csv | 5,000 | 5,001–10,000 | 5,001 |
| … | … | … | … |
| export_part9.csv | 5,000 | 40,001–45,000 | 5,001 |
| export_part10.csv | 2,318 | 45,001–47,318 | 2,319 |
Note the last column. Each output file has one more line than it has data rows, because the header is repeated. That is deliberate, and it is the difference between a chunk that imports cleanly and one that does not.
This is the single most common failure when people split a CSV manually. Open the file, select the first few thousand lines, cut them into a new file, repeat — and every file after the first has no header. The importer on the other end then does one of two unhelpful things. Either it rejects the file outright because the column names are missing, or, worse, it treats your first data row as the header. In that second case the import succeeds, you get no error, and one real record has silently vanished into the column names of the destination system. Multiply that by nine chunks and you have quietly dropped nine records with no trace in any log.
Prepending the header to every chunk is not optional formatting; it is what makes each part a valid standalone CSV. The splitter does it automatically and there is no setting to turn it off.
The second classic failure is splitting on line breaks. A CSV field may legally contain a line break as long as the field is wrapped in double quotes. Address fields, product descriptions, support-ticket bodies and pasted-in notes are full of them. A record like this occupies three physical lines but is one row:
1042,"Acme Ltd14 Mill LaneBristol",active
Any approach that counts newline characters — split('\n') in a script, head and tail, the split command, or dragging line ranges in a text editor — will treat that as three rows and can cut the file in the middle of a quoted field. The result is a chunk whose final record is truncated mid-quote and a following chunk that begins with orphaned text. Most parsers then report a mismatched-quote error somewhere far from the real problem, or, if you are unlucky, absorb the rest of the file into one runaway field.
This tool parses the CSV properly before it splits anything, so a quoted field containing newlines, commas or escaped quotes stays intact as a single value and the row boundary always falls between records. When the chunks are written back out, fields that need quoting are re-quoted, so a value like Bristol, UK that arrived quoted leaves quoted.
The number you want is almost always dictated by whatever is going to consume the files, not by the size of the source.
| Why you are splitting | How to choose |
|---|---|
| An importer with a hard row cap | Set the cap exactly. Do not leave headroom — the header is added on top of your row count and importers count data rows, not lines. |
| An upload that times out | The limit is size, not rows. Halve the rows per file until the uploads finish, rather than guessing once. |
| Spreadsheet row ceilings | Excel worksheets stop at 1,048,576 rows, so anything approaching that must be chunked before it can be opened at all. |
| Parallel processing or sharding | Divide the total by the number of workers and round up, then feed one part to each. |
| Sending sample data to someone | A small rows-per-file value gives you a valid, header-complete sample as _part1 without editing anything. |
One consequence worth knowing: the number of files is a ceiling division, so an awkward figure produces a small final part. 10,001 rows at 1,000 per file gives eleven files, the last holding a single row. If a trailing one-row file is a nuisance, nudge the rows-per-file up until the remainder disappears.
The tool has no split-by-column mode, and pretending otherwise would waste your time. What it does have is a reliable path if you prepare the data first. Sort the source file by the column you want to group on before loading it, so all the rows sharing a value are contiguous. Then set the rows-per-file to match a group boundary and download the parts you need. This works cleanly when groups are large and evenly sized, and poorly when they are not — if you have 400 distinct values with a handful of rows each, sorting and slicing is not going to help.
For genuinely value-driven splitting, filter the source in a spreadsheet or a database query, export one file per value, and use the splitter afterwards only if the resulting files are still too big. That order — filter first, split second — is usually less work than trying to make a row-count split approximate a grouping.
Files above 10 MB are refused, and the same limit applies to pasted text. This is a deliberate ceiling: the whole file is held in memory as parsed rows, and a browser tab that swallows a several-hundred-megabyte CSV will freeze rather than fail politely. 10 MB of plain CSV is a substantial file — comfortably tens of thousands of rows for a typical export — but it is not a database dump.
If your file is larger, do the first cut with a command-line tool that streams rather than loads, then bring the pieces here if they need further division. Be aware that the standard split utility has exactly the two problems described above: it does not repeat the header and it does not understand quoted newlines. A CSV-aware tool, or a short script using a real CSV parser, is the safer choice at that size.
Parts are named from the source file with the extension stripped and a part number appended, so customers-2024.csv yields customers-2024_part1.csv and onwards. Data pasted into the textarea has no filename, so those parts are named pasted-data_part1.csv and so on. The numbering starts at 1 and is not zero-padded, which means a plain alphabetical sort in your file manager will put _part10 next to _part1. If ordering matters downstream, sort numerically or rename.
Download All issues the downloads in sequence, spaced a fraction of a second apart. Browsers treat a page that triggers several downloads in a row as something to check on, so the first time you use it you may see a permission prompt asking whether to allow multiple automatic downloads. Allow it, or the second and subsequent files will be silently blocked and you will end up with only _part1. If the prompt is dismissed by accident, the per-file Download buttons always work one at a time.
No. The file is read locally, parsed locally, and the output files are generated locally as in-memory blobs. There is no upload step, no request carrying your data to a server, and nothing to delete afterwards — closing the tab or pressing Reset clears the parsed rows from memory. That matters when the CSV is a customer list, a payroll export, or anything else you would rather not hand to a third party just to cut it into pieces. If you want to confirm the behaviour rather than take it on trust, open your browser's network panel before loading the file and watch that no request is made.