skip to content

Data Loading & Stages

Getting data in through stages: bulk COPY INTO for files, Snowpipe for continuous arrival, and VARIANT with FLATTEN for semi-structured payloads. Interviewers ask because file sizing and the batch-versus-stream choice drive both load latency and credit spend.

part ofSnowflakeoverview, primer and where to startread it →
on this pageshow

questions

6

In Snowflake, what are internal and external stages, and how do files get into each?

level: juniorimportance: must knowfreq 78%

answer

  1. Files must land somewhere Snowflake can see
  2. Two families: Snowflake-managed and your own bucket
  3. One stage per user, one per table, plus named
  4. PUT uploads; CREATE STAGE ... URL points outward

basics

~20 s

A Snowflake stage is a named location that holds data files for loading. Internal stages live in Snowflake-managed storage and receive files through the PUT command; external stages point at a bucket you own in S3, Azure Blob or GCS.

solid answer

~40 s

`COPY INTO` never reads from a laptop — it reads from a **stage**. Snowflake gives you three internal stages: the per-user stage `@~`, the per-table stage `@%orders`, and named internal stages created with `CREATE STAGE`. Files reach an internal stage with `PUT file:///tmp/data.csv @my_stage AUTO_COMPRESS=TRUE`, run from a client such as SnowSQL or a driver rather than a plain worksheet. An **external stage** is created with `CREATE STAGE ... URL='s3://bucket/path/' STORAGE_INTEGRATION = my_int`; the files stay in your bucket and Snowflake reads them in place. Named stages can carry a default `FILE_FORMAT` and can be granted to roles; the user and table stages cannot be altered or dropped. External stages are also the foundation for Snowpipe auto-ingest, because cloud event notifications fire when a new object lands in the bucket.

code

sql · 9 lines
sql
CREATE STAGE raw_csv
  FILE_FORMAT = (TYPE = CSV SKIP_HEADER = 1 FIELD_OPTIONALLY_ENCLOSED_BY = '"');

-- from SnowSQL or a driver, not a plain worksheet
PUT file:///data/orders.csv @raw_csv/orders/ AUTO_COMPRESS = TRUE;

LIST @raw_csv/orders/;

COPY INTO orders FROM @raw_csv/orders/ ON_ERROR = ABORT_STATEMENT;

go deeper

for a junior

Be ready to name the three internal stages (@~, @%table, a named stage), say that PUT uploads from a client, and show a CREATE STAGE with a URL for an external bucket.

for a middle

Explain what each stage type can and cannot do — default file formats, grants, which table it can load — and why external stages are the ones Snowpipe auto-ingest builds on.

for a senior

Show judgment about credentials and lifecycle: storage integrations over inline keys, path prefixes and PATTERN to avoid huge object listings, and a deliberate policy for purging or expiring staged files.

for a principal

Own the landing-zone design across teams: who writes to which bucket prefix, how stage grants map to roles, whether the lake or Snowflake-managed storage is the system of record, and what that implies for replay and cost.

## What a stage is A stage in Snowflake is a named pointer to a file location plus, optionally, a default file format. Loading is always a two-step story: get the files to a stage, then run `COPY INTO <table> FROM @<stage>`. `COPY INTO` cannot read your local filesystem, and there is no server-side "upload" in a SQL worksheet — the stage is the mandatory hand-off point. ## The three internal stage flavours Internal stages sit in Snowflake-managed cloud storage. Files there are encrypted and counted against your storage bill until you remove them. - **User stage — `@~`.** One per user, created automatically, cannot be altered or dropped, and is visible only to that user. Handy for ad-hoc one-off loads that may target several tables. - **Table stage — `@%orders`.** One per table, created automatically with the table. Files staged here can only be loaded into that table, and it has no privileges of its own — access follows the table. You cannot attach a default file format to it. - **Named internal stage — `@raw_stage`.** A real schema object created with `CREATE STAGE raw_stage FILE_FORMAT = (TYPE = CSV)`. It can carry a default file format, be granted to roles, be organised into folder-like paths, and support a directory table. This is the one you use for anything recurring or shared across a team. ## Getting files into an internal stage ```sql -- run from SnowSQL, a driver, or the Snowsight load wizard PUT file:///data/orders_2026_08.csv @raw_stage/orders/ AUTO_COMPRESS = TRUE PARALLEL = 8; LIST @raw_stage/orders/; ``` `PUT` is a client-side command: SnowSQL, the Python/JDBC/ODBC drivers and the Snowsight load-data UI implement it, but you cannot type `PUT` into a plain SQL worksheet and have it reach your disk. `AUTO_COMPRESS = TRUE` gzips the file on the way up. `GET` pulls files back down, `LIST` (`LS`) shows what is staged, and `REMOVE` deletes staged files. Staged files linger and cost storage, so most pipelines either `REMOVE` them or set `PURGE = TRUE` on the `COPY`. ## External stages ```sql CREATE STAGE ext_orders URL = 's3://acme-lake/orders/' STORAGE_INTEGRATION = acme_s3_int FILE_FORMAT = (TYPE = PARQUET); ``` Here the files stay in your own bucket and Snowflake reads them in place — no upload step and no second copy of the data. A **storage integration** is the recommended way to authorise this: it is an account-level object bound to a cloud IAM role (an AWS role ARN, an Azure tenant/app, a GCS service account) plus a list of allowed locations, so no long-lived keys appear in DDL or in `SHOW STAGES` output. Inline `CREDENTIALS = (AWS_KEY_ID = ... )` also works and is what interviewers expect you to argue against. ## Which one to reach for Use an external stage when the files already live in your data lake, when another team or tool produces them, when you want cloud-native lifecycle rules to expire them, or when you want Snowpipe auto-ingest — event notifications only exist on your own bucket. Use an internal stage when Snowflake is the only consumer, when you are pushing files from an on-prem or CI process that has no bucket, or when you want the files encrypted and governed entirely inside Snowflake. ## The COPY that follows ```sql COPY INTO orders FROM @ext_orders/2026/08/ FILE_FORMAT = (FORMAT_NAME = my_csv) PATTERN = '.*[.]csv[.]gz' ON_ERROR = ABORT_STATEMENT; ``` A folder prefix after the stage name narrows what is read, and `PATTERN` filters by regex. A stage path plus a `PATTERN` is far cheaper than pointing at the bucket root and letting Snowflake list millions of objects. `FILE_FORMAT` can be inline or a named `CREATE FILE FORMAT` object; naming it keeps the delimiter, header and null-handling rules in one place across pipelines. ## What interviewers probe The common follow-ups are: which stage is automatic and which you create; why `PUT` fails in a worksheet; why a storage integration beats embedded keys; and whether you know that the stage is only the landing zone — nothing is queryable as table data until `COPY INTO` runs (or you define an external table over the stage).

  • Why is a storage integration preferred over inline CREDENTIALS on an external stage?
    A storage integration is an account-level object bound to a cloud IAM role and an allow-list of locations, so no long-lived access keys are written into DDL, stored in object metadata, or exposed by `SHOW STAGES`. Rotation happens on the cloud side without touching Snowflake, and the allowed-locations list caps blast radius if the integration is misused.
  • When would you use a table stage instead of a named internal stage?
    Only for quick, throwaway loads into one specific table. A table stage exists automatically, needs no DDL and inherits the table's privileges, but it cannot carry a default file format, cannot be granted separately, and its files can only be loaded into that one table. Anything recurring or shared belongs in a named stage.
  • What does PURGE = TRUE on COPY INTO do, and when is it risky?
    It deletes the source files from the stage after they load successfully, which keeps internal-stage storage costs down. It is risky on an external stage that other consumers read, and it removes your ability to re-run the load from the same files — so pipelines that need replay usually leave files in place and expire them with a cloud lifecycle rule instead.

A stage is the loading dock. An internal stage is a dock inside Snowflake's warehouse that you truck pallets into; an external stage is Snowflake being given a key to your own dock so it can read the pallets where they already sit.

saying these in an interview costs you the question

  • Thinking COPY INTO can read a local file path directly
  • Claiming PUT works from a plain SQL worksheet
  • Saying an external stage copies files into Snowflake storage
  • Believing staged files are queryable before COPY INTO runs
  • Embedding AWS keys in CREATE STAGE as the normal practice

context

open as a page

How does Snowflake's COPY INTO avoid reloading a file, and when does that protection lapse?

level: middleimportance: must knowfreq 68%

basics

~20 s

Snowflake records every file a COPY INTO loads in per-table load metadata and skips files it has already loaded. That metadata expires after 64 days, and FORCE = TRUE ignores it entirely — both paths can produce duplicate rows.

open as a page

In Snowflake, how do you query a JSON array inside a VARIANT column using LATERAL FLATTEN?

level: middleimportance: must knowfreq 66%

basics

~10 s

Traverse a Snowflake VARIANT with colon paths and cast the result, then use LATERAL FLATTEN(input => payload:items) to turn each array element into its own row, reading the element from the flattened VALUE column.

open as a page

Why does one 50 GB gzipped CSV load slowly into Snowflake even on a large warehouse?

level: middleimportance: should knowfreq 58%

basics

~20 s

Snowflake parallelises a bulk load across files, and a single compressed file is handled by one loading thread. Fifty gigabytes in one file leaves most of a large warehouse idle. Split it into many files of roughly 100–250 MB compressed.

open as a page

When would you choose Snowpipe over a scheduled COPY INTO in Snowflake, and what does it cost?

level: seniorimportance: should knowfreq 62%

basics

~20 s

Snowpipe loads files within about a minute of arrival on Snowflake-managed serverless compute, billed per second plus a per-file overhead, so it suits continuous small-batch arrival. A scheduled COPY INTO on your own warehouse is cheaper and more controllable for large periodic batches.

open as a page

Why do filters on a Snowflake VARIANT path sometimes prune as well as a typed column and sometimes not?

level: seniorimportance: nice to knowfreq 36%

basics

~20 s

During ingest Snowflake extracts consistently typed VARIANT paths into hidden sub-columns that carry their own min/max metadata, so filters on them prune like typed columns. Irregular or mixed-type paths are not extracted and force a full document read.

open as a page