This check flags Cloud SQL PostgreSQL instances where the log_temp_files flag is unset or disabled, leaving you blind to disk-spilling queries. Set the flag to 0 to log every temporary file and surface inefficient or abusive queries before they hurt performance.
PostgreSQL writes temporary files to disk when a query needs more working memory than work_mem allows. Sorts, hash joins, and large aggregations are common culprits. By default, Cloud SQL does not log these events, so you have no record of which queries are spilling to disk, how often, or how large the spills are. This Lensix check, sql_pgtempfiles, looks at the log_temp_files database flag on your GCP Cloud SQL PostgreSQL instances and reports any instance where it is not enabled.
What this check detects
The check inspects the database flags on each Cloud SQL PostgreSQL instance and verifies that log_temp_files is present and set to a value that logs temporary file usage. The flag controls a threshold, measured in kilobytes:
- -1 (the default) disables temporary file logging entirely.
- 0 logs every temporary file regardless of size.
- Any positive integer logs only temporary files at or above that size in KB.
If the flag is missing or set to -1, the check fails. The recommended secure value is 0, which captures all temporary file activity.
Note: A temporary file is not the same as a temporary table. log_temp_files records the on-disk files PostgreSQL creates when an operation exceeds work_mem. Each logged line includes the file path and its size, which together tell you exactly which query overflowed and by how much.
Why it matters
Temporary file logging is one of those settings that looks like pure performance tuning until you need it during an incident. Here is why it earns a place in your security and reliability baseline.
Disk spills are a silent performance killer
When a query spills to disk, it stops using fast memory and starts hitting storage. On a busy instance this can multiply query latency, exhaust IOPS, and cascade into connection pile-ups. Without logging, you find out about it through user complaints and guesswork rather than data. With logging on, you have a precise record of which statements caused the spill and the size of each file.
It exposes inefficient and abusive queries
Repeated large temporary files often point to a missing index, an unbounded ORDER BY, or a query pulling far more rows than it should. They can also signal a query crafted to consume resources, whether by accident from a bad deploy or deliberately as part of a denial-of-service attempt against your database. Temporary file logs make these patterns visible.
It supports compliance and audit requirements
Benchmarks such as the CIS Google Cloud Platform Foundations Benchmark call out database logging flags explicitly. Auditors expect to see evidence that you can reconstruct database activity, and temporary file logs are part of a complete logging posture alongside log_connections, log_disconnections, and log_min_duration_statement.
Warning: Setting log_temp_files to 0 on a high-traffic instance with many small spills can generate a large volume of log lines. This increases Cloud Logging ingestion, which has a cost. If volume becomes a problem, raise the threshold to a value like 1024 (1 MB) to capture only meaningful spills, but be aware this is a compromise rather than full coverage.
How to fix it
You can enable the flag through the gcloud CLI, the Google Cloud console, or infrastructure as code. Pick whichever matches how you manage the instance.
Warning: Changing a database flag on Cloud SQL may require a restart depending on the flag. log_temp_files is a reloadable flag and does not force a restart on its own, but applying it through gcloud sql instances patch can still trigger a brief maintenance operation. Apply changes during a low-traffic window if you are uncertain.
Option 1: gcloud CLI
First, check the current flags so you do not accidentally drop existing ones. The --database-flags argument replaces the entire flag set on each call.
gcloud sql instances describe INSTANCE_NAME \
--project PROJECT_ID \
--format="value(settings.databaseFlags)"
Then apply log_temp_files=0 alongside any flags you already had. Include every existing flag in the same command:
gcloud sql instances patch INSTANCE_NAME \
--project PROJECT_ID \
--database-flags log_temp_files=0,log_min_duration_statement=1000
Danger: --database-flags overwrites the full list of flags. If you omit a flag that was previously set, it reverts to its default. Always copy the existing flags from the describe output into your patch command, or you risk silently disabling other security and logging settings.
Option 2: Google Cloud console
- Open SQL in the Google Cloud console and select your PostgreSQL instance.
- Click Edit.
- Expand Flags.
- Click Add a database flag, choose
log_temp_files, and set the value to0. - Click Save and confirm.
Option 3: Terraform
If you manage Cloud SQL with Terraform, add the flag to the instance settings block. This makes the configuration durable and reviewable.
resource "google_sql_database_instance" "postgres" {
name = "my-postgres-instance"
database_version = "POSTGRES_15"
region = "us-central1"
settings {
tier = "db-custom-2-7680"
database_flags {
name = "log_temp_files"
value = "0"
}
database_flags {
name = "log_min_duration_statement"
value = "1000"
}
}
}
Apply it with the usual workflow:
terraform plan -out tfplan
terraform apply tfplan
Tip: In Terraform, each database_flags block is additive, so you do not have the overwrite problem you get with the gcloud CLI. Keep all flags declared in the same resource and let Terraform reconcile the full set.
Verify the change
Confirm the flag took effect, then generate some load and check Cloud Logging for the new entries.
gcloud sql instances describe INSTANCE_NAME \
--project PROJECT_ID \
--format="value(settings.databaseFlags)" | grep log_temp_files
Temporary file events appear in the PostgreSQL logs with a message like temporary file: path "...", size NNNN. You can query them in Cloud Logging:
gcloud logging read \
'resource.type="cloudsql_database" AND textPayload:"temporary file"' \
--project PROJECT_ID \
--limit 20
How to prevent it from happening again
Fixing one instance by hand is fine. Stopping the misconfiguration from reappearing across dozens of instances is the real goal. Bake the flag into the way you provision and review databases.
Make it a module default
If you use a shared Terraform module for Cloud SQL, set the logging flags inside the module so every instance inherits them. Teams provisioning a new database get the secure baseline without thinking about it.
variable "extra_database_flags" {
type = map(string)
default = {}
}
locals {
base_flags = {
log_temp_files = "0"
log_min_duration_statement = "1000"
log_connections = "on"
log_disconnections = "on"
}
all_flags = merge(local.base_flags, var.extra_database_flags)
}
Gate it in CI/CD with policy as code
Catch missing flags before they ever reach production by validating Terraform plans in your pipeline. An Open Policy Agent (Conftest) rule can reject any Cloud SQL PostgreSQL instance without temporary file logging:
package main
deny[msg] {
rc := input.resource_changes[_]
rc.type == "google_sql_database_instance"
startswith(rc.change.after.database_version, "POSTGRES")
flags := { f.name: f.value |
f := rc.change.after.settings[_].database_flags[_]
}
not flags["log_temp_files"]
msg := sprintf("%s is missing log_temp_files flag", [rc.address])
}
Run it against a plan in JSON form during the pull request:
terraform show -json tfplan > plan.json
conftest test plan.json --policy policy/
Tip: Pair the CI gate with continuous checks in Lensix so drift is caught even when changes happen outside your pipeline. A console edit or an emergency gcloud command can quietly remove the flag, and only ongoing scanning will flag it again.
Best practices
Temporary file logging works best as part of a broader logging and observability baseline for PostgreSQL on Cloud SQL.
- Enable a full set of logging flags. Combine
log_temp_files=0withlog_min_duration_statement,log_connections=on,log_disconnections=on,log_checkpoints=on, andlog_lock_waits=onfor a complete picture of activity. - Tune
work_memdeliberately. Once you can see which queries spill, decide whether to raisework_memfor the workload, optimize the query, or add an index. Logging without action just fills storage. - Alert on spill volume. Create a log-based metric in Cloud Monitoring counting temporary file events and alert when the rate spikes. A sudden jump often correlates with a bad deploy or a runaway report.
- Review log retention and cost. Decide how long you keep these logs and route high-volume entries to a sink such as BigQuery or Cloud Storage if you need long retention without paying for hot logging storage.
- Apply the same baseline to read replicas. Flags do not always propagate the way you expect. Confirm replicas carry the same logging configuration as the primary.
The flag itself is a one-line change, but the value comes from treating temporary file logs as a signal you actually monitor. Turn it on, build an alert around it, and you convert an invisible class of performance and abuse problems into something you can see and act on.

