- Snowflake documents GEOGRAPHY, GEOMETRY, spatial functions, and H3 functions. Check current account edition, region, and function limits before choosing it
- H3 can provide a common index for some aggregation and join patterns, but resolution, geometry conversion, data volume, and output checks must be tested
- Warehouse sizing, clustering, search optimisation, storage, and query shape affect cost and runtime. The retained cost table is not a current estimate
- Snowpark Python can extend a SQL workflow, but package support, memory, execution limits, and data movement require a target-account check
- Marketplace and data-sharing options are account, provider, region, and contract dependent; verify current availability before relying on them
Geospatial in Cloud Series
This is Part 4 of our Geospatial in Cloud series. Each post is self-contained. Part 1 covers Databricks. Part 2 covers AWS. Part 3 covers GCP. Read the one that matches your stack.
Snowflake can provide a warehouse-based boundary for spatial analytics. The current account, edition, region, package support, query shape, and operating model still need to be checked for the target workflow.
The boundary matters. Current Snowflake documentation and the target account must be checked for raster, 3D, CRS, topology, package, and query requirements. If the workflow needs capabilities outside that boundary, compare another spatial runtime.
Point-in-polygon joins, H3 aggregation, exposure analysis, and location intelligence may fit a SQL-first workflow. Validate the data movement, query, cost, output, and failure path before making a platform claim.
Why Snowflake for Geospatial
If the team is SQL-first and the data is already in Snowflake, a warehouse boundary may reduce some setup work. It does not remove the need to check functions, data loading, edition, cost, permissions, and validation.
Warehouse-based execution
Warehouse sizing, auto-suspend, concurrency, edition, and region affect the operating model. Check current account behaviour before estimating cost or runtime.
H3 in SQL
Snowflake documents H3 functions. Resolution, geometry conversion, data volume, clustering, and output checks must be tested for the target join or aggregation.
Data sharing options
Marketplace and sharing features depend on the provider, account, region, licence, and contract. Verify the current path before relying on it.
SQL workflow
Native SQL may reduce context switching for a SQL-first team. Check the required functions, Python boundary, package support, and review process.
GEOGRAPHY vs GEOMETRY
Snowflake provides two spatial data types. Choosing the wrong one is one of the most common mistakes we see teams make in their first week.
GEOGRAPHY models the earth as a sphere using WGS 84 (SRID 4326). Coordinates are longitude/latitude degrees. Distance calculations return metres on the spherical surface. This is the type most GIS engineers reach for first - it maps directly to the lon/lat paradigm from QGIS and ArcGIS.
GEOMETRY uses a planar Cartesian coordinate system. It supports arbitrary SRIDs - EPSG:27700 for British National Grid, EPSG:32632 for UTM Zone 32N, whatever your data uses. Calculations are Euclidean. Use this when your data lives in a projected coordinate system and you need metre-accurate distances without spherical distortion.
Critical limitations to know
- Only 2D coordinates supported - no Z (elevation) or M (measure) values
- You cannot cast between GEOGRAPHY and GEOMETRY - they are separate worlds
- Check the current GEOGRAPHY CRS and coordinate semantics before loading
- Column size limit is 64 MB per value (increased from 8 MB in 2025)
- GEOGRAPHY uses a perfect sphere model, not an ellipsoid - slight accuracy differences vs PostGIS for geodetic work
Rule of thumb: if your data is in lon/lat and you are doing analytics (distance, containment, aggregation), use GEOGRAPHY. If your data is in a national or UTM projection and you need precise planar geometry operations, use GEOMETRY. If you need to convert between projections, use ST_TRANSFORM - but only on GEOMETRY columns.
Spatial SQL Functions
Snowflake documents a set of native spatial functions. Compare the live function reference with the target workflow rather than relying on a count or a general coverage percentage. Confirm the required operation, type, CRS behaviour, account edition, and validation path.
The essentials are all present: ST_DISTANCE, ST_INTERSECTS, ST_CONTAINS, ST_BUFFER, ST_UNION, ST_INTERSECTION, ST_SIMPLIFY, ST_CENTROID, ST_AREA. You can run spatial joins, create buffers, dissolve polygons, calculate distances, and do containment checks.
Two aggregate functions handle the bulk of GIS dissolve operations: ST_COLLECT combines rows into a GeometryCollection, and ST_UNION_AGG dissolves all geometries in a group - the SQL equivalent of ArcGIS Dissolve.
Functions you will miss (coming from PostGIS)
- No
ST_Voronoi/ST_DelaunayTriangles - No
ST_ClusterDBSCAN/ST_ClusterKMeans(use Python UDFs) - No
ST_MakeValidnatively (available via Sedona Native App) - No linear referencing (
ST_LineLocatePoint,ST_LineInterpolatePoint) - No topology operations, no routing, no network analysis
- No raster functions at all
One possible extension is the Apache Sedona Native App (SedonaSnow), subject to current Marketplace availability, account terms, and review. It may add ST_MakeValid, ST_SubDivide, broader CRS support via ST_Transform, and more. Check the current package, permissions, cost, and output before adopting it.
H3 Indexing Patterns
H3 is a hexagonal indexing system. Snowflake documents H3 functions that can support some indexing and aggregation patterns. Check the live function reference and target account before relying on a particular function or resolution.
A useful test is to compare a traditional spatial join ( ST_INTERSECTS on two large tables) with a common H3 key. Convert both datasets at a documented resolution, join on the derived key, and verify false positives, false negatives, boundary behaviour, output size, and query cost. The performance result is workload-specific.
The key functions: H3_LATLNG_TO_CELL(lat, lng, resolution) converts a point to an H3 cell index. H3_COVERAGE(geography, resolution) covers a polygon with the minimal set of H3 cells. H3_CELL_TO_BOUNDARY(cell) converts back to a hexagonal polygon for visualisation. H3_CELL_TO_PARENT and H3_CELL_TO_CHILDREN navigate the hierarchy for multi-resolution analysis.
H3 RESOLUTION GUIDE
Resolution 3
~12,400 km2 - Country-level
Resolution 5
~253 km2 - Regional analysis
Resolution 7
~5.16 km2 - City / catchment areas
Resolution 9
~0.105 km2 - Neighbourhood / postcode
Resolution 11
~0.002 km2 - Building level
Resolution 15
~0.9 m2 - Sub-metre precision
A possible pattern is to add an H3 column, choose a resolution for the required output, cluster if the account and workload support it, and compare the result with the original geometry predicate. The resolution and clustering choice require a representative test.
Comparison: Databricks, BigQuery, and Snowflake expose different spatial and indexing models. Compare the current documentation, runtime, data movement, cost, and validation path for the target workflow.
Watch the cell count
Running H3_COVERAGE on large polygons can create many cells. Choose a resolution from the required output, then test cell count, warehouse size, runtime, cost, and boundary accuracy.
Loading Geospatial Data
Snowflake natively understands GeoJSON, WKT, WKB, EWKT, and EWKB. You can load these from staged files (internal or external S3/GCS/Azure stages) via COPY INTO with a TO_GEOGRAPHY() or TO_GEOMETRY() cast.
GeoParquet is the recommended format. It stores geometry as WKB in a binary column, compresses well, and is becoming the interchange standard across Snowflake, Databricks, DuckDB, and BigQuery. Iceberg table support for GEOGRAPHY and GEOMETRY types was announced at Summit 2025 - when GA, this makes GeoParquet round-tripping straightforward across platforms.
Shapefiles are not natively supported. This is friction for every team migrating from ArcGIS. The recommended workflow: convert to GeoParquet locally using ogr2ogr or GeoPandas, upload to a Snowflake stage, then COPY INTO with WKB parsing. Alternatively, use FME's native Snowflake Spatial writer if your organisation already has a licence.
DATA LOADING SUPPORT
One trap to watch: GeoJSON FeatureCollections need to be flattened. Each Feature becomes a row via LATERAL FLATTEN. The GEOGRAPHY type rejects any SRID other than 4326 - if your GeoJSON has a different CRS, you need GEOMETRY instead.
Spatial Indexing
There is no CREATE SPATIAL INDEX in Snowflake. If you come from PostGIS, this feels wrong. But Snowflake has three mechanisms that achieve similar outcomes through different means.
1. Automatic micro-partition pruning
Snowflake stores bounding-box metadata for every micro-partition. When you filter with spatial predicates, it skips partitions whose bounding boxes do not overlap. This is automatic and free. For well-clustered data, it provides significant speedup. For randomly distributed data, it helps less.
2. H3 clustering (recommended)
Pre-compute an H3 index column and cluster the table by it. This ensures spatially proximate data lives in the same micro-partitions, making bounding-box pruning highly effective. This is the cheapest and most impactful optimisation for large spatial tables. Use ALTER TABLE ... CLUSTER BY (h3_column).
3. Search Optimisation Service (Enterprise only)
Creates persistent search access paths for spatial predicates. Enable per-column with ALTER TABLE ... ADD SEARCH OPTIMIZATION ON GEO(column). Supports ST_INTERSECTS, ST_CONTAINS, ST_WITHIN, ST_DWITHIN.
Cost warning: Search Optimisation Service uses a separate cost model. Run the current estimate procedure and check edition, table update rate, region, and account pricing before enabling it.
H3 clustering may be a useful test boundary when the data and query pattern support it. Compare it with micro-partition pruning and Search Optimisation Service using the same data, query, output check, and current account cost model.
Python + GeoPandas Integration
Snowpark Python is the bridge between SQL and Python inside Snowflake. Python UDFs run in a secure sandbox with access to packages from Snowflake's Anaconda channel. The geospatial packages that matter are available: Shapely, GeoPandas, Fiona, PyPROJ, and GDAL.
The primary use case: operations that Snowflake's native SQL cannot handle. Spatial clustering with DBSCAN, complex geometry validation, coordinate transformations across CRS not supported natively, or reading Shapefiles directly from a stage using Fiona.
Performance traps with Python UDFs
- Startup: measure package loading and first-call behaviour for the target warehouse
- Memory: check the current warehouse and Snowpark limits against the operation
- Raster: verify current package support and the required raster boundary before using a Python UDF
- Debugging: retain explicit errors, logs, inputs, outputs, and retry evidence
Snowflake Notebooks (Streamlit-based) let you run GeoPandas interactively inside Snowflake with Pydeck or Folium for visualisation. For exploratory spatial analysis, this can be a useful interactive path. For a repeatable pipeline, define the stored procedure or UDTF boundary, tests, observability, and rollback behaviour.
Streamlit in Snowflake deserves mention: you can build interactive geospatial web apps (maps, dashboards) that run entirely inside your Snowflake account. Data never leaves the platform, access control inherits from Snowflake's RBAC, and there is no infrastructure to manage. For internal tools, this is a compelling alternative to standing up a separate mapping application.
Snowflake vs Databricks for Geospatial
This is a retained comparison framework. Re-run it against the current platform versions, account terms, target data, and validation requirements before choosing a platform.
| FACTOR | SNOWFLAKE | DATABRICKS |
|---|---|---|
| Primary language | SQL (Python via UDFs) | Python/Spark (SQL via Spark SQL) |
| H3 support | Check current function reference | Check current runtime and extensions |
| Spatial functions | Check current function reference | Check current runtime and extensions |
| Raster support | None | Via Mosaic / Sedona |
| 3D geometry | None | Limited |
| Cluster management | None (serverless) | Required (Spark config) |
| Data sharing | Zero-copy (Marketplace) | Delta Sharing (open protocol) |
| Scale boundary | Target test required | Target test required |
| ML on spatial | Cortex ML (basic) + Python UDFs | MLflow + Spark ML + Mosaic |
| Cost model | Credits (simpler) | DBUs + cloud infra (harder to predict) |
Choose Snowflake when: your team is SQL-first, your data is already in Snowflake, you need zero-copy sharing with marketplace data providers, and your workload is vector analytics without raster requirements.
Choose Databricks when: your team is Python/Spark-first, you need raster support, you are building ML pipelines on spatial features, or you are processing at extreme scale (billions of rows with complex geometry operations).
For a parcel-to-zone aggregation, compare both platforms with the same input, H3 or geometry predicate, output verifier, cost model, and operating owner. The result is workflow-specific.
Cost Model
Snowflake charges standard compute credits for all spatial operations - no separate geospatial pricing. You pay per second of warehouse time (1-minute minimum on resume), plus storage.
| WORKLOAD | WAREHOUSE | DURATION | ~COST (ENTERPRISE) |
|---|---|---|---|
| Spatial join — target tables | Target warehouse | Run record required | Model required |
| H3 coverage — target polygons | Target warehouse | Run record required | Model required |
| Batch risk analysis — target data | Target warehouse | Run record required | Model required |
| Point aggregation — target events | Target warehouse | Run record required | Model required |
| Search Optimisation Service | Account-specific | Check current | Source and model required |
A moderate geospatial analytics model must include warehouse size, resume and suspend behaviour, query frequency, storage, transfers, Search Optimisation Service, support, and engineering time. Compare the result with the current licence or self-managed model at the same scope.
Hidden costs to watch
- Search Optimisation Service has a separate current cost and edition model
- Warehouse resume, auto-suspend, concurrency, and idle time affect cost
- High H3 resolutions or large polygons can expand the cell count
- Snowpark-optimised warehouse pricing and limits require a current check
- Edition and region can change feature availability and cost
When NOT to Use Snowflake for Geospatial
Every platform has boundaries. Here are Snowflake's.
Raster or imagery processing
No GeoTIFF, no DEMs, no satellite imagery, no raster algebra. If your workflow touches gridded data, use Databricks (Mosaic), Google Earth Engine, or a dedicated raster pipeline.
3D geometry or LiDAR
Only 2D coordinates supported. No Z values, no M values. Terrain analysis, 3D building models, and point clouds require a different tool.
Low-latency spatial lookups
Snowflake is an analytics boundary. If the target is a low-latency map API, compare a warm service or indexed runtime with the required latency and failure behaviour.
Complex topology operations
Check the current native function set and extension options. If routing, network analysis, linear referencing, or topology is central, compare a runtime designed for that operation.
Heavy CRS transformations
GEOGRAPHY is locked to WGS 84. GEOMETRY supports SRIDs but the built-in CRS catalogue is limited compared to PostGIS. If your workflow requires frequent reprojection between obscure coordinate systems, expect friction.
Budget-constrained teams without Enterprise
The most impactful performance feature (Geo Search Optimisation) requires Enterprise Edition. On Standard Edition, you rely on H3 clustering and micro-partition pruning - still effective, but the ceiling is lower.
Getting Started
If you are already on Snowflake, start by checking the current spatial and H3 function reference, account edition, region, package support, and warehouse policy. Do not assume that every function, extension, or package is available in every account.
Convert your Shapefiles to GeoParquet
Use ogr2ogr or GeoPandas locally. This is the one step you cannot skip - Snowflake does not read Shapefiles natively.
Stage and load
PUT the files to a stage, COPY INTO with TO_GEOGRAPHY() or TO_GEOMETRY(). Validate with ST_ISVALID.
Add H3 indexes
Add an H3 column at resolution 7-9, then cluster by it. This single step gives you the biggest performance improvement.
Start with SQL
ST_INTERSECTS, ST_DISTANCE, ST_AREA, GROUP BY H3 cell. Your SQL analysts can start querying spatial data immediately.
Add Python when needed
Only reach for Snowpark Python UDFs when native SQL cannot do the job - spatial clustering, complex validation, format conversion.
Explore the Marketplace
Check the Snowflake Marketplace for CARTO Analytics Toolbox (70+ extra spatial functions) and third-party geospatial datasets (flood zones, demographics, POI).
Snowflake can be a useful SQL boundary for some spatial analytics workflows. It is not a universal replacement for a spatial database, raster runtime, or topology engine.
For teams that need point-in-polygon joins, H3 aggregation, exposure analysis, and location intelligence in SQL, it may fit. Confirm the current functions, data-sharing path, cost, output, and operational ownership with a representative test.
Know its boundaries. Check raster, 3D, latency, CRS, topology, package, and data-loading requirements. If the workflow fits, compare Snowflake with the alternatives using the same evidence and current account terms.
Get Workflow Automation Insights
Monthly tips on automating GIS workflows, open-source tools, and lessons from enterprise deployments. No spam.
