# snowflake_table_permanent_regenerable_failsafe

> 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.

Source: https://zop.dev/integrations/snowflake/recommendations/snowflake-table-permanent-regenerable-failsafe
Updated: 2026-08-19

---

## 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

```sql
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_gb
FROM snowflake.account_usage.table_storage_metrics
WHERE failsafe_bytes > 0
ORDER BY failsafe_bytes DESC
LIMIT 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.
