{"id":45881,"date":"2026-11-10T08:35:14","date_gmt":"2026-11-10T08:35:14","guid":{"rendered":"https:\/\/www.withdata.com\/blog\/?p=45881"},"modified":"2026-11-10T08:50:34","modified_gmt":"2026-11-10T08:50:34","slug":"big-csv-that-wont-open","status":"publish","type":"post","link":"https:\/\/www.withdata.com\/blog\/bigtextfilesplitter\/big-csv-that-wont-open.html","title":{"rendered":"The Big CSV: What Opens It, What Splits It, and What Only Looks Like It Works"},"content":{"rendered":"<p>A CSV of a few gigabytes is not a corrupted file, and the machine is not too slow. Three different limits are being hit at once, and they are easy to confuse:<\/p>\n<table>\n<thead>\n<tr>\n<th>What you tried<\/th>\n<th>What actually stopped you<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>double-click it, Excel opens<\/td>\n<td><strong>1,048,576 rows<\/strong> and <strong>16,384 columns<\/strong> per sheet; past that Excel truncates without asking<\/td>\n<\/tr>\n<tr>\n<td>a script, pandas, a &#8220;big file&#8221; viewer<\/td>\n<td>the file is <strong>loaded whole<\/strong> into memory \u2014 several times its size once it is parsed into rows<\/td>\n<\/tr>\n<tr>\n<td>a text editor<\/td>\n<td>it tries to lay out every line; the UI freezes before the file is even read<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The questions people ask about this are ten years old and still open: <em>&#8220;How do I read a large csv file with pandas?&#8221;<\/em> has <strong>586,968 views<\/strong> on Stack Overflow (asked 2014-09-21), <em>&#8220;Batch file to split .csv file&#8221;<\/em> has <strong>164,650<\/strong> (2013-12-16), and the <em>&#8220;split reading a large csv into evenly-sized chunks&#8221;<\/em> question 51,037. On r\/excel the same thing keeps coming back: <em>&#8220;Excel file far too large to even open&#8221;<\/em> (2026-04, 51 comments), <em>&#8220;Having trouble extrapolating data from a 10GB CSV file&#8221;<\/em> (2024-07, 32), <em>&#8220;Excel File Grew from 400MB to 650MB&#8221;<\/em> (2026-06, 77).<\/p>\n<p>Two different jobs are hiding in that table, and they need two different answers: <strong>looking<\/strong> at the file, and <strong>handing the data on<\/strong>.<\/p>\n<h2>1. Opening it, without splitting anything<\/h2>\n<p>If what you need is to see what is on line 18 million, or how many rows match an IP, nothing has to be split and nothing has to be converted. <a href=\"https:\/\/www.withdata.com\/big-text-file-viewer\/\" target=\"_blank\" rel=\"noopener noreferrer\">BigTextFileViewer<\/a> opens the file where it is and reads it in blocks instead of loading it:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.withdata.com\/wp\/wp-content\/uploads\/2026\/11\/bigcsv-03-viewer.png\" alt=\"BigTextFileViewer with a 1.097 GB CSV: 26000001 lines, opened in two seconds, UTF-8\" width=\"1176\"><\/p>\n<p>The status bar is the whole claim: <strong><code>1.097 GB, 26000001 Lines, 00:00:02<\/code><\/strong> \u2014 the file was not converted, not split, and not loaded; it was opened. <code>Search<\/code> walks the file and reports matches with their line numbers, and jumping to a line number is instant, which is the difference between this and scrolling a 10 GB file in an editor.<\/p>\n<h2>2. Splitting, when the pieces are going somewhere<\/h2>\n<p>The moment the data has to leave \u2014 into Excel, into a database, into someone else&#8217;s inbox \u2014 the file has to become smaller than the limit that is blocking it, and splitting by rows is the cheap way to do it.<\/p>\n<p>Reading a CSV means parsing: split the line on the delimiter, unquote the fields, convert numbers and dates, build a row object. That is where the memory goes \u2014 a 1 GB CSV can become 3\u20136 GB of objects in a Python process, which is exactly what the pandas thread is about.<\/p>\n<p>Counting line breaks does not need any of that. A splitter can walk the file as bytes, note where every N-th line ends, and copy each block to its own file. Memory stays flat because nothing is parsed, and a quoted field containing a comma costs nothing.<\/p>\n<p>The trade-off is stated in the same breath: a line-based splitter assumes <strong>one record per line<\/strong>. If a value contains a line break inside quotes, that record will be cut in half. Use it for the usual exports (no embedded newlines); for files where quoted line breaks are real, split with a CSV-aware tool that parses records first (<code>DataFileSplitter<\/code> does, and repeats the header in each part).<\/p>\n<h2>3. What a split looks like<\/h2>\n<p><a href=\"https:\/\/www.withdata.com\/big-text-file-splitter\/\" target=\"_blank\" rel=\"noopener noreferrer\">BigTextFileSplitter<\/a> is the line-based one: it never parses the CSV, never builds rows, and its <code>Split Text File<\/code> window asks for four things \u2014 the file, where the pieces go, how to split, and whether to repeat the header:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.withdata.com\/wp\/wp-content\/uploads\/2026\/11\/bigcsv-01-split-dialog.png\" alt=\"Split Text File: big.csv, 118.786 MB, 3,000,001 lines, Split By Lines, max 500000 lines, Keep Header In Every File\" width=\"736\"><\/p>\n<ul>\n<li><strong>Split By<\/strong> \u2014 <code>Lines<\/code> (a row count per file), <code>File Size<\/code> (megabytes per file), <code>File Count<\/code> (how many<\/li>\n<\/ul>\n<p>parts you want), or <code>Symbol<\/code> (a marker line, for log files).<\/p>\n<ul>\n<li><strong>Max Lines per Split File<\/strong> \u2014 500,000 is a good default for something that will be opened in Excel:<\/li>\n<\/ul>\n<p>five parts of half a million rows each stay well under the row limit.<\/p>\n<ul>\n<li><strong>Keep Header In Every File<\/strong> \u2014 the first line of the source is written at the top of every piece, so<\/li>\n<\/ul>\n<p>each part is still a valid CSV with its column names.<\/p>\n<p>The run itself is the whole point:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.withdata.com\/wp\/wp-content\/uploads\/2026\/11\/bigcsv-02-split-log.png\" alt=\"Log: 3000000 lines, Elapsed 00:00:00.500, split to 6 files\" width=\"736\"><\/p>\n<p><strong>3,000,000 lines, 118.786 MB, 0.5 seconds, 6 files.<\/strong><\/p>\n<h2>4. The numbers at a real size<\/h2>\n<p>The window above is 118 MB, which is a pleasant demo. A file that actually hurts:<\/p>\n<table>\n<thead>\n<tr>\n<th>File<\/th>\n<th>Rows<\/th>\n<th>Result<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>118.8 MB<\/td>\n<td>3,000,000<\/td>\n<td>6 parts of 500,000 rows, <strong>0.5 s<\/strong>, header in every part<\/td>\n<\/tr>\n<tr>\n<td><strong>1.12 GB<\/strong><\/td>\n<td><strong>26,000,000<\/strong><\/td>\n<td>6 parts of 5,000,000 rows, <strong>3.77 s<\/strong>, <strong>peak working set 51 MB<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The second line is the one worth reading twice: the memory does not follow the file. It was measured by polling the process while it ran, and the figure did not move as the file grew.<\/p>\n<p>Two things were checked after that run, because they are the usual ways a split silently damages data:<\/p>\n<ul>\n<li><strong>The line endings are copied, not normalised.<\/strong> A <code>LF<\/code> file stays <code>LF<\/code>; a <code>CRLF<\/code> file stays <code>CRLF<\/code>.<\/li>\n<\/ul>\n<p>(This was a real defect until this week \u2014 every piece used to come out <code>CRLF<\/code>.)<\/p>\n<ul>\n<li><strong>Rejoining the parts reproduces the source byte for byte<\/strong>, once the repeated header lines are<\/li>\n<\/ul>\n<p>removed: the MD5 of the reassembled file matches the original.<\/p>\n<h2>5. After the split<\/h2>\n<p>Each part is a normal file, so the destination decides what to do with it:<\/p>\n<ul>\n<li><strong>into Excel<\/strong> \u2014 500,000 rows per part opens without the &#8220;file too large&#8221; behaviour, and each part has<\/li>\n<\/ul>\n<p>its own header row;<\/p>\n<ul>\n<li><strong>into a database<\/strong> \u2014 <a href=\"https:\/\/www.withdata.com\/file-to-db\/\" target=\"_blank\" rel=\"noopener noreferrer\">FileToDB<\/a> imports the parts as they are,<\/li>\n<\/ul>\n<p>or a folder of them in one run;<\/p>\n<ul>\n<li><strong>just to look<\/strong> \u2014 a part opens in any viewer, or in<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.withdata.com\/big-text-file-viewer\/\" target=\"_blank\" rel=\"noopener noreferrer\">BigTextFileViewer<\/a> along with the rest of the file.<\/p>\n<h2>6. From the command line<\/h2>\n<p>&#8220;<code>bat BigTextFileSplitter.exe split --from=big.csv --to=D:\\parts --by=lines --max-lines=500000 <\/code>&#8220;<\/p>\n<p>For a nightly export the same command belongs in the scheduler; the GUI&#8217;s <code>Save Task<\/code> writes exactly that session.<\/p>\n<h2>FAQ<\/h2>\n<h3>Why does Excel stop at 1,048,576 rows?<\/h3>\n<p>That is the sheet limit, and Excel does not warn you \u2014 it just stops. Splitting below that number (half a million is a safe round figure) is the only way to keep the whole file in spreadsheets.<\/p>\n<h3>Is splitting lossless?<\/h3>\n<p>Yes, as bytes: the pieces contain the original characters, the original line endings, and \u2014 with <code>Keep Header In Every File<\/code> \u2014 a copy of the header line. Concatenating the pieces (minus the repeated headers) reproduces the source exactly.<\/p>\n<h3>What about commas or quotes inside values?<\/h3>\n<p>A line-based split does not care: it never parses the fields, so commas and quotes are copied as they are. What it cannot do is keep a record that contains a line break inside quotes \u2014 that needs a CSV-aware split.<\/p>\n<h3>Can I split by size instead of by rows?<\/h3>\n<p><code>Split By \u2192 File Size<\/code> cuts at a number of megabytes. Rows are usually the better unit when the parts will be opened in Excel; size is better for log files and for uploads with a hard limit.<\/p>\n<h3>Do I need to install anything on the machine that produces the file?<\/h3>\n<p>No. The splitter is a single desktop program; it reads the file where it is and writes the parts next to it.<\/p>\n<h3>Can it split a 20 GB file?<\/h3>\n<p>The limits are disk space and time, not memory: the splitter does not load the file. A 1.1 GB file takes under four seconds here, so the arithmetic is on your side.<\/p>\n<h2>Split it, then open it<\/h2>\n<blockquote>\n<p><strong>Cut a file that will not open into parts that will \u2014 with the header repeated and every byte kept.<\/strong> <a href=\"https:\/\/www.withdata.com\/big-text-file-splitter\/\" target=\"_blank\" rel=\"noopener noreferrer\">Try BigTextFileSplitter<\/a> \u2014 Windows \/ macOS \/ Linux, one-time price. To read a big file without splitting it at all, that is <a href=\"https:\/\/www.withdata.com\/big-text-file-viewer\/\" target=\"_blank\" rel=\"noopener noreferrer\">BigTextFileViewer<\/a>.<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>A CSV of a few gigabytes is not a corrupted file, and the machine is not too slow. Three different limits are being hit at once, and they are easy to confuse: What you tried What actually stopped you double-click it, Excel opens 1,048,576 rows and 16,384 columns per sheet; past that Excel truncates without [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2674],"tags":[13766,13868,13867,2675],"class_list":["post-45881","post","type-post","status-publish","format-standard","hentry","category-bigtextfilesplitter","tag-bigtextfilesplitter","tag-csv-too-large","tag-large-csv","tag-split-csv"],"_links":{"self":[{"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/posts\/45881","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/comments?post=45881"}],"version-history":[{"count":3,"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/posts\/45881\/revisions"}],"predecessor-version":[{"id":45885,"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/posts\/45881\/revisions\/45885"}],"wp:attachment":[{"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/media?parent=45881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/categories?post=45881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.withdata.com\/blog\/wp-json\/wp\/v2\/tags?post=45881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}