Permanent Snowflake tables paying for Fail-safe they will never use
What does ZopNight detect here?
A PERMANENT Snowflake table carries 7 days of Fail-safe storage billed at the full rate, on top of Time Travel. For regenerable tables such as staging, ELT intermediates, and scratch, that is pure waste. Recreating them as TRANSIENT drops failsafe_bytes to zero.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | snowflake_table_permanent_regenerable_failsafe |
| Category | rightsizing |
| Severity | low |
| Metric | none — pure configuration read |
| Source | signals/tier/snowflake-table-make-transient.yaml |
Where it applies
Fail-safe is not a feature you can turn off
Snowflake bills three storage layers on a PERMANENT table: active bytes, Time Travel bytes, and Fail-safe bytes. Fail-safe is a fixed 7-day window of non-customer-visible recovery storage. You cannot query it, you cannot restore from it yourself, and you cannot disable it.
Only Snowflake support can recover from Fail-safe, and only in a genuine disaster. For a staging table that gets rebuilt every night by the pipeline that populated it, you are paying seven days of storage for a recovery mechanism nobody will ever invoke.
TRANSIENT is the switch
A TRANSIENT table has no Fail-safe at all: failsafe_bytes drops to zero. It keeps Time Travel
(configurable, up to 1 day on transient), so accidental-drop protection remains.
The trade is explicit and worth stating plainly: you lose the disaster-recovery layer you were never going to use, on data you can regenerate. If the table cannot be regenerated, it should stay PERMANENT and this finding does not apply to it.
The signal
The rule looks at snowflake.table.failsafe_bytes averaged over 14 days on tables where
kind = TABLE. Non-zero Fail-safe bytes is the whole condition. The rule does not attempt to guess
whether your table is regenerable, because it cannot.
That judgment is yours, and it is the reason this is a recommendation rather than an automated action.
Querying TABLE_STORAGE_METRICS for failsafe bytes
SELECT table_catalog, table_schema, table_name, active_bytes/POW(1024,3) AS active_gb, time_travel_bytes/POW(1024,3) AS tt_gb, failsafe_bytes/POW(1024,3) AS failsafe_gbFROM snowflake.account_usage.table_storage_metricsWHERE failsafe_bytes > 0ORDER BY failsafe_bytes DESCLIMIT 50;How to convert
There is no ALTER TABLE ... SET TRANSIENT. Conversion means creating a new transient table,
copying the data, and swapping names, so schedule it with the pipeline that owns the table
rather than running it ad hoc against something actively being written.