Snowflake Architecture: Three Layers and What Each One Bills For

A team runs its nightly load and its morning dashboards on the same platform, and for the first year nobody thinks about the architecture at all. Then the load starts overrunning into business hours, the dashboards slow down, and someone asks why adding capacity for one did nothing for the other. The answer is in a structural choice the product made early: storage, compute, and coordination are three separate layers, they are billed on three different principles, and the one people watch is not the only one on the invoice.

This article describes that structure as documented on September 15, 2026, and works outward from it: how data is physically organized, how compute is bought and why concurrency is a separate purchase from speed, how access is granted, what sharing does that copying cannot, and where credits go. Cloud products change, so treat the shape as durable and the specifics as dated. Examples are invented, and no rates appear here because they vary by region, edition, and contract.

Three layers, and what each is for

The documentation describes the architecture as a hybrid of traditional shared-disk and shared-nothing designs: one shared copy of the data, as in shared-disk, processed by independent compute nodes that do not share resources, as in shared-nothing. That combination is what the three layers implement.

LayerWhat it doesShared or separate
Database storageHolds table data, reorganized into an internally optimized, compressed, columnar form in cloud storageShared: one copy, visible to every warehouse
Query processingExecutes SQL in virtual warehouses, which are independent compute clustersSeparate: warehouses do not share resources, so one does not affect another’s performance
Cloud servicesCoordinates the platform: authentication, metadata, query optimization, access control, complianceShared: every request passes through it

The middle row is the one to hold onto, because it settles the opening question. The nightly load and the morning dashboards can run on different warehouses reading the same tables, and then the load cannot slow the dashboards down. Making one warehouse bigger does nothing for the other, because they were never sharing anything to begin with. This is the concrete form of what earlier discussions call workload isolation: isolation of compute without duplication of data.

The storage layer also accepts more than one kind of table. The documented types include Snowflake’s own tables, Apache Iceberg tables, and hybrid tables, which matters for anyone weighing how portable their data will be — the subject of external tables and the lake/warehouse boundary — and is a question worth settling per table rather than per platform.

How the data is physically arranged

Storage is divided into micro-partitions: contiguous units of 50 to 500 MB of uncompressed data, formed transparently in the order data is inserted or loaded, with no definition or maintenance required from the user. Within each one, columns are stored and compressed independently, with the compression algorithm chosen automatically.

What makes them useful is the metadata kept about each: the range of values for every column, the number of distinct values, and other properties. That is what allows precise pruning at query time — skipping micro-partitions that cannot satisfy a filter, then reading only the needed columns within those that can. It is the same mechanism as partition pruning elsewhere, with the difference that nobody chose a partition key.

The documentation makes three claims for this over traditional static partitioning, and each removes a decision that is easy to get wrong: the units do not have to be defined or maintained up front, they are small enough to make DML efficient, and because their ranges may overlap, the scheme avoids the skew that a badly chosen partition key produces.

Automatic does not mean indifferent to layout, though. How much pruning is available still depends on whether a column’s values are concentrated within few micro-partitions or spread across all of them, which is what a clustering key influences. Snowflake measures the result as clustering depth, the average depth of overlapping micro-partitions, where lower is better — while noting that query performance is a better indicator of good clustering than the depth number by itself. That caveat is worth taking literally: clustering is a cost, and the reason to pay it is a query that got faster, not a metric that improved.

Warehouses: buying speed and buying concurrency

A virtual warehouse is the unit of compute, and two different problems are solved by two different adjustments to it.

  • Scaling up means a larger warehouse. The documentation describes this as more beneficial for slow-running queries and for data loading — one unit of work that needs more resources.
  • Scaling out means more clusters in a multi-cluster warehouse. This improves concurrency, letting more queries run simultaneously without queueing.

The condition that separates them is documented plainly: if there are not enough resources to execute all the queries submitted, the extra ones are queued. So the diagnostic question is whether a slow query is slow while running or slow while waiting.

The two levers overlap rather than divide cleanly, and Snowflake’s guidance on working with warehouses says so directly: resizing can also help reduce the queuing that occurs when a warehouse lacks the compute to process everything submitted concurrently, since finishing each query sooner drains a queue faster. The same guidance sets the boundary — resizing is not intended for handling concurrency issues, and the documented answer for a large number of concurrent users and queries is additional warehouses or a multi-cluster warehouse. Read them together: size primarily changes how long a query runs and can relieve a queue as a consequence, while cluster count is aimed at the queue itself. It also notes that larger is not necessarily faster, and that small queries already executing quickly may show no significant improvement — which is why paying for size to fix a concurrency problem tends to cost more than it returns.

Multi-cluster warehouses run in one of two modes. Maximized sets minimum and maximum clusters to the same value above one, so all clusters run continuously once the warehouse starts — suited to load that is known and steady. Auto-scale sets a maximum above the minimum and lets Snowflake start and stop clusters with the load.

Auto-scale then carries a policy choice that is easy to miss, because it changes behavior at exactly the moment a queue forms.

PolicyStarts a cluster whenShuts one down whenFavors
StandardA query is queued, or resources are insufficientLoad has been low for a sustained period, one cluster at a timeResponsiveness
EconomyThe system estimates at least six minutes of work aheadFewer than six minutes of work remainCredit conservation

Standard is the right default for interactive work, where a queued dashboard query is the problem being solved. Economy suits queues that are expected and tolerable, such as a batch window. Choosing Economy for a BI warehouse produces a platform that is slow precisely when people are waiting, and choosing Standard for a bursty batch workload spins up clusters for work that would have finished anyway.

Because warehouses are independent, they are also the natural unit of design rather than a setting to tune. A warehouse per workload class — loading, transformation, BI, ad-hoc exploration — gives each one its own size, its own scaling policy, and its own line in the bill, and prevents any of them from delaying the others. It also multiplies the number of things that can be left running, which the next section is about.

Who may see what

Access control combines two models. Under discretionary access control, every object has an owner, and the owner can grant access to it. Under role-based access control, privileges are assigned to roles and roles are assigned to users. A third mode assigns privileges directly to users and applies when secondary roles are set to all.

Four terms carry the model. Securable objects are the things access can be granted on, and access is denied unless explicitly granted. Privileges are defined levels of access to an object. Roles receive privileges and are granted to users or to other roles. Users are identities, whether a person or a service.

The part that shapes designs is that roles can be granted to other roles, forming a hierarchy in which a role inherits the privileges of the roles beneath it. System-defined roles exist for the standard separations: organization-level administration, ACCOUNTADMIN as the top-level role combining system and security administration, SECURITYADMIN for global grant management and user and role administration, USERADMIN for creating users and roles, SYSADMIN for creating warehouses and database objects, and PUBLIC as a pseudo-role automatically granted to everyone.

Three consequences are worth designing for rather than discovering.

  • Ownership is a privilege, and it usually lands on whoever created the object. Owning an object means holding the OWNERSHIP privilege, and the owning role gets the default privileges including the ability to grant and revoke. So an object created by a personal role becomes something only that role fully controls, which is how a table ends up dependent on one departed colleague’s role. Creating objects under a functional role rather than an individual one avoids it.
  • Inheritance flows upward, so hierarchies grant more than they appear to. A role high in the hierarchy accumulates everything below it. Hierarchies built for convenience tend to end with a role that can see everything and several people holding it.
  • PUBLIC is granted to everyone automatically. Anything granted to it is granted to all users, which makes it a convenient shortcut and a poor place for anything sensitive.

There is also a variant worth knowing when delegation is the goal: in a managed access schema, only the schema owner controls grants, rather than each object’s owner. That inverts the default and is the mechanism for keeping grant authority in one place while letting many people create objects. Whichever model is chosen, the platform’s roles do not answer who decides what the data means, which remains the question of a named data owner.

Sharing rather than sending

Getting data to another organization normally means an extract, and the platform offers an alternative within its own boundary. In Secure Data Sharing, no actual data is copied or transferred between accounts; the sharing works through the services layer and the metadata store, and the data stays in the provider’s storage.

The economics follow from that and are worth stating precisely, because they are what make the feature different from a fast extract. Shared data does not occupy storage in the consumer’s account and so does not contribute to its storage charges. The only charges to the consumer are for the compute used to query the imported data. And updates to existing objects in a share become immediately available to all consumers.

The last point is the one that changes how people work. An extract is stale from the moment it is produced, which is why every extract eventually needs a freshness statement, a pipeline, and a reconciliation against the source. A share within a region has none of those, because there is one copy.

Within a region is the qualifier to carry, and it is the difference between a feature and a plan. Snowflake documents that sharing across regions or cloud platforms uses its data replication functionality: the provider creates one copy of the dataset per region — one per region rather than one per consumer — and refreshes the replication group manually or on a schedule set by a parameter. Everything the previous paragraph said then changes. There is a second copy occupying storage, replication cost that scales with what is replicated, and a refresh cycle that bounds how current the consumer’s view is — so the three things a share removed all come back in a smaller form.

Do not read that schedule as the freshness guarantee, though, because it sets the interval between starts rather than a bound on staleness. The replication run itself takes time, failures get retried, and the documentation for the schedule parameter states that a valid run time is skipped if the previous run has not completed before the next one starts. A ten-minute schedule over a seven-minute replication does not promise ten-minute-old data, and a run that overruns its interval costs the following cycle entirely. What a consumer can actually be promised is a measured lag, monitored, with the schedule as the control you adjust to hold it.

Cross-region sharing is still usually better than letting each consumer build its own extract, because there is one replica per region rather than one per consumer, but it belongs in the design as a replication decision rather than as an extension of zero-copy sharing.

Both forms share a constraint: the parties have to be on the platform. So this is a reason to prefer sharing where it applies rather than a general solution to data distribution.

Credits, and how to bound them

Each layer is billed on its own principle, and the three are worth seeing together before optimizing any one of them.

LayerWhat is billedWhat moves it
StorageA flat rate per terabyte, computed monthly from the average on-disk bytes stored per dayData volume and how long history is retained — not query activity
Query processingCredits for user-managed warehouses, per second with a 60-second minimum each time a warehouse startsSize, running clusters, and running time
Cloud servicesCredits, but charged only when daily cloud services consumption exceeds 10% of daily warehouse usageMetadata-heavy activity relative to how much warehouse compute runs alongside it

Two consequences follow that the warehouse-only view misses. Storage accrues whether or not anyone queries, so a well-tuned platform with years of unreviewed retention still has a growing bill that no query optimization touches. And the cloud services adjustment has a shape worth understanding: because the 10% is measured against daily warehouse usage, a workload made of many small metadata-heavy operations with little warehouse compute is the pattern most likely to cross it — the threshold moves with what else you are running.

There is also a fourth source that belongs in a budget even though it has no layer of its own. Serverless features use Snowflake-managed compute rather than a virtual warehouse and are billed separately, which means they do not appear where teams look for warehouse spend. Data transfer is billed too: ingress is not charged, but egress is when data moves to a different region on the same cloud or to another cloud platform — the line item that the cross-region sharing discussed above creates.

The warehouse layer is nonetheless where most controllable spend sits, and the documented formula for a multi-cluster warehouse is direct: credits consumed are the warehouse size multiplied by the number of running clusters multiplied by the hours they run. Both scaling directions are multiplicative, which is why enabling auto-scale and increasing size are each capable of producing a surprise.

Consumption grows through a small number of paths, and each has a control that acts before the money is spent rather than a report that explains it afterwards.

Where it growsControl that acts in advance
Warehouses left running with nothing to doAuto-suspend set short enough to matter, with auto-resume so nobody is tempted to disable it
Auto-scale reaching for clusters during ordinary burstsA maximum cluster count, and the Economy policy where a queue is acceptable
Warehouses sized for the worst query and used for every querySeparate warehouses per workload class, sized for their own work
Queries scanning far more than they needClustering where it earns its cost, and query profiles reviewed against table size
Storage growing with retained history nobody reviewsA retention decision per dataset, since no warehouse setting affects this
Warehouse consumption discovered at the end of the monthResource monitors, described below

A resource monitor tracks the credits used by user-managed virtual warehouses, along with the cloud services credits supporting them, over a chosen interval. It exists at one of two levels: an account monitor observes all warehouses and there is one per account, while warehouse monitors observe assigned warehouses, with any warehouse belonging to at most one. A credit quota sets how many credits are allocated for the interval, which defaults to monthly and can be set to daily, weekly, yearly, or never.

Its scope is exactly what that first sentence says, and the gap is the point: a resource monitor watches user-managed warehouse credits and the cloud services supporting them. Storage is not in scope, and neither is serverless compute, which uses Snowflake-managed resources rather than a warehouse. So a monitor is a guardrail on the largest and most variable component, not a cap on the bill, and the components it does not cover need a review cadence instead of a threshold.

At threshold percentages of that quota, three actions are available, and the difference between the last two matters during an incident.

  • Notify sends an alert and does nothing to the warehouse.
  • Suspend stops the warehouse after the queries currently executing have finished.
  • Suspend Immediate stops it at once, cancelling the queries that are running.

A workable arrangement is to notify early, suspend at a level that represents a genuine overrun, and reserve suspend-immediate for warehouses where an abandoned query is cheaper than continued spending.

What a cancellation actually leaves behind is worth being precise about, because the risk is real but not the one people assume. A cancelled statement does not leave half its rows committed: with autocommit on, each statement outside an explicit transaction runs in its own implicit single-statement transaction and is committed if it succeeds and rolled back if it fails, and within an explicit transaction a failed statement’s changes are rolled back as well. The exposure is at the level above. A load built from several statements that each commit — stage, merge into a target, update a control table — can be interrupted between them, leaving the earlier steps applied and the later ones not. So suspend-immediate does not corrupt a table; it can leave a pipeline half-done, which is a different problem with a different fix: make each run resumable or idempotent, and check the control table rather than the target when a job is interrupted. Where a job cannot be made restartable, it is a poor candidate for suspend-immediate, and that choice belongs with whoever understands what runs there.

One administrative detail shapes the rollout: the documentation states that only users with the ACCOUNTADMIN role can create a resource monitor, though an account administrator can grant other roles the privileges to monitor or modify them. Cost guardrails are therefore established centrally even when the spending is decentralized, which means the people who own the budgets need someone with that role to act for them — a dependency worth arranging before the first surprise rather than during it.

A short checklist

QuestionIf the answer is unclear
Which workload classes have their own warehouse, and which share one?Loads and dashboards delay each other on a platform designed to prevent exactly that
Is the current slowness queueing or execution?Capacity is bought in the direction that does not help
Which scaling policy is set on each warehouse, and does it match what runs there?Interactive queries wait, or clusters start for work that would have finished
Are objects created by functional roles or by individuals?Ownership follows a person, and their departure becomes an access problem
What is granted to PUBLIC?Everyone has access that nobody deliberately gave them
Which datasets are shared and which are extracted, and why?Copies accumulate where a share would have been current by definition
Which warehouses have a resource monitor, and what does it do at the threshold?Spending is discovered after the fact, or a load is cancelled mid-write

Questions to explore further

  • For last month’s credits, how much was consumed by warehouses that were running but not executing a query?
  • Which roles in your hierarchy can reach the most sensitive table, counting inherited privileges rather than direct grants?
  • How many of your recurring extracts go to parties who could read a share instead?
  • If a runaway query doubled your daily spend, what would stop it, and how long would that take?

References

All sources were checked on September 15, 2026. Cloud platform architecture, feature availability by edition and region, and pricing change frequently; confirm against current documentation before relying on any of it.


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.