What you will be able to do
- Size warehouses and data files so a COPY load runs in parallel without wasting credits
- Choose a file cadence that balances Snowpipe cost and latency
- Select files by path, FILES list or PATTERN, and handle files whose load metadata has expired
- Prepare CSV and semi-structured files, use INFER_SCHEMA, and choose an ON_ERROR behavior
1.Warehouses and file sizing for bulk loads
Loading large data sets can slow down queries, so Snowflake recommends separate warehouses for loading and for querying. How much a load can run in parallel depends on two things: the compute in the warehouse and the number of files. You can't have more parallel load operations than you have files. That is why file size matters more than warehouse size. Aim for files of roughly 100–250 MB (or larger) compressed. This guidance applies to bulk loads and to Snowpipe.
Avoid both extremes. Many tiny files add per-file overhead, so combine them. Very large files (100 GB or more) are not recommended. Split them, by line so that no record spans two chunks. On Unix-like systems the split utility does this. For example, splitting an 8 GB file of 10 million lines every 100,000 lines gives 100 files of about 80 MB each. One exception: Snowflake can scan large uncompressed CSV files (over 128 MB, RFC4180-compliant) in parallel, as long as MULTI_LINE is FALSE, COMPRESSION is NONE, and ON_ERROR is ABORT_STATEMENT or CONTINUE.
Checkpoint 1 of 8· Fill the gap
Which flag makes split cut the file by line count, so no record spans two chunks?
split ? 100000 pagecounts-20151201.csv pages-l takes a line_count. -b splits by byte count, which can cut a record in half. Snowflake recommends splitting by line.
Source: docs.snowflake.comCheckpoint 2 of 8· Exam question
Before running a full COPY INTO on a newly delivered vendor file, an engineer wants to preview which rows would fail and why, without inserting any rows into the target table. Which approach satisfies this?
Correct answer: A — Run COPY INTO with VALIDATION_MODE = 'RETURN_ERRORS', which parses the staged file and returns the rows that would fail without loading any data into the table
- A. Correct: VALIDATION_MODE runs the parsing logic of the COPY statement and reports validation errors without inserting any rows, which is exactly the dry-run behavior the engineer needs to preview failures before committing to a real load.
- B. Incorrect: this approach actually inserts valid rows into the temporary table as a side effect of the load, so it does not achieve a true preview-without-loading, and it adds unnecessary cleanup overhead compared to a dedicated validation mode.
- C. Incorrect: querying a staged file directly can show raw content, but it does not apply the target table's column types, file format, or transformation logic, so it will not surface the same load errors that COPY INTO's parser would catch.
- D. Incorrect: PURGE controls whether the source file is deleted from the stage after a successful load, it has nothing to do with previewing errors, and combining it with a real load still inserts rows rather than just validating them.
2.File cadence for continuous loading with Snowpipe
Snowpipe usually loads new data within a minute of the file notification. Very large files, or files that take a lot of work to decompress, decrypt or transform, take longer. Cost is also driven by file count, because managing the internal load queue adds overhead that grows with the number of queued files. With files of about 100–250 MB or larger, that overhead becomes immaterial.
If your source takes more than a minute to build up a few MB, write a new file about once per minute. Staging files more often than that only adds queue overhead, and latency is not guaranteed to improve. Batching tools can help. Amazon Data Firehose, for example, lets you set a buffer size and a buffer interval, and keeping the interval at its 60-second minimum avoids creating too many files.
Checkpoint 3 of 8· Check yourself
A team wants lower Snowpipe latency, so they start writing a tiny file every 5 seconds. What is the documented effect?
Staging files more often than once per minute has two downsides: the latency gain is not guaranteed, and the per-file queue overhead goes up.
“A reduction in latency between staging and loading the data can’t be guaranteed.”Source: docs.snowflake.com
Sources2
3.Choosing files and the 64-day load metadata
COPY can pick a subset of a stage's files in three ways. This lets you run several COPY statements at once over different subsets.
| Method | How | Speed and limits |
|---|---|---|
| Path / prefix | FROM @stage/path/ | Combine with FILES or PATTERN for more control |
| FILES parameter | Discrete list of file names | Generally the fastest; maximum of 1,000 files |
| PATTERN parameter | Regular expression | Generally the slowest; useful for loading files in named order |
COPY INTO load1 FROM @%load1/data1/ FILES=('test1.csv', 'test2.csv', 'test3.csv')PATTERN behaves differently in the two methods. A bulk load applies the regex to the whole storage location in the FROM clause. Snowpipe first trims off the path segments that are already in the stage definition. For Snowpipe, Snowflake prefers cloud event filtering to PATTERN.
COPY records metadata on the target table for each loaded file: its name, size, ETag, rows parsed, last load time and errors. This stops parallel COPY statements from loading the same file twice. Files that fail are marked load failed, and a later COPY can pick them up. If many concurrent COPY statements load the same table, Snowflake recommends Snowpipe instead.
The metadata expires after 64 days. When a file's LAST_MODIFIED date and its last load are both older than that, and the table's initial load was also more than 64 days ago, COPY can't tell whether the file was already loaded, so it skips the file by default. Setting LOAD_UNCERTAIN_FILES to true loads those files and still uses whatever metadata is available. FORCE ignores the metadata completely and reloads every file, which can duplicate data.
Checkpoint 4 of 8· Put it in order
Put the events of the documented reload scenario in order
- 1.A file is staged and successfully loaded
- 2.A reload attempt skips the file unless LOAD_UNCERTAIN_FILES or FORCE is set
- 3.The table's initial load metadata expires after 64 days
- 4.The file's LAST_MODIFIED date and its load metadata both pass 64 days
- 5.The table is created and its initial load runs
The file is skipped only after the initial-load metadata and the file's own metadata have both expired. At that point COPY can no longer determine the file's load status.
“The LOAD_UNCERTAIN_FILES copy option (or the FORCE copy option) is required to load the file.”Source: docs.snowflake.com
Sources3
4.Preparing file formats and detecting schemas
Delimited files default to UTF-8, and you can set another encoding with the ENCODING file format option. Semi-structured formats support UTF-8 only. For CSV, put quotes around any field that contains the delimiter or a carriage return, escape any quotes inside the data, and give every row the same number of columns.
Two file format options fix common problems. In a VARIANT column, JSON nulls are stored as the string "null". If those nulls just mean a value is missing, STRIP_NULL_VALUES = TRUE avoids wasting storage and slowing queries. Some exporters put a space before each opening quote, which makes Snowflake read the quotes as part of the data. TRIM_SPACE removes that space:
COPY INTO mytable
FROM @%mytable
FILE_FORMAT = (TYPE = CSV TRIM_SPACE=true FIELD_OPTIONALLY_ENCLOSED_BY = '0x22');You don't have to write the target table by hand. The INFER_SCHEMA table function reads staged files and returns their column definitions. CREATE TABLE ... USING TEMPLATE then builds a table from that output, and the same works for external and Iceberg tables. INFER_SCHEMA supports Parquet, Avro, ORC, JSON and CSV.
Checkpoint 5 of 8· Check yourself
An engineer wants the target table's columns created automatically from staged Parquet files. Which combination does this?
INFER_SCHEMA finds the column definitions in the staged files, and USING TEMPLATE creates a table from them.
“with the USING TEMPLATE clause to create a new table or external table with the column definitions derived from the INFER_SCHEMA function output”Source: docs.snowflake.com
Checkpoint 6 of 8· Exam question
A data engineer is loading a batch of 500 uncompressed CSV files, each around 200 MB, from an S3 external stage into a permanent table using COPY INTO. The load runs slower than expected on a Large warehouse. Which change is most likely to improve load throughput?
Correct answer: A — Compress the files with gzip and split them into roughly 100-250 MB chunks so more files load in parallel across warehouse threads
- A. Correct: Snowflake recommends compressed files in roughly the 100-250 MB range because each file is processed by a single thread, and right-sized compressed files let the warehouse parallelize loading across many threads instead of bottlenecking on a few large or uncompressed files.
- B. Incorrect: consolidating into one large file removes the ability to parallelize across threads, since a single file can only be processed by one thread at a time, which typically slows the load rather than speeding it up.
- C. Incorrect: table type (permanent vs. transient) affects storage retention and Time Travel/Fail-safe behavior, not the mechanics of how COPY INTO reads and parallelizes file scanning during a load.
- D. Incorrect: SIZE_LIMIT caps how many bytes a single COPY statement will load before stopping, it does not change how files are parallelized across threads, so raising it does not address a throughput bottleneck caused by file sizing.
5.Error handling with ON_ERROR and VALIDATION_MODE
The ON_ERROR copy option decides what a load does when it hits bad rows. The values are CONTINUE, SKIP_FILE, SKIP_FILE_num, 'SKIP_FILE_num%' and ABORT_STATEMENT. Snowflake's documentation says the default suits common scenarios but isn't always the best choice. (The source excerpts used for this lesson don't say which value is the default, so check the COPY INTO <table> reference.)
CONTINUE keeps loading the file. COPY then reports at most one error per file, and the difference between ROWS_PARSED and ROWS_LOADED tells you how many rows had errors. To see every error, use the VALIDATION_MODE parameter or the VALIDATE function. SKIP_FILE skips any file that contains an error, and the numeric forms skip a file only once its error rows reach a count or percentage. SKIP_FILE has to buffer the whole file, so it is slower than CONTINUE or ABORT_STATEMENT. Large files raise the stakes. Skipping one because of a few errors wastes time and credits, and a load that runs past the 24-hour limit can be aborted without committing any of the file.
Checkpoint 7 of 8· Check yourself
Why can ON_ERROR = SKIP_FILE make a load slower than CONTINUE, even when the files contain no errors?
SKIP_FILE has to keep the whole file buffered in case it needs to discard it, so it is slower than CONTINUE or ABORT_STATEMENT.
“The SKIP_FILE action buffers an entire file whether errors are found or not.”Source: docs.snowflake.com
Checkpoint 8 of 8· Exam question
A nightly batch load into a staging table must not stop on the first bad row, but the engineering team wants a hard limit so a file with heavy corruption doesn't get partially loaded row by row. Which ON_ERROR setting fits this requirement?
Correct answer: A — ON_ERROR = 'SKIP_FILE_10', which skips loading an entire file once the number of error rows found in that file reaches ten
- A. Correct: the SKIP_FILE_<n> form skips a file once its error-row count reaches the specified threshold, which lets good rows load from mostly-clean files while still drawing a hard line against files with heavy corruption, matching the stated requirement.
- B. Incorrect: CONTINUE has no error-count threshold at all, it keeps loading rows from a file no matter how corrupted that file is, which is exactly the unbounded behavior the team wants to avoid.
- C. Incorrect: ABORT_STATEMENT is the strictest option, stopping the entire multi-file COPY statement on the first error anywhere, which contradicts the requirement to keep loading good rows rather than stopping immediately.
- D. Incorrect: plain SKIP_FILE discards a file on its very first error rather than allowing a configurable number of bad rows first, so it does not give the team the row-count-based tolerance they are asking for.
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A slow bulk load is best fixed by scaling the warehouse up to X-Large or larger.Why is that wrong?
Load parallelism is limited by the number of files. Unless you are loading hundreds or thousands of files at once, a Small to Large warehouse is usually enough, and sizing files to 100–250 MB helps more.
Covered in Warehouses and file sizing for bulk loads
2.FORCE is the safe way to load old files that COPY skipped because their load status is unknown.Why is that wrong?
FORCE ignores load metadata and reloads every file, which can duplicate data. LOAD_UNCERTAIN_FILES loads the uncertain files and still uses whatever metadata is available.
Covered in Choosing files and the 64-day load metadata
Practise it for real
Load a split file set from a table stage with an explicit FILES list, then check that load metadata prevents a duplicate load
1.Split a large CSV export by line, for example: split -l 100000 pagecounts-20151201.csv pages
Why: Splitting by line produces several moderate-sized files, so the load can run in parallel and no record spans two chunks.
You should see: A set of smaller files whose names start with the prefix pages
2.Upload the split files to the target table's stage with the PUT command
Why: The PUT command uploads local files to any internal stage, including a table stage.
You should see: The files are listed on the table stage. Only the table owner can stage files there.
3.Run COPY INTO with a FILES list naming the staged files
Why: A discrete FILES list is usually the fastest way to select files, up to 1,000 per statement.
You should see: The named files load into the table
4.Run the same COPY statement again without FORCE
Why: COPY keeps load metadata for each file on the table so it doesn't load the same file twice.
You should see: The files that already loaded are not loaded again
Stuck? Get a nudge
To reload on purpose, use FORCE, and remember that it can duplicate rows.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“We recommend dedicating separate warehouses for loading and querying operations to optimize performance for each.”
↩︎ Warehouses and file sizing for bulk loads“Using a larger warehouse (X-Large, 2X-Large, etc.) will consume more credits and may not result in any performance increase.”
↩︎ Prediction - 2.
“we recommend aiming to produce data files roughly 100-250 MB (or larger) in size compressed.”
↩︎ Warehouses and file sizing for bulk loads“We recommend splitting large files by line to avoid records that span chunks.”
↩︎ Warehouses and file sizing for bulk loads“Snowpipe is designed to load new data typically within a minute after a file notification is sent”
↩︎ File cadence for continuous loading with Snowpipe“consider creating a new (potentially smaller) data file once per minute.”
↩︎ File cadence for continuous loading with Snowpipe“The number of columns in each row should be consistent.”
↩︎ Preparing file formats and detecting schemas“it could be aborted without any portion of the file being committed”
↩︎ Error handling with ON_ERROR and VALIDATION_MODE“The number of load operations that run in parallel can’t exceed the number of data files to be loaded.”
↩︎ Exam trap 1“A reduction in latency between staging and loading the data can’t be guaranteed.”
↩︎ Checkpoint - 3.
“the FILES parameter supports a maximum of 1,000 files”
↩︎ Choosing files and the 64-day load metadata“This load metadata expires after 64 days.”
↩︎ Choosing files and the 64-day load metadata“To load files whose metadata has expired, set the LOAD_UNCERTAIN_FILES copy option to true.”
↩︎ Choosing files and the 64-day load metadata“Note that this option reloads files, potentially duplicating data in a table.”
↩︎ Exam trap 2“The LOAD_UNCERTAIN_FILES copy option (or the FORCE copy option) is required to load the file.”
↩︎ Checkpoint - 4.
“For semi-structured file formats (JSON, Avro, etc.), the only supported character set is UTF-8.”
↩︎ Preparing file formats and detecting schemas - 5.
“This function supports Apache Parquet, Apache Avro, ORC, JSON, and CSV files.”
↩︎ Preparing file formats and detecting schemas“with the USING TEMPLATE clause to create a new table or external table with the column definitions derived from the INFER_SCHEMA function output”
↩︎ Checkpoint - 6.
“To view all the errors in the data files, use the VALIDATION_MODE parameter or query the VALIDATE function.”
↩︎ Error handling with ON_ERROR and VALIDATION_MODE“Carefully consider the ON_ERROR copy option value.”
↩︎ Error handling with ON_ERROR and VALIDATION_MODE“The SKIP_FILE action buffers an entire file whether errors are found or not.”
↩︎ Checkpoint