State Backend Configuration
How Flink's state backend handles state TTL and expired-state cleanup, including GeminiStateBackend-specific behavior, across SQL, DataStream, and Python deployments.
This page covers how Flink's state backend handles state time-to-live (TTL) and expired-state cleanup. It applies to SQL, DataStream, and Python deployments alike.
State TTL Cleanup
Gemini doesn't expire state by default. If no TTL is configured, state lives indefinitely, matching RocksDB's behavior. Expiry applies only when you configure it explicitly: per-state through StateTtlConfig, job-wide through state.backend.gemini.ttl.ms, which works for SQL, DataStream, and Python deployments alike, or through table.exec.state.ttl for SQL deployments. Outside of TTL, state is removed only when your application clears it, or when a job starts without restoring from earlier state or a savepoint.
table.exec.state.ttl sets how long a state entry stays valid before it becomes eligible for removal. Expiry and physical deletion are separate steps: Gemini stops returning an entry as soon as it expires, but deletes it from storage through background compaction, so removal isn't tied to the next read or access.
GeminiStateBackend honors Flink's per-state TTL configuration (StateTtlConfig). state.backend.gemini.ttl.ms sets a job-level default TTL, applicable to SQL, DataStream, and Python deployments, that any per-state TTL configuration overrides.
Gemini differs from RocksDB in how it treats expired data that hasn't been cleaned up yet. Gemini never returns it, matching Flink's NeverReturnExpired state visibility, whereas RocksDB can still return it under ReturnExpiredIfNotCleanedUp. Both backends support the OnCreateAndWrite and OnReadAndWrite update types for refreshing an entry's TTL timestamp.