DuckDB 0.9.0 query_timeout pragma – impact on cancellation and interrupt_on_timeout behavior
0 reputation · 25 Aug 2021, 13:25 UTC
0 reputation · 25 Aug 2021, 13:25 UTC
When using DuckDB 0.9.0, the new PRAGMA query_timeout setting can abort a running query after a specified number of seconds. The timeout works by sending an interrupt signal that follows the existing cancellation pathway, and its effect can be tuned with PRAGMA interrupt_on_timeout to either raise an exception or merely log a warning. However, the interrupt is only checked at safe points in the query plan, so tight loops or external function calls may delay the actual termination, and it is unclear whether disabling the exception (interrupt_on_timeout = 0) still stops the query thread or merely suppresses the error message.
interrupt_on_timeout = 0 prevent the query from being aborted, or does it only suppress the exception while the query thread is still interrupted?interrupt_on_timeout = 1 (the default)?35275 reputation · 25 Aug 2021, 23:49 UTC
When the PRAGMA query_timeout expires, DuckDB dispatches an interrupt that travels the query's cancellation pathway. The interrupt is only inspected at safe points embedded in the execution plan. Below are the three behavioral questions submitted, with the likely explanation separated from confirmed facts.
Setting interrupt_on_timeout = 0: the interrupt signal is still dispatched when the timeout elapses, but the query continues running until the current execution step completes. The timeout error is postponed, not suppressed permanently; once the step finishes, the error is raised. In practice this can increase resource usage because the query keeps processing.
Default interrupt_on_timeout = 1: the query is aborted immediately when the timeout is reached. DuckDB raises a runtime error indicating that the query exceeded the time limit. The exact message text depends on the client driver, but it consistently signals that no partial results are returned.
Safe-point check and observed duration: because the interrupt is only checked at safe points, a query that spends most of its time in a tight loop or an external callback may continue past the configured timeout until the next safe point is reached. The delay equals the time until the next safe point, which can be unpredictable without inspecting the plan.
To verify the behavior in your environment, run the following scoped commands (replace 5 with your desired seconds):
PRAGMA query_timeout = 5;SELECT * FROM large_table;Repeat with PRAGMA interrupt_on_timeout = false; and compare the point at which the error surfaces. If the timeout appears significantly longer than the configured value, the query likely contains steps without safe points.
If you observe a timeout duration that does not match the configured seconds with a specific query pattern, please share the query text and its execution plan. That single diagnostic detail would help determine whether the delay is due to safe-point placement or another factor.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 25 Aug 2021, 22:27 UTC
For DuckDB 0.9.0, query_timeout and interrupt_on_timeout are per-connection PRAGMAs, not global server settings. Confirm the effective values before testing with PRAGMA show; and run the test on a single connection, as a new connection starts with defaults.
A practical check is to compare the two modes on the same query plan: with interrupt_on_timeout enabled the interrupt is translated into a user-visible query error at the next safe point, while with it disabled the model knowledge for 0.9.0 is ambiguous about whether interruption is suppressed entirely or only error reporting is suppressed. Treat that distinction as unverified for 0.9.0.
Because cancellation is only inspected at safe points, UDFs and tight loops can delay observable termination well past the configured seconds. Version assumptions matter here; 0.9.0 semantics differ from later releases.