In OpenTofu, a normal plan refreshes its view of remote objects and proposes changes to bring them in line with configuration; it does not execute those changes. Use -refresh-only when the goal is to record intentional changes made outside OpenTofu, and reserve -destroy for planning removal of tracked objects. Keep backend-supported state locking enabled: disabling it can put concurrent operations at risk.
What a normal OpenTofu plan does
When you run tofu plan in a working directory and workspace, OpenTofu reads the current settings of tracked remote objects, refreshes its state view, compares that view with the configuration, and proposes actions. The plan is a preview, not an execution: OpenTofu says the plan command alone does not carry out the proposed changes.
A direct tofu apply without a saved plan generally generates a fresh plan and asks for approval before carrying out its actions. The plan therefore separates deciding what should change from applying those changes.
Refresh options: refresh state or skip the read?
Default refresh
Normal planning includes a refresh from remote objects. This helps OpenTofu account for changes that happened since the state was last updated, including changes made outside the usual workflow. The resulting proposal is based on the refreshed view and the current configuration.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
-refresh=false: skip remote refresh
tofu plan -refresh=false tells OpenTofu not to update its state view from remote objects before planning. It can reduce remote API requests, but it can also leave outside changes unaccounted for and produce an incomplete or incorrect plan. Treat it as a deliberate exception, not a general speed setting.
If a plan behaves as though refresh were disabled even though you did not type the option, check whether TF_CLI_ARGS_plan is setting options for plan invocations. OpenTofu documents this environment variable as a way to inject plan arguments, including -refresh=false (environment variables reference).
-refresh-only: reconcile state with remote reality
Refresh-only mode has a different purpose: it plans updates to OpenTofu state and root-module outputs so they reflect changes made to remote objects outside the normal workflow. For example, after an intentional console-side change, review a refresh-only plan if you want OpenTofu’s recorded state to reflect that reality.
Rank #2
This is not the same as -refresh=false. The latter skips refresh; refresh-only makes reflecting remote changes the plan’s goal. It does not ask OpenTofu to change remote objects merely to make them match configuration.
Choose the planning mode by the intended outcome
OpenTofu has three modes. Normal mode is the default; destroy and refresh-only are alternatives and cannot be combined with each other. These modes apply to tofu plan and to tofu apply when you are not applying a previously saved plan file. See the plan mode reference and apply command reference.
| Mode | Command | Plan goal | Effect when applied |
|---|---|---|---|
| Normal | tofu plan |
Propose actions to make remote objects match configuration, using refreshed state by default. | Executes the approved proposed actions. |
| Refresh-only | tofu plan -refresh-only |
Plan state and root-output updates to reflect remote changes. | Updates recorded state and outputs rather than reconciling remote objects to configuration. |
| Destroy | tofu plan -destroy |
Plan destruction of remote objects tracked by OpenTofu. | Destroys the tracked objects if the plan is applied. |
Use destroy mode only when removal is actually intended; the flag creates a destructive plan, but planning alone does not delete anything. For changes made out of band, use refresh-only when the intended outcome is state reconciliation. A normal plan may instead propose infrastructure changes to restore configuration.
Rank #3
State locking: keep concurrent writers from colliding
For operations that could write state, OpenTofu automatically locks state when the configured backend supports locking. A lock prevents another operation from acquiring the same state concurrently; if OpenTofu cannot acquire the lock, it does not continue. Not every backend supports locking, so check the documentation for the backend you use. See OpenTofu’s state-locking documentation.
Wait for temporary contention
If another operation is expected to release the lock shortly, -lock-timeout=DURATION tells OpenTofu to retry acquiring it for a period before returning an error. For example, tofu plan -lock-timeout=30s waits up to the specified duration. This is a wait, not a way to bypass a lock; exact option behavior can vary by command.
Avoid -lock=false when others may be working
The -lock=false option disables locking for most commands and is explicitly discouraged. If another operator or automation process accesses the same workspace at the same time, suppressing the lock can put state integrity at risk. Prefer waiting or diagnosing the existing lock rather than allowing concurrent state writers.
Rank #4
Use force-unlock only for your own abandoned lock
If automatic unlocking failed, tofu force-unlock can release a lock using its unique lock ID. Use it only for a lock you own after automatic unlocking has failed. Releasing another operator’s active lock can allow multiple writers to proceed.
Speculative plans and saved plan files
Without -out, tofu plan produces a speculative plan: a preview with no intent to apply. Use -out=tfplan to save an opaque plan artifact that can later be supplied to tofu apply:
tofu plan -out=tfplan— create and save the planned actions.- Review the plan through your normal approval process, protecting the file as sensitive.
tofu apply tfplan— apply the saved plan.
A saved plan supports a review-and-apply workflow, but it is not safe to treat as ordinary log output. It can contain full configuration, planned values, and sensitive values in cleartext even when terminal output redacts them. Restrict access and do not casually attach plan files to tickets or logs. A speculative plan can also become stale as infrastructure changes; check a final non-speculative plan before applying if conditions have changed.
Best Value
Why the standalone tofu refresh command is deprecated
The separate tofu refresh command reads remote object settings and updates state without first giving you an opportunity to review the changes. OpenTofu describes it as effectively equivalent to tofu apply -refresh-only -auto-approve and recommends the reviewable alternative tofu apply -refresh-only. See the refresh command documentation.
The risk is especially serious if provider credentials are misconfigured: OpenTofu may conclude that managed objects were deleted and remove them from tracked state without a confirmation prompt. Prefer a refresh-only plan and an approval step when reconciling state.
Command examples
tofu plan— make a normal speculative plan with refresh enabled.tofu plan -refresh=false— skip refresh, accepting the risk of a plan based on stale state.tofu plan -refresh-only— plan state and root-output updates based on remote changes.tofu plan -destroy— plan destruction of tracked objects.tofu plan -lock-timeout=30s— retry lock acquisition for up to the chosen duration.tofu plan -out=tfplan— save a sensitive plan artifact for later application.tofu apply tfplan— apply that saved plan.tofu apply -refresh-only— review and approve state reconciliation.
These examples describe documented option semantics; command details and deprecation status can change between OpenTofu releases. Consult the current documentation for your installed version and configured backend.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




