Speed Up Your Workflows with File Caching
For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append.mdto anykestra.io/docs/*URL for plain Markdown.
Kestra supports two complementary caching strategies: file caching via WorkingDirectory and output caching via taskCache.
- File caching stores files (dependencies, build artifacts) in internal storage and restores them at the start of the next run.
- Output caching stores a task’s status and outputs in the database and skips re-execution entirely when inputs have not changed. See taskCache below.
Cache files in a WorkingDirectory task
Add a cache block to a WorkingDirectory task to persist files across executions.
id: caching_filesnamespace: company.team
tasks: - id: working_dir type: io.kestra.plugin.core.flow.WorkingDirectory cache: patterns: - some_directory/** ttl: PT1HThe cache property accepts a list of glob patterns and a ttl duration after which the cached files are invalidated.
How caching works
Kestra packages the matched files and stores them in internal storage at the end of each run. On the next run, those files are restored before any task executes.
Runner compatibility
File caching works when the script runs in a PROCESS runner. If you use a DOCKER runner, Kestra cannot cache files that exist only inside the container. Attempting to do so throws an error: Unable to execute WorkingDirectory post actions.
To cache pip packages with a Docker runner, install into a subdirectory of the working directory using --cache-dir and cache that directory instead:
id: python_cached_pipnamespace: company.team
tasks: - id: working_dir type: io.kestra.plugin.core.flow.WorkingDirectory cache: patterns: - cache/pip/** ttl: PT24H tasks: - id: python_script type: io.kestra.plugin.scripts.python.Script taskRunner: type: io.kestra.plugin.scripts.runner.docker.Docker beforeCommands: - pip install --cache-dir cache/pip pandas script: | import pandas as pd print(pd.__version__)Because cache/pip lives inside the working directory (not inside the container), Kestra can read and restore it between runs.
Node.js example
This flow installs the colors package and caches node_modules for one hour. Caching node_modules directly requires the PROCESS runner.
id: node_cached_dependenciesnamespace: company.team
tasks: - id: working_dir type: io.kestra.plugin.core.flow.WorkingDirectory cache: patterns: - node_modules/** ttl: PT1H tasks: - id: node_script type: io.kestra.plugin.scripts.node.Script beforeCommands: - npm install colors script: | const colors = require("colors"); console.log(colors.red("Hello"));Python example (Process runner)
This flow installs pandas into a deps folder and caches it for one day.
id: python_cached_dependenciesnamespace: company.team
tasks: - id: working_dir type: io.kestra.plugin.core.flow.WorkingDirectory tasks: - id: python_script type: io.kestra.plugin.scripts.python.Script taskRunner: type: io.kestra.plugin.core.runner.Process beforeCommands: - pip install --target=./deps pandas env: PYTHONPATH: "./deps" script: | import pandas as pd print(pd.__version__) cache: patterns: - deps/** ttl: PT24HCache invalidation
- After the first run, files are cached.
- On subsequent runs, if the
ttlhas not elapsed, the cached files are restored. If it has elapsed, the cache is cleared andbeforeCommands(e.g.npm install) runs in full. - Changing the
ttltakes effect on the next run.
The ttl is evaluated at runtime against the last task execution date.
Cache task outputs with taskCache
The taskCache property stores a task’s status and outputs in Kestra’s database. When the same execution runs again with identical inputs, Kestra skips the task and reuses the cached outputs. It is most effective for heavy operations such as large data extractions or long-running scripts.
Task caching is only supported for Runnable Tasks.
Syntax
taskCache: enabled: true ttl: PT1H # Duration in ISO 8601 format, e.g., PT1H for 1 hourThe ttl property defines how long cached outputs are kept before expiring. Use any ISO 8601 duration (e.g., PT1H for 1 hour, PT24H for 1 day, or P7D for 7 days).
Example
This flow downloads product data once per day, caches it for 24 hours, and reuses it in joins with frequently updated transaction data.
id: cachingnamespace: company.team
tasks: - id: transactions type: io.kestra.plugin.core.http.Download uri: https://huggingface.co/datasets/kestra/datasets/resolve/main/csv/cache_demo/transactions.csv
- id: products type: io.kestra.plugin.core.http.Download uri: https://huggingface.co/datasets/kestra/datasets/resolve/main/csv/cache_demo/products.csv description: This task pulls the full product catalog once per day. Because the catalog changes infrequently and contains over 200k rows, running it only once daily avoids unnecessary strain on a production DB, while ensuring downstream joins always use up-to-date reference data. taskCache: enabled: true ttl: PT24H
- id: duckdb type: io.kestra.plugin.jdbc.duckdb.Query store: true inputFiles: products.csv: "{{ outputs.products.uri }}" transactions.csv: "{{ outputs.transactions.uri }}" sql: |- SELECT t.transaction_id, t.timestamp, t.quantity, t.sale_price, p.product_name, p.category, p.cost_price, p.supplier_id, (t.sale_price - p.cost_price) * t.quantity AS profit FROM read_csv_auto('transactions.csv') AS t JOIN read_csv_auto('products.csv') AS p USING (product_id);This approach minimizes load on the production database while ensuring transactions are always processed against up-to-date product data.
Was this page helpful?