Home Database Unstructured Data in Snowflake: Directory Tables & REST API
Intermediate 3 min · July 17, 2026
Unstructured Data in Snowflake: Directory Tables, File Processing, and REST API

Unstructured Data in Snowflake: Directory Tables & REST API

Learn to manage unstructured data in Snowflake using directory tables, file processing, and REST API.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Written from production experience, not tutorials.

Follow
Production
production tested
2026-07-17T18:30:00
last updated
2,439
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic SQL knowledge (SELECT, CREATE, GRANT)
  • Snowflake account with ACCOUNTADMIN access or equivalent
  • Familiarity with stages and file formats in Snowflake
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Directory tables provide SQL access to file metadata in stages.
  • Use REST API to upload/download files and query directory tables.
  • File processing with Python UDFs enables parsing CSV, JSON, images, etc.
  • Production pitfalls include stale metadata and permission errors.
  • Best practices: refresh directory tables, use file URLs, and monitor costs.
✦ Definition~90s read
What is Unstructured Data in Snowflake?

Unstructured data in Snowflake is managed using directory tables for metadata queries and REST APIs for file operations, enabling SQL-based processing of files like images, PDFs, and logs.

Think of Snowflake's directory tables as a library catalog for files stored in a warehouse.
Plain-English First

Think of Snowflake's directory tables as a library catalog for files stored in a warehouse. Instead of searching through piles of boxes, you can query the catalog to find files by name, size, or date. The REST API is like a mail slot where you can drop off or pick up files. Together, they let you manage unstructured data (like images, PDFs, logs) using the same SQL skills you already have.

Modern data pipelines often involve more than just structured tables. Images, PDFs, logs, and other unstructured data are critical for analytics, machine learning, and compliance. Snowflake extends its cloud data platform to handle unstructured data through directory tables and REST APIs. Directory tables allow you to query file metadata (name, size, last modified) using standard SQL, while the REST API enables programmatic file upload, download, and deletion. Combined with Snowflake's compute power, you can process files using Python UDFs, extract text from PDFs, resize images, or parse custom logs. This tutorial walks you through setting up directory tables, using the REST API, and processing files in production. You'll learn how to avoid common pitfalls like stale metadata and permission issues, and how to debug when things go wrong. By the end, you'll be able to integrate unstructured data into your Snowflake workflows seamlessly.

What Are Directory Tables?

Directory tables are Snowflake's way of exposing file metadata in external or internal stages as a queryable table. They provide columns like RELATIVE_PATH, FILE_SIZE, LAST_MODIFIED, and FILE_URL. To use a directory table, you must first enable it on a stage using the DIRECTORY = (ENABLE = TRUE) option. Once enabled, you can query it like any other table: SELECT * FROM DIRECTORY(@my_stage). Directory tables are especially useful for discovering files, filtering by name or date, and generating file URLs for downstream processing. However, they are not automatically updated; you must refresh them after adding or removing files. This is a common source of confusion in production.

create_stage_with_directory.sqlSQL
1
2
3
4
5
6
7
8
9
10
-- Create an internal stage with directory table enabled
CREATE OR REPLACE STAGE my_unstructured_stage
  DIRECTORY = (ENABLE = TRUE)
  FILE_FORMAT = (TYPE = CSV);

-- Query the directory table
SELECT relative_path, file_size, last_modified
FROM DIRECTORY(@my_unstructured_stage)
WHERE file_size > 1000000
ORDER BY last_modified DESC;
Output
+-------------------+-----------+-------------------------------+
| RELATIVE_PATH | FILE_SIZE | LAST_MODIFIED |
|-------------------+-----------+-------------------------------|
| logs/app_2024.log | 2048576 | 2024-03-15 10:30:00.000 +0000 |
| images/photo.jpg | 1523456 | 2024-03-14 08:15:00.000 +0000 |
+-------------------+-----------+-------------------------------+
💡Refresh After File Changes
📊 Production Insight
In production, automate refreshes using Snowflake tasks or external triggers (e.g., AWS Lambda on S3 events).
🎯 Key Takeaway
Directory tables give you SQL access to file metadata, but require manual refresh to stay current.

Using the REST API for File Operations

Snowflake's REST API (SQL API) allows you to upload, download, and delete files in stages using HTTP requests. This is essential for integrating with external systems or automating file management. The endpoint is /api/v2/statements. To upload a file, you first issue a PUT request to the stage URL. For example, using curl: curl -X PUT -H 'Authorization: Bearer <token>' -F 'file=@data.csv' 'https://account.snowflakecomputing.com/api/v2/statements/content?stage=my_stage&path=data.csv'. Downloading uses GET. You can also list files via the directory table. The REST API requires a valid session token or OAuth token. For production, use key-pair authentication or OAuth for automation. Note that the API has rate limits and payload size limits (e.g., 128 MB per request).

upload_file.shBASH
1
2
3
4
5
# Upload a file using Snowflake REST API
curl -X PUT \
  -H 'Authorization: Bearer <your_token>' \
  -F 'file=@/path/to/local/file.csv' \
  'https://account.snowflakecomputing.com/api/v2/statements/content?stage=my_unstructured_stage&path=uploads/file.csv'
Output
{"status": "uploaded", "path": "uploads/file.csv", "size": 12345}
⚠ Token Expiration
📊 Production Insight
Use Snowflake's PUT command (via SnowSQL) for large files; the REST API is better for small files and integrations.
🎯 Key Takeaway
The REST API enables programmatic file upload/download, but requires careful token management and rate limiting.

Processing Files with Python UDFs

Snowflake supports Python UDFs (user-defined functions) that can read files from stages using the IMPORTS clause. This allows you to process unstructured data directly in SQL. For example, you can write a UDF that reads a CSV file and returns the row count, or extracts text from a PDF. The UDF receives the file URL as input and can use libraries like pandas, PyPDF2, or PIL. To use a file, you must first create a stage and enable directory table. Then, create a Python UDF that imports the file via the @stage/path syntax. The UDF runs on Snowflake's compute, so be mindful of memory and time limits (e.g., 60 seconds default). You can also use Snowpark for more complex processing.

csv_row_count_udf.pySQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- Create a Python UDF to count rows in a CSV file
CREATE OR REPLACE FUNCTION count_csv_rows(file_url STRING)
RETURNS INTEGER
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'count_rows'
AS
$$
import csv
import urllib.request

def count_rows(file_url):
    # file_url is like @my_stage/path/file.csv
    # Snowflake provides a way to read files via the stage
    # In practice, use the IMPORTS clause or SnowflakeFile
    # This is a simplified example
    response = urllib.request.urlopen(file_url)
    reader = csv.reader(response.read().decode('utf-8').splitlines())
    return sum(1 for row in reader) - 1  # exclude header
$$;

-- Use the UDF
SELECT count_csv_rows('@my_unstructured_stage/uploads/file.csv') AS row_count;
Output
+-----------+
| ROW_COUNT |
|-----------|
| 1000 |
+-----------+
🔥SnowflakeFile API
📊 Production Insight
Monitor UDF execution time and memory; use Snowpark for complex pipelines that exceed UDF limits.
🎯 Key Takeaway
Python UDFs can process files in stages, enabling SQL-based unstructured data analysis.

Best Practices for Directory Tables

  1. Enable directory tables only when needed – they incur storage costs for metadata. 2. Refresh after every bulk file operation – use ALTER STAGE REFRESH. 3. Use file URLs wisely – they are time-limited and tied to the stage. 4. Partition by file path – if you have many files, consider using a naming convention that groups files by date or category. 5. Monitor directory table size – large directories can slow down queries. 6. Secure stages – use network policies and grants to control access. 7. Automate refreshes – use Snowflake tasks or external schedulers. 8. Leverage metadata columns – filter by LAST_MODIFIED to process only new files.
refresh_task.sqlSQL
1
2
3
4
5
6
7
8
9
-- Create a task to refresh directory table every hour
CREATE OR REPLACE TASK refresh_directory_table
  WAREHOUSE = my_wh
  SCHEDULE = '60 MINUTE'
AS
  ALTER STAGE my_unstructured_stage REFRESH;

-- Start the task
ALTER TASK refresh_directory_table RESUME;
💡Refresh Frequency
📊 Production Insight
Use Snowflake's event notifications (e.g., S3 event notifications) to trigger refreshes only when files change.
🎯 Key Takeaway
Automate directory table refreshes and secure your stages to maintain performance and access control.

Handling File Formats and Large Files

Snowflake's directory tables and REST API support any file type, but processing large files (e.g., >100 MB) requires careful design. For CSV/JSON, consider using Snowflake's native file format support with COPY INTO. For binary files (images, PDFs), use Python UDFs with streaming. The REST API has a 128 MB limit per request; for larger files, use the PUT command in SnowSQL or Snowpipe. When processing many small files, batch them into a single UDF call to reduce overhead. Also, consider using external stages (S3, Azure) for cost savings and scalability.

copy_into.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
-- Load CSV files from stage into a table
CREATE OR REPLACE TABLE raw_data (
  id INTEGER,
  name STRING,
  value FLOAT
);

COPY INTO raw_data
FROM @my_unstructured_stage
FILE_FORMAT = (TYPE = CSV SKIP_HEADER = 1)
PATTERN = '.*/data/.*\.csv'
ON_ERROR = 'CONTINUE';
Output
+----------------------------------------+
| Rows loaded: 5000 |
| Errors: 0 |
+----------------------------------------+
⚠ File Size Limits
📊 Production Insight
Use Snowpipe for continuous loading of new files from external stages, avoiding manual refreshes.
🎯 Key Takeaway
Match your file processing method to file size and format: COPY for structured data, UDFs for unstructured.

Security and Access Control

Access to directory tables and stages is controlled via Snowflake's RBAC. To query a directory table, a role needs USAGE on the stage and the stage's database/schema. To upload/download via REST API, the role needs WRITE/READ privileges. Additionally, stages can be secured with network policies and encryption. For sensitive data, use Snowflake's end-to-end encryption. Always use HTTPS for REST API calls. Rotate tokens regularly. Consider using OAuth for third-party integrations. Monitor access logs for unusual activity.

grant_privileges.sqlSQL
1
2
3
4
5
6
7
8
-- Grant necessary privileges to a role
GRANT USAGE ON DATABASE my_db TO ROLE analyst;
GRANT USAGE ON SCHEMA my_db.public TO ROLE analyst;
GRANT USAGE ON STAGE my_unstructured_stage TO ROLE analyst;
GRANT READ ON STAGE my_unstructured_stage TO ROLE analyst;

-- Verify grants
SHOW GRANTS TO ROLE analyst;
Output
+-------------------------------+-----------+-----------------+
| PRIVILEGE | GRANTEE | GRANTED_BY |
|-------------------------------+-----------+-----------------|
| USAGE ON DATABASE my_db | ANALYST | ACCOUNTADMIN |
| USAGE ON SCHEMA my_db.public | ANALYST | ACCOUNTADMIN |
| USAGE ON STAGE my_unstructured_stage | ANALYST | ACCOUNTADMIN |
| READ ON STAGE my_unstructured_stage | ANALYST | ACCOUNTADMIN |
+-------------------------------+-----------+-----------------+
🔥Minimum Privileges
📊 Production Insight
Use Snowflake's access history views to audit who accessed which files.
🎯 Key Takeaway
Secure your stages with RBAC, network policies, and encryption. Grant minimal privileges.
● Production incidentPOST-MORTEMseverity: high

The Stale Directory Table That Broke Data Pipelines

Symptom
Queries against the directory table returned zero rows for recently uploaded files, causing downstream processing to skip new data.
Assumption
The developer assumed directory tables automatically reflect file changes in real time, similar to standard tables.
Root cause
Directory tables cache metadata and require an explicit ALTER STAGE ... REFRESH command to update after file additions or deletions.
Fix
Added a scheduled task to refresh the directory table after each bulk upload, and implemented a check for metadata staleness.
Key lesson
  • Directory tables do not auto-refresh; always refresh after file changes.
  • Use Snowflake tasks or external orchestration to automate refreshes.
  • Monitor directory table row counts to detect staleness.
  • Consider using event notifications (e.g., SQS) to trigger refreshes.
  • Document the refresh requirement in runbooks.
Production debug guideSymptom to Action4 entries
Symptom · 01
Directory table returns no rows for new files
Fix
Run ALTER STAGE <stage_name> REFRESH; and verify files exist in the stage.
Symptom · 02
REST API returns 403 Forbidden
Fix
Check that the role has USAGE on the stage and that the stage's directory table is enabled.
Symptom · 03
File processing UDF fails with 'file not found'
Fix
Verify the file URL is correct and the file exists in the stage. Use LIST STAGE to confirm.
Symptom · 04
Query on directory table is slow
Fix
Ensure the directory table is refreshed; stale metadata can cause full scans. Consider clustering on file name.
★ Quick Debug Cheat SheetCommon issues and immediate actions for unstructured data in Snowflake.
Directory table empty
Immediate action
Refresh stage
Commands
ALTER STAGE my_stage REFRESH;
SELECT * FROM DIRECTORY(@my_stage);
Fix now
Schedule periodic refreshes.
REST API 403+
Immediate action
Check role privileges
Commands
SHOW GRANTS TO ROLE my_role;
GRANT USAGE ON STAGE my_stage TO ROLE my_role;
Fix now
Grant USAGE and ensure directory table enabled.
UDF file not found+
Immediate action
List stage files
Commands
LIST @my_stage;
SELECT file_url FROM DIRECTORY(@my_stage) WHERE relative_path = 'file.csv';
Fix now
Use correct relative path.
FeatureDirectory TableREST APIPython UDF
PurposeQuery file metadataUpload/download filesProcess file content
Refresh RequiredYesNoNo
File Size LimitNone128 MBDepends on UDF timeout
AuthenticationSnowflake sessionToken/OAuthSnowflake session
Use CaseDiscover filesIngest filesTransform files
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
create_stage_with_directory.sqlCREATE OR REPLACE STAGE my_unstructured_stageWhat Are Directory Tables?
upload_file.shcurl -X PUT \Using the REST API for File Operations
csv_row_count_udf.pyCREATE OR REPLACE FUNCTION count_csv_rows(file_url STRING)Processing Files with Python UDFs
refresh_task.sqlCREATE OR REPLACE TASK refresh_directory_tableBest Practices for Directory Tables
copy_into.sqlCREATE OR REPLACE TABLE raw_data (Handling File Formats and Large Files
grant_privileges.sqlGRANT USAGE ON DATABASE my_db TO ROLE analyst;Security and Access Control

Key takeaways

1
Directory tables provide SQL access to file metadata but require manual refresh.
2
REST API enables programmatic file upload/download with token-based auth.
3
Python UDFs can process files in stages for unstructured data analysis.
4
Automate refreshes and secure stages to maintain production reliability.

Common mistakes to avoid

4 patterns
×

Forgetting to refresh directory table after uploading files

×

Using REST API for large file uploads

×

Granting excessive privileges on stages

×

Assuming directory tables show files from subdirectories automatically

INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is a directory table in Snowflake and how do you enable it?
Q02SENIOR
How do you refresh a directory table and why is it necessary?
Q03SENIOR
Describe a scenario where you would use the REST API for file operations...
Q04SENIOR
What are the limitations of Python UDFs for file processing in Snowflake...
Q05SENIOR
How would you design a pipeline to process thousands of new files every ...
Q01 of 05JUNIOR

What is a directory table in Snowflake and how do you enable it?

ANSWER
A directory table is a metadata view of files in a stage. Enable it by setting DIRECTORY = (ENABLE = TRUE) when creating or altering the stage.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Do directory tables update automatically?
02
Can I use the REST API to upload files larger than 128 MB?
03
How do I process files in a Python UDF?
04
What is the cost of directory tables?
05
Can I query directory tables across multiple stages?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Written from production experience, not tutorials.

Follow
Verified
production tested
2026-07-17T18:30:00
last updated
2,439
articles · all by Naren
🔥

That's Snowflake. Mark it forged?

3 min read · try the examples if you haven't

Previous
Drivers and Connectors: Python, JDBC, Kafka, Spark, and More
32 / 33 · Snowflake
Next
Views, Secure Views, Result Caching, and Alerts in Snowflake