From 653b9396fc07e77d2ee2ebc0e95981e08af7e22b Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 16:00:24 +1300 Subject: [PATCH 01/39] Add api guide --- docs/nextflow/reduce-api-calls.md | 153 ++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 docs/nextflow/reduce-api-calls.md diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md new file mode 100644 index 000000000..1e1a02e7c --- /dev/null +++ b/docs/nextflow/reduce-api-calls.md @@ -0,0 +1,153 @@ +--- +title: Reduce Wave API calls +description: Advanced +tags: [nextflow, wave, use cases] +--- + +Wave rate limits can affect large-scale pipelines that pull containers across thousands of concurrent tasks. This guide shows you how to use Wave freeze to reduce API calls and avoid rate limits. + +## How Wave rate limits work + +Wave applies rate limits to manifest requests, not layer requests. With an access token, you can pull 2,000 containers per minute. When you pull a container: + +- The manifest request counts as one pull against your rate limit. +- Layer and blob requests don't count against rate limits. +- A container with 100 layers counts as 1 pull. + +Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: + +- 50 concurrent pipeline runs +- Each run spawns 10,000 tasks +- Each task pulls a container +- Total: 500,000 manifest requests + +This volume exceeds the 2,000 per minute limit and causes failed tasks and pipeline errors. + +## Use Wave freeze to avoid rate limits + +Wave freeze builds your container once and stores it in your registry. After the initial build, all container pulls bypass Wave. + +**Augmentation without freeze:** + +1. Each task requests a manifest from Wave. +1. Wave retrieves the base image from the source registry. +1. Wave augments the image with the fusion layer. +1. Wave returns the modified manifest. +1. Every task creates one API call to Wave. + +With thousands of concurrent tasks, this approach exceeds rate limits. + +**Augmentation with freeze:** + +1. Wave builds the image once with your specifications. +1. Wave pushes the complete image to your registry. +1. Wave stores the manifest in its database. +1. Wave returns a direct URL to your registry. +1. All future pulls go directly to your registry. + +With freeze enabled, Wave is removed from the container pull path. Your compute instances pull directly from your registry with no Wave API calls. + +## Configure Wave freeze + +To configure Wave freeze, add the following configuration to your Nextflow pipeline: + +```groovy +wave.enabled = true +wave.freeze = true +wave.build.repository = '' + +tower.accessToken = '' +``` + +Replace the following: + +- ``: the repository to store your built containers +- ``: your Seqera access token + +### Container registry selection + +**Recommended**: Use Amazon ECR for AWS Batch workloads + +Amazon ECR provides the following benefits: + +- Automatic authentication through IAM roles. +- No manual credential configuration +- Lowest latency for AWS workloads. +- Simplest setup. + +**Not recommended**: Private Docker Hub for AWS Batch workloads + +Private Docker Hub has the following limitations: + +- Requires manual credential configuration on each compute instance. +- Additional security overhead. +- More complex authentication setup. + +If you use private Docker Hub, configure Docker credentials on each compute instance. + +### First pipeline run + +When you run your pipeline for the first time with Wave freeze: + +1. The Nextflow head job sends your build request to Wave. +1. Wave checks whether the requested images already exist. +1. Wave builds any missing images and pushes them to your registry. +1. Wave returns the final registry URLs. +1. Your compute tasks pull images directly from your registry. + +The initial build counts against build limits, not pull limits. Build limits are significantly higher than pull limits. + +### Subsequent pipeline runs + +When you run your pipeline again: + +1. The Nextflow head job contacts Wave to check for existing images. +1. Wave finds the cached images (matched by content hash). +1. Wave returns the registry URLs immediately without rebuilding. +1. All container pulls go directly to your registry. +1. No Wave API calls occur during task execution. + +Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. + +## Remove Wave from production pipelines + +For containers that change infrequently, you can remove Wave from your production workflows. + +### Extract container URLs + +To run your pipeline without Wave: + +1. Run your pipeline with Wave freeze enabled: + + ```bash + nextflow run main.nf + ``` + +1. Inspect the pipeline to view the container URLs that Wave created: + + ```bash + nextflow inspect main.nf + ``` + +1. Update your pipeline and configuration: + 1. Copy the registry URLs from the inspect output. + 1. Update your pipeline to use these direct URLs. + 1. Set `wave.enabled = false` in your configuration. + 1. Remove Wave dependencies from your setup. + +After you complete these steps, all container pulls go directly to your registry. + +### When to use this approach + +Remove Wave from production pipelines when: + +- Your containers change infrequently (monthly or yearly). +- You need maximum performance and minimal dependencies. +- You want complete control over container versions. +- You can manage a periodic rebuild process. + +Don't remove Wave when: + +- You frequently update container dependencies. +- You're actively developing and testing workflows. +- You need Wave's dynamic container building features. From 7eb3fde3408cb7fb76f3b3d8a4e42415e0c01a0b Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 16:16:26 +1300 Subject: [PATCH 02/39] Update front matter --- docs/nextflow/reduce-api-calls.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 1e1a02e7c..555355421 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -1,7 +1,9 @@ --- title: Reduce Wave API calls -description: Advanced -tags: [nextflow, wave, use cases] +description: Learn how to use Wave freeze to reduce API calls and avoid rate limits in large-scale Nextflow pipelines +date created: 2025-09-30 +date edited: 2025-09-30 +tags: [nextflow, wave, rate limits, use cases, guides] --- Wave rate limits can affect large-scale pipelines that pull containers across thousands of concurrent tasks. This guide shows you how to use Wave freeze to reduce API calls and avoid rate limits. From d47ef175fd804dd886a70f22c44f3730399ff708 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 17:26:19 +1300 Subject: [PATCH 03/39] Add fixes --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 555355421..25de36091 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -97,7 +97,7 @@ When you run your pipeline for the first time with Wave freeze: 1. Wave returns the final registry URLs. 1. Your compute tasks pull images directly from your registry. -The initial build counts against build limits, not pull limits. Build limits are significantly higher than pull limits. +The initial build counts against build limits, not pull limits. ### Subsequent pipeline runs From 652e861e0c8c8f14918e53f2cf150e4a38586aa2 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 20:23:11 +1300 Subject: [PATCH 04/39] Remove incorrect Wave store manifest point --- docs/nextflow/reduce-api-calls.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 25de36091..b065e783f 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -29,21 +29,20 @@ This volume exceeds the 2,000 per minute limit and causes failed tasks and pipel Wave freeze builds your container once and stores it in your registry. After the initial build, all container pulls bypass Wave. -**Augmentation without freeze:** +**Building without freeze:** 1. Each task requests a manifest from Wave. 1. Wave retrieves the base image from the source registry. -1. Wave augments the image with the fusion layer. +1. Wave builds the image with the fusion layer. 1. Wave returns the modified manifest. 1. Every task creates one API call to Wave. With thousands of concurrent tasks, this approach exceeds rate limits. -**Augmentation with freeze:** +**Building with freeze:** 1. Wave builds the image once with your specifications. 1. Wave pushes the complete image to your registry. -1. Wave stores the manifest in its database. 1. Wave returns a direct URL to your registry. 1. All future pulls go directly to your registry. From 34022935841266c403219e2fba29bcebe5e78b3d Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 20:24:53 +1300 Subject: [PATCH 05/39] Remove manifest and replace with pull --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index b065e783f..adf21ccb9 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -10,7 +10,7 @@ Wave rate limits can affect large-scale pipelines that pull containers across th ## How Wave rate limits work -Wave applies rate limits to manifest requests, not layer requests. With an access token, you can pull 2,000 containers per minute. When you pull a container: +Wave applies rate limits to container pulls. With an access token, you can pull 2,000 containers per minute. When you pull a container: - The manifest request counts as one pull against your rate limit. - Layer and blob requests don't count against rate limits. From cec1e4df0dab6d6191b1ab2a733940fc155ac0ae Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 22:45:43 +1300 Subject: [PATCH 06/39] Move text to minimal admonition --- docs/nextflow/reduce-api-calls.md | 124 ++++++++++++------------------ 1 file changed, 50 insertions(+), 74 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index adf21ccb9..981940156 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -3,18 +3,32 @@ title: Reduce Wave API calls description: Learn how to use Wave freeze to reduce API calls and avoid rate limits in large-scale Nextflow pipelines date created: 2025-09-30 date edited: 2025-09-30 -tags: [nextflow, wave, rate limits, use cases, guides] +tags: [nextflow, wave, rate limits, guides] --- Wave rate limits can affect large-scale pipelines that pull containers across thousands of concurrent tasks. This guide shows you how to use Wave freeze to reduce API calls and avoid rate limits. -## How Wave rate limits work +## API limits -Wave applies rate limits to container pulls. With an access token, you can pull 2,000 containers per minute. When you pull a container: +Wave applies rate limits to container builds and pulls. Authenticated users have higher rate limits than anonymous users. -- The manifest request counts as one pull against your rate limit. -- Layer and blob requests don't count against rate limits. -- A container with 100 layers counts as 1 pull. +If an access token is provided, the following rate limits apply: + +- 250 container builds per hour +- 2,000 container pulls per minute + +If an access token isn't provided, the following rate limits apply: + +- 25 container builds per day +- 100 container pulls per hour + +## How Wave pull rate limits work + +When you pull a container: + +- The manifest request counts as one pull against your rate limit +- Layer and blob requests don't count against rate limits +- A container with 100 layers counts as 1 pull Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: @@ -31,20 +45,20 @@ Wave freeze builds your container once and stores it in your registry. After the **Building without freeze:** -1. Each task requests a manifest from Wave. -1. Wave retrieves the base image from the source registry. -1. Wave builds the image with the fusion layer. -1. Wave returns the modified manifest. -1. Every task creates one API call to Wave. +1. Each task requests a manifest from Wave +1. Wave retrieves the base image from the source registry +1. Wave builds the image with the fusion layer +1. Wave returns the modified manifest +1. Every task creates one API call to Wave With thousands of concurrent tasks, this approach exceeds rate limits. **Building with freeze:** -1. Wave builds the image once with your specifications. -1. Wave pushes the complete image to your registry. -1. Wave returns a direct URL to your registry. -1. All future pulls go directly to your registry. +1. Wave builds the image once with your specifications +1. Wave pushes the complete image to your registry +1. Wave returns a direct URL to your registry +1. All future pulls go directly to your registry With freeze enabled, Wave is removed from the container pull path. Your compute instances pull directly from your registry with no Wave API calls. @@ -62,7 +76,7 @@ tower.accessToken = '' Replace the following: -- ``: the repository to store your built containers +- ``: your repository to store and access built containers - ``: your Seqera access token ### Container registry selection @@ -71,18 +85,18 @@ Replace the following: Amazon ECR provides the following benefits: -- Automatic authentication through IAM roles. +- Automatic authentication through IAM roles - No manual credential configuration -- Lowest latency for AWS workloads. -- Simplest setup. +- Lowest latency for AWS workloads +- Simplest setup **Not recommended**: Private Docker Hub for AWS Batch workloads Private Docker Hub has the following limitations: -- Requires manual credential configuration on each compute instance. -- Additional security overhead. -- More complex authentication setup. +- Requires manual credential configuration on each compute instance +- Additional security overhead +- More complex authentication setup If you use private Docker Hub, configure Docker credentials on each compute instance. @@ -90,65 +104,27 @@ If you use private Docker Hub, configure Docker credentials on each compute inst When you run your pipeline for the first time with Wave freeze: -1. The Nextflow head job sends your build request to Wave. -1. Wave checks whether the requested images already exist. -1. Wave builds any missing images and pushes them to your registry. -1. Wave returns the final registry URLs. -1. Your compute tasks pull images directly from your registry. +1. The Nextflow head job sends your build request to Wave +1. Wave checks whether the requested images already exist +1. Wave builds any missing images and pushes them to your registry +1. Wave returns the final registry URLs +1. Your compute tasks pull images directly from your registry -The initial build counts against build limits, not pull limits. +The initial build counts against build limits, not pull limits ### Subsequent pipeline runs When you run your pipeline again: -1. The Nextflow head job contacts Wave to check for existing images. -1. Wave finds the cached images (matched by content hash). -1. Wave returns the registry URLs immediately without rebuilding. -1. All container pulls go directly to your registry. -1. No Wave API calls occur during task execution. +1. The Nextflow head job contacts Wave to check for existing images +1. Wave finds the cached images (matched by content hash) +1. Wave returns the registry URLs immediately without rebuilding +1. All container pulls go directly to your registry +1. No Wave API calls occur during task execution Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. -## Remove Wave from production pipelines - -For containers that change infrequently, you can remove Wave from your production workflows. - -### Extract container URLs - -To run your pipeline without Wave: - -1. Run your pipeline with Wave freeze enabled: - - ```bash - nextflow run main.nf - ``` - -1. Inspect the pipeline to view the container URLs that Wave created: - - ```bash - nextflow inspect main.nf - ``` - -1. Update your pipeline and configuration: - 1. Copy the registry URLs from the inspect output. - 1. Update your pipeline to use these direct URLs. - 1. Set `wave.enabled = false` in your configuration. - 1. Remove Wave dependencies from your setup. - -After you complete these steps, all container pulls go directly to your registry. - -### When to use this approach - -Remove Wave from production pipelines when: - -- Your containers change infrequently (monthly or yearly). -- You need maximum performance and minimal dependencies. -- You want complete control over container versions. -- You can manage a periodic rebuild process. - -Don't remove Wave when: +:::note +For stable containers, you may run `nextflow inspect main.nf` to get registry URLs and update your pipeline to use them directly. Keep Wave enabled during active development or when using dynamic container features. +::: -- You frequently update container dependencies. -- You're actively developing and testing workflows. -- You need Wave's dynamic container building features. From 6f43c0f731cc894376cd23ae85f7cc6664b08da3 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 30 Sep 2025 23:00:58 +1300 Subject: [PATCH 07/39] Fix small typo --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 981940156..390b9684c 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -83,7 +83,7 @@ Replace the following: **Recommended**: Use Amazon ECR for AWS Batch workloads -Amazon ECR provides the following benefits: +Amazon ECR has the following benefits: - Automatic authentication through IAM roles - No manual credential configuration From 4eafc28b93e8056479a5e7e18029285a4168a7a8 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 07:25:15 +1300 Subject: [PATCH 08/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 390b9684c..863ed49fa 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -41,7 +41,7 @@ This volume exceeds the 2,000 per minute limit and causes failed tasks and pipel ## Use Wave freeze to avoid rate limits -Wave freeze builds your container once and stores it in your registry. After the initial build, all container pulls bypass Wave. +Wave freeze builds your container once and stores it in your registry. After the initial build, the source for the container manifest and layers are redirected to your private registry by Wave. **Building without freeze:** From 6500d35f0ac79586c412f5c37a02c8e9f02ce15c Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 07:25:25 +1300 Subject: [PATCH 09/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 863ed49fa..0bdf30013 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -55,7 +55,7 @@ With thousands of concurrent tasks, this approach exceeds rate limits. **Building with freeze:** -1. Wave builds the image once with your specifications +1. Wave retrieves the manifest or builds the image once with your specifications 1. Wave pushes the complete image to your registry 1. Wave returns a direct URL to your registry 1. All future pulls go directly to your registry From 7746228fdf189b93ef7d5e2eabdc4244bfb82045 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 07:25:38 +1300 Subject: [PATCH 10/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 0bdf30013..310210a9b 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -120,7 +120,7 @@ When you run your pipeline again: 1. Wave finds the cached images (matched by content hash) 1. Wave returns the registry URLs immediately without rebuilding 1. All container pulls go directly to your registry -1. No Wave API calls occur during task execution +1. Wave API calls do not count against quota. Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. From 296116a63f141275844404f9753db01736fd6065 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 07:25:56 +1300 Subject: [PATCH 11/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 310210a9b..a2a45760b 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -125,6 +125,6 @@ When you run your pipeline again: Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. :::note -For stable containers, you may run `nextflow inspect main.nf` to get registry URLs and update your pipeline to use them directly. Keep Wave enabled during active development or when using dynamic container features. +For stable containers, you can run `nextflow inspect` to generate a Nextflow configuration that includes resolved container URLs from your repository, which can then be used within Nextflow as an additional configuration file. Keep Wave enabled during active development or when using dynamic container features to build containers at runtime. ::: From a6f8c01dd0509442874d3ce7566117db376240bc Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 07:26:47 +1300 Subject: [PATCH 12/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index a2a45760b..11c53c850 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -46,7 +46,7 @@ Wave freeze builds your container once and stores it in your registry. After the **Building without freeze:** 1. Each task requests a manifest from Wave -1. Wave retrieves the base image from the source registry +1. Wave either retrieves the base image manifest from the source registry, builds the image from a Dockerfile or builds the image from a Conda definition. 1. Wave builds the image with the fusion layer 1. Wave returns the modified manifest 1. Every task creates one API call to Wave From a79e036f6117b59f86fdfa78be7bf648a0c92204 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 07:27:04 +1300 Subject: [PATCH 13/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 11c53c850..958a451bb 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -56,7 +56,7 @@ With thousands of concurrent tasks, this approach exceeds rate limits. **Building with freeze:** 1. Wave retrieves the manifest or builds the image once with your specifications -1. Wave pushes the complete image to your registry +1. Wave pushes the complete image manifest and layers to your registry 1. Wave returns a direct URL to your registry 1. All future pulls go directly to your registry From cbc92b31d42fbb63980cce34880f03ffa86d899b Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 09:04:40 +1300 Subject: [PATCH 14/39] Apply suggestions from code review --- docs/nextflow/reduce-api-calls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 958a451bb..50e65a628 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -15,12 +15,12 @@ Wave applies rate limits to container builds and pulls. Authenticated users have If an access token is provided, the following rate limits apply: - 250 container builds per hour -- 2,000 container pulls per minute +- 2,000 container pulls (manifests) per minute If an access token isn't provided, the following rate limits apply: - 25 container builds per day -- 100 container pulls per hour +- 100 container pulls (manifests) per hour ## How Wave pull rate limits work From cedfd5b2ba9885b48f03be81d523ae5d6bf52c59 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 09:40:58 +1300 Subject: [PATCH 15/39] Apply suggestions from code review --- docs/nextflow/reduce-api-calls.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 50e65a628..3827b2d3e 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -10,17 +10,17 @@ Wave rate limits can affect large-scale pipelines that pull containers across th ## API limits -Wave applies rate limits to container builds and pulls. Authenticated users have higher rate limits than anonymous users. +Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. If an access token is provided, the following rate limits apply: - 250 container builds per hour -- 2,000 container pulls (manifests) per minute +- 2,000 container pulls (manifest requests) per minute If an access token isn't provided, the following rate limits apply: - 25 container builds per day -- 100 container pulls (manifests) per hour +- 100 container pulls (manifest requests) per hour ## How Wave pull rate limits work From 5590e72bdd5a05a453a81edc6aabc19da1706e47 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 09:43:30 +1300 Subject: [PATCH 16/39] Apply suggestions from code review Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 3827b2d3e..e6f4ea84a 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -47,7 +47,7 @@ Wave freeze builds your container once and stores it in your registry. After the 1. Each task requests a manifest from Wave 1. Wave either retrieves the base image manifest from the source registry, builds the image from a Dockerfile or builds the image from a Conda definition. -1. Wave builds the image with the fusion layer +1. Wave injects the fusion layer to the container manifest 1. Wave returns the modified manifest 1. Every task creates one API call to Wave @@ -58,7 +58,11 @@ With thousands of concurrent tasks, this approach exceeds rate limits. 1. Wave retrieves the manifest or builds the image once with your specifications 1. Wave pushes the complete image manifest and layers to your registry 1. Wave returns a direct URL to your registry -1. All future pulls go directly to your registry +On subsequent attempts to access the container, Wave will not rebuild the existing container: + +1. Wave checks for existence of the container +1. Wave identifies the container exists at the Wave Freeze configured location +1. Wave returns the existing URL to your registry With freeze enabled, Wave is removed from the container pull path. Your compute instances pull directly from your registry with no Wave API calls. From 6b018a239706f2f8e62fe638ac6928248ed1bc87 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 09:57:01 +1300 Subject: [PATCH 17/39] Apply suggestions from code review --- docs/nextflow/reduce-api-calls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index e6f4ea84a..7cc81eae3 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -96,13 +96,13 @@ Amazon ECR has the following benefits: **Not recommended**: Private Docker Hub for AWS Batch workloads -Private Docker Hub has the following limitations: +External container registries have following limitations: - Requires manual credential configuration on each compute instance - Additional security overhead - More complex authentication setup -If you use private Docker Hub, configure Docker credentials on each compute instance. +If you use external container registries, configure your credentials on each compute instance. ### First pipeline run From e3f11bad6b7e7ff9f66a81bd869724c59945cf36 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 10:02:59 +1300 Subject: [PATCH 18/39] Apply suggestions from code review Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 7cc81eae3..30e01d795 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -64,7 +64,7 @@ On subsequent attempts to access the container, Wave will not rebuild the existi 1. Wave identifies the container exists at the Wave Freeze configured location 1. Wave returns the existing URL to your registry -With freeze enabled, Wave is removed from the container pull path. Your compute instances pull directly from your registry with no Wave API calls. +With freeze enabled, only the first API call to Wave counts towards your quota. You can access the same container thousands of times without affecting your allowance. ## Configure Wave freeze From 0d2c036cf3ed064526777fd8fb42dfdd1f0b0029 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 1 Oct 2025 13:58:02 +1300 Subject: [PATCH 19/39] Fold in changes and restrucure --- docs/nextflow/reduce-api-calls.md | 119 +++++++++++++++--------------- 1 file changed, 59 insertions(+), 60 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 30e01d795..4e87459e0 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -1,12 +1,12 @@ --- title: Reduce Wave API calls -description: Learn how to use Wave freeze to reduce API calls and avoid rate limits in large-scale Nextflow pipelines +description: Learn how to freeze containers and reduce API calls in large-scale Nextflow pipelines date created: 2025-09-30 -date edited: 2025-09-30 +date edited: 2025-10-01 tags: [nextflow, wave, rate limits, guides] --- -Wave rate limits can affect large-scale pipelines that pull containers across thousands of concurrent tasks. This guide shows you how to use Wave freeze to reduce API calls and avoid rate limits. +Wave rate limits can affect large-scale pipelines that pull container images across thousands of concurrent tasks. This guide shows you how to use Wave freeze to reduce API calls and avoid rate limits. ## API limits @@ -24,66 +24,94 @@ If an access token isn't provided, the following rate limits apply: ## How Wave pull rate limits work -When you pull a container: +When you pull a container image: - The manifest request counts as one pull against your rate limit - Layer and blob requests don't count against rate limits -- A container with 100 layers counts as 1 pull +- A container image with 100 layers counts as 1 pull Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: - 50 concurrent pipeline runs - Each run spawns 10,000 tasks -- Each task pulls a container +- Each task pulls a container image - Total: 500,000 manifest requests This volume exceeds the 2,000 per minute limit and causes failed tasks and pipeline errors. -## Use Wave freeze to avoid rate limits +## How Wave freeze to avoids rate limits -Wave freeze builds your container once and stores it in your registry. After the initial build, the source for the container manifest and layers are redirected to your private registry by Wave. +Wave freeze builds your container image once and stores it in your registry. After the initial build, the source for the container image manifest and layers are redirected to your private registry by Wave. -**Building without freeze:** +### Building without Wave freeze -1. Each task requests a manifest from Wave -1. Wave either retrieves the base image manifest from the source registry, builds the image from a Dockerfile or builds the image from a Conda definition. -1. Wave injects the fusion layer to the container manifest -1. Wave returns the modified manifest -1. Every task creates one API call to Wave +When you run your pipeline without Wave freeze: + +1. Each task requests a manifest from Wave. +1. Wave either retrieves the base image manifest from the source registry, builds the image from a Dockerfile, or builds the image from a Conda definition. +1. Wave injects the Fusion layer to the container image manifest. +1. Wave stores the built container images on Seqera infrastructure. +1. Wave returns the modified manifest. +1. Every task creates one API call to Wave. With thousands of concurrent tasks, this approach exceeds rate limits. -**Building with freeze:** +### Building with Wave freeze + +When you run your pipeline with Wave freeze for the first time: -1. Wave retrieves the manifest or builds the image once with your specifications -1. Wave pushes the complete image manifest and layers to your registry -1. Wave returns a direct URL to your registry -On subsequent attempts to access the container, Wave will not rebuild the existing container: +1. The Nextflow head job sends your build request to Wave. +1. Wave checks whether the requested images already exist. +1. Wave builds any missing images and pushes them to your registry. +1. Wave returns the final registry URLs. +1. Your compute tasks pull images directly from your registry. -1. Wave checks for existence of the container -1. Wave identifies the container exists at the Wave Freeze configured location -1. Wave returns the existing URL to your registry +When you run your pipeline with Wave freeze again: -With freeze enabled, only the first API call to Wave counts towards your quota. You can access the same container thousands of times without affecting your allowance. +1. The Nextflow head job contacts Wave to request the frozen images. +1. Wave's rate limiting applies to this request. +1. Wave finds the frozen images in your registry (matched by content hash). +1. Wave returns the registry URLs immediately without rebuilding. +1. All tasks pull the image directly from your registry. +1. The same frozen image serves many task executions. + +With freeze enabled, only the first API call to Wave counts towards your quota. +Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. + +:::note +For stable container images, you can run `nextflow inspect` to generate a Nextflow configuration that includes resolved container registry URLs. These can then be used within Nextflow as an additional configuration file. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. +::: ## Configure Wave freeze To configure Wave freeze, add the following configuration to your Nextflow pipeline: ```groovy -wave.enabled = true -wave.freeze = true -wave.build.repository = '' - -tower.accessToken = '' +fusion.enabled = true // Recommended +tower.accessToken = '' // Required +wave.enabled = true // Required +wave.freeze = true // Required +wave.build.repository = '' // Required +wave.build.cacheRepository = '' // Recommended ``` Replace the following: -- ``: your repository to store and access built containers - ``: your Seqera access token +- ``: the container registry URL where Wave uploads built images +- ``: the container registry URL for caching image layers built by the Wave service + +:::note +Specify `wave.build.cacheRepository` to accelerate container builds. +The cache reuses unchanged layers to reduce build times and costs. +::: + +:::note +Fusion isn't required for Wave freeze. +However, Fusion ensures that the frozen images contain the necessary components for optimal performance when when accessing cloud object storage. +::: -### Container registry selection +## Container registry selection **Recommended**: Use Amazon ECR for AWS Batch workloads @@ -94,7 +122,7 @@ Amazon ECR has the following benefits: - Lowest latency for AWS workloads - Simplest setup -**Not recommended**: Private Docker Hub for AWS Batch workloads +**Not recommended**: External container registries for AWS Batch workloads External container registries have following limitations: @@ -103,32 +131,3 @@ External container registries have following limitations: - More complex authentication setup If you use external container registries, configure your credentials on each compute instance. - -### First pipeline run - -When you run your pipeline for the first time with Wave freeze: - -1. The Nextflow head job sends your build request to Wave -1. Wave checks whether the requested images already exist -1. Wave builds any missing images and pushes them to your registry -1. Wave returns the final registry URLs -1. Your compute tasks pull images directly from your registry - -The initial build counts against build limits, not pull limits - -### Subsequent pipeline runs - -When you run your pipeline again: - -1. The Nextflow head job contacts Wave to check for existing images -1. Wave finds the cached images (matched by content hash) -1. Wave returns the registry URLs immediately without rebuilding -1. All container pulls go directly to your registry -1. Wave API calls do not count against quota. - -Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. - -:::note -For stable containers, you can run `nextflow inspect` to generate a Nextflow configuration that includes resolved container URLs from your repository, which can then be used within Nextflow as an additional configuration file. Keep Wave enabled during active development or when using dynamic container features to build containers at runtime. -::: - From 85af124fd3bb95d4ddb0f25c4a78fc6e0a42d771 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 1 Oct 2025 20:52:52 +1300 Subject: [PATCH 20/39] Update docs/nextflow/reduce-api-calls.md --- docs/nextflow/reduce-api-calls.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 4e87459e0..a1f7fec1a 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -76,6 +76,7 @@ When you run your pipeline with Wave freeze again: 1. The same frozen image serves many task executions. With freeze enabled, only the first API call to Wave counts towards your quota. +Frozen images will be reused as long as the image and its configuration remain the same. Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. :::note From c784bb094fbd5b57976ef2e9d65b95eed8a5e11e Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 1 Oct 2025 21:03:50 +1300 Subject: [PATCH 21/39] Add section about tag selection --- docs/nextflow/reduce-api-calls.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index a1f7fec1a..d9444c400 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -112,6 +112,12 @@ Fusion isn't required for Wave freeze. However, Fusion ensures that the frozen images contain the necessary components for optimal performance when when accessing cloud object storage. ::: +## Container image tags + +Use specific version tags (such as `ubuntu:22.04`) or SHA256 digests with Wave freeze. +Specific tags enable Wave to match content hashes and reuse frozen images, which ensures reproducibility and eliminates unnecessary rebuilds. +Avoid the `latest` tag because it points to different image versions over time. + ## Container registry selection **Recommended**: Use Amazon ECR for AWS Batch workloads From d183f3ac3b7cc715115913f7b128f014ed684e8d Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Thu, 2 Oct 2025 11:25:07 +1300 Subject: [PATCH 22/39] Make registries more generic --- docs/nextflow/reduce-api-calls.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index d9444c400..978b0032d 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -120,21 +120,27 @@ Avoid the `latest` tag because it points to different image versions over time. ## Container registry selection -**Recommended**: Use Amazon ECR for AWS Batch workloads +**Recommended**: Use your cloud provider's native container registry for simplest setup and integration. -Amazon ECR has the following benefits: +Native cloud registries have the following benefits: -- Automatic authentication through IAM roles -- No manual credential configuration -- Lowest latency for AWS workloads -- Simplest setup +- Automatic authentication through cloud IAM roles +- Low latency for workloads in the same cloud region +- Simple setup and configuration +- Native integration with your cloud platform -**Not recommended**: External container registries for AWS Batch workloads +Examples of native registries by cloud provider: -External container registries have following limitations: +- **AWS**: Amazon Elastic Container Registry (ECR) +- **Azure**: Azure Container Registry (ACR) +- **Google Cloud**: Google Artifact Registry + +**Not recommended**: Third-party container registries + +Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) have the following limitations: - Requires manual credential configuration on each compute instance - Additional security overhead - More complex authentication setup -If you use external container registries, configure your credentials on each compute instance. +If you use third-party registries, configure your credentials on each compute instance. From 2edcd695521d4895628bd9f871333e608f72d265 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Fri, 3 Oct 2025 10:44:45 +1300 Subject: [PATCH 23/39] Apply suggestions from code review - Apply direct suggestions Co-authored-by: Adam Talbot <12817534+adamrtalbot@users.noreply.github.com> --- docs/nextflow/reduce-api-calls.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 978b0032d..7a5b80145 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -26,7 +26,7 @@ If an access token isn't provided, the following rate limits apply: When you pull a container image: -- The manifest request counts as one pull against your rate limit +- The manifest request to Wave counts as one pull against your rate limit - Layer and blob requests don't count against rate limits - A container image with 100 layers counts as 1 pull @@ -50,7 +50,7 @@ When you run your pipeline without Wave freeze: 1. Each task requests a manifest from Wave. 1. Wave either retrieves the base image manifest from the source registry, builds the image from a Dockerfile, or builds the image from a Conda definition. 1. Wave injects the Fusion layer to the container image manifest. -1. Wave stores the built container images on Seqera infrastructure. +1. Wave stores the final manifest on Seqera infrastructure. 1. Wave returns the modified manifest. 1. Every task creates one API call to Wave. @@ -62,16 +62,15 @@ When you run your pipeline with Wave freeze for the first time: 1. The Nextflow head job sends your build request to Wave. 1. Wave checks whether the requested images already exist. -1. Wave builds any missing images and pushes them to your registry. +1. Wave builds any missing images and pushes the manifest and layers to your registry. 1. Wave returns the final registry URLs. 1. Your compute tasks pull images directly from your registry. When you run your pipeline with Wave freeze again: 1. The Nextflow head job contacts Wave to request the frozen images. -1. Wave's rate limiting applies to this request. 1. Wave finds the frozen images in your registry (matched by content hash). -1. Wave returns the registry URLs immediately without rebuilding. +1. Wave returns the container URLs in the destination container registry without rebuilding. 1. All tasks pull the image directly from your registry. 1. The same frozen image serves many task executions. From 10549b2a48f1e83d8a4bcc2c2c34264ba8783f2b Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Fri, 3 Oct 2025 11:06:11 +1300 Subject: [PATCH 24/39] Add longer note about using Wave CLI and nextflow inspect --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 7a5b80145..4effd9c2d 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -79,7 +79,7 @@ Frozen images will be reused as long as the image and its configuration remain t Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. :::note -For stable container images, you can run `nextflow inspect` to generate a Nextflow configuration that includes resolved container registry URLs. These can then be used within Nextflow as an additional configuration file. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. +For stable container images, you can resolve container URLs using [`nextflow inspect`](https://nextflow.io/docs/latest/reference/cli.html#inspect) or [Wave CLI](../cli/index.md). Both tools generate Nextflow configuration files with resolved container registry URLs that you can you to configure your pipeline. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. ::: ## Configure Wave freeze From 6926886dc5d1f3521f6fb257294b6bd70b5c36b5 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Sat, 4 Oct 2025 02:23:12 +1300 Subject: [PATCH 25/39] Update docs/nextflow/reduce-api-calls.md --- docs/nextflow/reduce-api-calls.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 4effd9c2d..747e87ec2 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -26,6 +26,11 @@ If an access token isn't provided, the following rate limits apply: When you pull a container image: +1. The Docker service downloads the container manifest (a JSON file detailing each layer of the final image). +1. The Docker service downloads each layer listed in the manifest file. + +Wave defines a pull as downloading both the container manifest and all layers. Therefore: + - The manifest request to Wave counts as one pull against your rate limit - Layer and blob requests don't count against rate limits - A container image with 100 layers counts as 1 pull From 9476a08c2f47ff8c53f56cd9e88e3360feeced76 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Fri, 31 Oct 2025 17:35:47 +1300 Subject: [PATCH 26/39] Clean up --- docs/nextflow/reduce-api-calls.md | 54 +++++++++++++++++-------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 747e87ec2..266e186a9 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -6,18 +6,18 @@ date edited: 2025-10-01 tags: [nextflow, wave, rate limits, guides] --- -Wave rate limits can affect large-scale pipelines that pull container images across thousands of concurrent tasks. This guide shows you how to use Wave freeze to reduce API calls and avoid rate limits. +Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. This guide describes how to use Wave freeze to reduce API calls and avoid rate limits. ## API limits Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. -If an access token is provided, the following rate limits apply: +If you provide a Platform access token, the following rate limits apply: - 250 container builds per hour - 2,000 container pulls (manifest requests) per minute -If an access token isn't provided, the following rate limits apply: +If you don't provide a Platform access token, the following rate limits apply: - 25 container builds per day - 100 container pulls (manifest requests) per hour @@ -31,35 +31,38 @@ When you pull a container image: Wave defines a pull as downloading both the container manifest and all layers. Therefore: -- The manifest request to Wave counts as one pull against your rate limit -- Layer and blob requests don't count against rate limits -- A container image with 100 layers counts as 1 pull +- The manifest request to Wave counts as one pull against your rate limit. +- Layer and blob requests don't count against rate limits. +- A container image with 100 layers counts as 1 pull. Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: - 50 concurrent pipeline runs - Each run spawns 10,000 tasks - Each task pulls a container image -- Total: 500,000 manifest requests +- 500,000 manifest requests are made -This volume exceeds the 2,000 per minute limit and causes failed tasks and pipeline errors. +This volume exceeds the 2,000 container pulls per minute limit and causes failed tasks and pipeline errors. -## How Wave freeze to avoids rate limits +## How Wave freeze avoids rate limits -Wave freeze builds your container image once and stores it in your registry. After the initial build, the source for the container image manifest and layers are redirected to your private registry by Wave. +Wave freeze builds your container image once and stores it in your registry. After the initial build, the source of the container image manifest and layers are redirected to your private registry by Wave. ### Building without Wave freeze When you run your pipeline without Wave freeze: 1. Each task requests a manifest from Wave. -1. Wave either retrieves the base image manifest from the source registry, builds the image from a Dockerfile, or builds the image from a Conda definition. +1. Wave performs one of the following actions: + - Retrieves the base image manifest from the source registry + - Builds the image from a Dockerfile + - Builds the image from a Conda definition 1. Wave injects the Fusion layer to the container image manifest. 1. Wave stores the final manifest on Seqera infrastructure. 1. Wave returns the modified manifest. 1. Every task creates one API call to Wave. -With thousands of concurrent tasks, this approach exceeds rate limits. +This approach exceeds rate limits with thousands of concurrent tasks. ### Building with Wave freeze @@ -77,14 +80,14 @@ When you run your pipeline with Wave freeze again: 1. Wave finds the frozen images in your registry (matched by content hash). 1. Wave returns the container URLs in the destination container registry without rebuilding. 1. All tasks pull the image directly from your registry. -1. The same frozen image serves many task executions. +1. The frozen image serves many task executions. -With freeze enabled, only the first API call to Wave counts towards your quota. -Frozen images will be reused as long as the image and its configuration remain the same. -Rate limit issues are eliminated because manifest requests happen at the registry level, not through Wave. +With freeze enabled, only the first API call to Wave counts toward your quota. +Wave reuses frozen images as long as the image and its configuration remain the same. +This prevents rate limit issues because manifest requests happen at the registry level, not through Wave. :::note -For stable container images, you can resolve container URLs using [`nextflow inspect`](https://nextflow.io/docs/latest/reference/cli.html#inspect) or [Wave CLI](../cli/index.md). Both tools generate Nextflow configuration files with resolved container registry URLs that you can you to configure your pipeline. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. +For stable container images, you can resolve container URLs using [`nextflow inspect`](https://nextflow.io/docs/latest/reference/cli.html#inspect) or [Wave CLI](../cli/index.md). Both tools generate Nextflow configuration files with resolved container registry URLs that can be used to configure your pipeline. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. ::: ## Configure Wave freeze @@ -102,29 +105,30 @@ wave.build.cacheRepository = '' // Recommended Replace the following: -- ``: your Seqera access token +- ``: your Platform access token - ``: the container registry URL where Wave uploads built images - ``: the container registry URL for caching image layers built by the Wave service :::note -Specify `wave.build.cacheRepository` to accelerate container builds. +To accelerate container builds, specify `wave.build.cacheRepository`. The cache reuses unchanged layers to reduce build times and costs. ::: :::note -Fusion isn't required for Wave freeze. -However, Fusion ensures that the frozen images contain the necessary components for optimal performance when when accessing cloud object storage. +You can use Wave freeze without Fusion. +However, it ensures that the frozen images contain the necessary components for optimal performance when accessing cloud object storage. ::: ## Container image tags Use specific version tags (such as `ubuntu:22.04`) or SHA256 digests with Wave freeze. -Specific tags enable Wave to match content hashes and reuse frozen images, which ensures reproducibility and eliminates unnecessary rebuilds. -Avoid the `latest` tag because it points to different image versions over time. +Specific tags enable Wave to match content hashes and reuse frozen images. +This ensures reproducibility and eliminates unnecessary rebuilds. +Avoid using the `latest` tag because it points to different image versions over time. ## Container registry selection -**Recommended**: Use your cloud provider's native container registry for simplest setup and integration. +**Recommended**: Use your cloud provider's native container registry for the simplest setup and integration. Native cloud registries have the following benefits: @@ -147,4 +151,4 @@ Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) have - Additional security overhead - More complex authentication setup -If you use third-party registries, configure your credentials on each compute instance. +If you use third-party registries, you must configure your credentials on each compute instance. From 455fa1dd12711832cd9d5240308e9cc9f190ff3c Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Fri, 31 Oct 2025 17:52:28 +1300 Subject: [PATCH 27/39] Fix consistency --- docs/nextflow/reduce-api-calls.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 266e186a9..2a730e5bb 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -1,8 +1,8 @@ --- -title: Reduce Wave API calls +title: Reducing Wave API calls description: Learn how to freeze containers and reduce API calls in large-scale Nextflow pipelines date created: 2025-09-30 -date edited: 2025-10-01 +date edited: 2025-10-31 tags: [nextflow, wave, rate limits, guides] --- @@ -31,9 +31,9 @@ When you pull a container image: Wave defines a pull as downloading both the container manifest and all layers. Therefore: -- The manifest request to Wave counts as one pull against your rate limit. -- Layer and blob requests don't count against rate limits. -- A container image with 100 layers counts as 1 pull. +- The manifest request to Wave counts as one pull against your rate limit +- Layer and blob requests don't count against rate limits +- A container image with 100 layers counts as 1 pull Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: @@ -143,7 +143,7 @@ Examples of native registries by cloud provider: - **Azure**: Azure Container Registry (ACR) - **Google Cloud**: Google Artifact Registry -**Not recommended**: Third-party container registries +**Not recommended**: Third-party container registries. Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) have the following limitations: From 7f14844f116f3cbc3046a1434fc68881bcb14e55 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 11 Nov 2025 11:08:28 +1300 Subject: [PATCH 28/39] Fix comments --- docs/nextflow/configuration.md | 4 ++++ docs/nextflow/reduce-api-calls.md | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/nextflow/configuration.md b/docs/nextflow/configuration.md index 4bd9d3fc8..3b61574bc 100644 --- a/docs/nextflow/configuration.md +++ b/docs/nextflow/configuration.md @@ -43,6 +43,8 @@ Use the following options to configure general Wave settings: Use the following options to configure Wave build settings: +

+ `wave.build.cacheRepository` : Specifies the container repository URL for caching image layers built by the Wave service. Requires corresponding credentials to be configured in your Seqera account. @@ -69,6 +71,8 @@ Use the following options to configure Wave build settings: : Specifies the Mamba container image used for building Conda-based containers. Must be a [micromamba-docker](https://github.com/mamba-org/micromamba-docker) compatible image. +

+ `wave.build.repository` : Specifies the container repository URL where Wave uploads built images. Requires corresponding credentials to be configured in your Seqera account. diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 2a730e5bb..8707b3f91 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -39,6 +39,7 @@ Rate limits affect pipelines with high concurrency. The following example demons - 50 concurrent pipeline runs - Each run spawns 10,000 tasks +- Each task runs on it's own VM - Each task pulls a container image - 500,000 manifest requests are made @@ -60,7 +61,6 @@ When you run your pipeline without Wave freeze: 1. Wave injects the Fusion layer to the container image manifest. 1. Wave stores the final manifest on Seqera infrastructure. 1. Wave returns the modified manifest. -1. Every task creates one API call to Wave. This approach exceeds rate limits with thousands of concurrent tasks. @@ -80,14 +80,13 @@ When you run your pipeline with Wave freeze again: 1. Wave finds the frozen images in your registry (matched by content hash). 1. Wave returns the container URLs in the destination container registry without rebuilding. 1. All tasks pull the image directly from your registry. -1. The frozen image serves many task executions. With freeze enabled, only the first API call to Wave counts toward your quota. Wave reuses frozen images as long as the image and its configuration remain the same. This prevents rate limit issues because manifest requests happen at the registry level, not through Wave. :::note -For stable container images, you can resolve container URLs using [`nextflow inspect`](https://nextflow.io/docs/latest/reference/cli.html#inspect) or [Wave CLI](../cli/index.md). Both tools generate Nextflow configuration files with resolved container registry URLs that can be used to configure your pipeline. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. +For pipelines with stable containers, you can prevent Wave API calls by pre-resolving URLs with [`nextflow inspect`](https://nextflow.io/docs/latest/reference/cli.html#inspect) or [Wave CLI](../cli/index.md), then using the resolved registry URLs directly in your configuration. Keep Wave enabled during active development or when using dynamic container features to build container images at runtime. ::: ## Configure Wave freeze @@ -105,9 +104,9 @@ wave.build.cacheRepository = '' // Recommended Replace the following: -- ``: your Platform access token -- ``: the container registry URL where Wave uploads built images -- ``: the container registry URL for caching image layers built by the Wave service +- ``: your [Platform access token](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token) +- ``: the [container registry URL](./configuration.md#build-repository) where Wave uploads built images +- ``: the [container registry URL](./configuration.md#build-cacherepository) for caching image layers built by the Wave service :::note To accelerate container builds, specify `wave.build.cacheRepository`. @@ -143,12 +142,13 @@ Examples of native registries by cloud provider: - **Azure**: Azure Container Registry (ACR) - **Google Cloud**: Google Artifact Registry -**Not recommended**: Third-party container registries. +**Alternate**: Third-party container registries. -Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) have the following limitations: +Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) require additional setup and have the following requirements: -- Requires manual credential configuration on each compute instance -- Additional security overhead -- More complex authentication setup +- Manual credential configuration on each compute instance +- Public endpoints for Wave to connect to +- Additional security configuration +- More complex authentication setup compared to native registries If you use third-party registries, you must configure your credentials on each compute instance. From 833d6e206134159ba17215bbac343bbd64779efe Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 11 Nov 2025 11:09:55 +1300 Subject: [PATCH 29/39] Fix comments --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 8707b3f91..eb7c7c430 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -142,7 +142,7 @@ Examples of native registries by cloud provider: - **Azure**: Azure Container Registry (ACR) - **Google Cloud**: Google Artifact Registry -**Alternate**: Third-party container registries. +**Alternative option**: Third-party container registries. Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) require additional setup and have the following requirements: From 34adc4b112e0e455a00f00e1c2241a231ef1b9bf Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Tue, 11 Nov 2025 11:20:57 +1300 Subject: [PATCH 30/39] Add inline commnets --- docs/nextflow/reduce-api-calls.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index eb7c7c430..c790ba720 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -94,12 +94,12 @@ For pipelines with stable containers, you can prevent Wave API calls by pre-reso To configure Wave freeze, add the following configuration to your Nextflow pipeline: ```groovy -fusion.enabled = true // Recommended +fusion.enabled = true // Recommended (optimizes frozen images for cloud storage) tower.accessToken = '' // Required wave.enabled = true // Required wave.freeze = true // Required wave.build.repository = '' // Required -wave.build.cacheRepository = '' // Recommended +wave.build.cacheRepository = '' // Recommended (accelerates builds by reusing unchanged layers) ``` Replace the following: @@ -108,16 +108,6 @@ Replace the following: - ``: the [container registry URL](./configuration.md#build-repository) where Wave uploads built images - ``: the [container registry URL](./configuration.md#build-cacherepository) for caching image layers built by the Wave service -:::note -To accelerate container builds, specify `wave.build.cacheRepository`. -The cache reuses unchanged layers to reduce build times and costs. -::: - -:::note -You can use Wave freeze without Fusion. -However, it ensures that the frozen images contain the necessary components for optimal performance when accessing cloud object storage. -::: - ## Container image tags Use specific version tags (such as `ubuntu:22.04`) or SHA256 digests with Wave freeze. From 058de522ee98509d78b901f35918b92bb0cbb5ea Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 12 Nov 2025 10:11:19 +1300 Subject: [PATCH 31/39] Fix links --- docs/nextflow/reduce-api-calls.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index c790ba720..2bd86a2e7 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -104,9 +104,9 @@ wave.build.cacheRepository = '' // Recommended (accelerates bu Replace the following: -- ``: your [Platform access token](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token) -- ``: the [container registry URL](./configuration.md#build-repository) where Wave uploads built images -- ``: the [container registry URL](./configuration.md#build-cacherepository) for caching image layers built by the Wave service +- [``](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token): your Platform access token +- [``](./configuration.md#build-repository): the container registry URL where Wave uploads built images +- [``](./configuration.md#build-cacherepository): the container registry URL for caching image layers built by the Wave service ## Container image tags @@ -134,11 +134,9 @@ Examples of native registries by cloud provider: **Alternative option**: Third-party container registries. -Third-party registries (such as Docker Hub, Quay.io, or JFrog Artifactory) require additional setup and have the following requirements: +Third-party registries (e.g., Docker Hub or Quay.io) require additional setup and have the following requirements: - Manual credential configuration on each compute instance - Public endpoints for Wave to connect to - Additional security configuration - More complex authentication setup compared to native registries - -If you use third-party registries, you must configure your credentials on each compute instance. From b9e5f619f2102af290b80a32d905b26d2f3bd3d5 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 12 Nov 2025 16:20:29 +1300 Subject: [PATCH 32/39] Remove links failing checks --- docs/nextflow/configuration.md | 4 ---- docs/nextflow/reduce-api-calls.md | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/nextflow/configuration.md b/docs/nextflow/configuration.md index 3b61574bc..4bd9d3fc8 100644 --- a/docs/nextflow/configuration.md +++ b/docs/nextflow/configuration.md @@ -43,8 +43,6 @@ Use the following options to configure general Wave settings: Use the following options to configure Wave build settings: -

- `wave.build.cacheRepository` : Specifies the container repository URL for caching image layers built by the Wave service. Requires corresponding credentials to be configured in your Seqera account. @@ -71,8 +69,6 @@ Use the following options to configure Wave build settings: : Specifies the Mamba container image used for building Conda-based containers. Must be a [micromamba-docker](https://github.com/mamba-org/micromamba-docker) compatible image. -

- `wave.build.repository` : Specifies the container repository URL where Wave uploads built images. Requires corresponding credentials to be configured in your Seqera account. diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 2bd86a2e7..6c00fb393 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -104,9 +104,9 @@ wave.build.cacheRepository = '' // Recommended (accelerates bu Replace the following: -- [``](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token): your Platform access token -- [``](./configuration.md#build-repository): the container registry URL where Wave uploads built images -- [``](./configuration.md#build-cacherepository): the container registry URL for caching image layers built by the Wave service +- ``: your [Platform access token](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token) +- ``: the container registry URL where Wave uploads built images +- ``: the container registry URL for caching image layers built by the Wave service ## Container image tags From 2d86ee5c8240231557ef36debfc7929e22253eca Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 3 Dec 2025 09:52:17 +1300 Subject: [PATCH 33/39] Commit changes to generate preview --- docs/api.md | 525 +++++++++++++++--------------- docs/nextflow/reduce-api-calls.md | 16 +- 2 files changed, 271 insertions(+), 270 deletions(-) diff --git a/docs/api.md b/docs/api.md index 07f44c392..72e3da89d 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4,7 +4,7 @@ title: API This page summarizes the API provided by the Wave container service. -**API limits** +## API limits The Wave service implements API rate limits for API calls. Authenticated users have higher rate limits than anonymous users. @@ -18,7 +18,11 @@ If an access token isn't provided, the following rate limits apply: - 25 container builds per day - 100 container pulls per hour -## POST `/container-token` +## APIs + +This section summarizes the API provided by the Wave container service. + +### POST `/container-token` Deprecated endpoint allows you to submit a request to access a private container registry via Wave, or build a container image on-the-fly with a Dockerfile or Conda recipe file. @@ -30,7 +34,7 @@ This API endpoint is deprecated in current versions of Wave. ::: -### Request body +#### Request body ```json { @@ -65,7 +69,7 @@ This API endpoint is deprecated in current versions of Wave. } ``` -#### Container token request attributes +**Container token request attributes** | Attribute | Description | | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -90,7 +94,7 @@ This API endpoint is deprecated in current versions of Wave. | `towerAccessToken` | Access token of the user account granting access to the Seqera Platform service specified via `towerEndpoint` (optional). | | `towerWorkspaceId` | ID of the Seqera Platform workspace from where the container registry credentials are retrieved (optional). When omitted the personal workspace is used. | -### Response +#### Response ```json { @@ -100,19 +104,21 @@ This API endpoint is deprecated in current versions of Wave. } ``` +**Container token response attributes** + | Attribute | Description | | ---------------- | ---------------------------------------------------------------------------------------- | | `containerToken` | The unique token identifying the Wave container request, e.g., `0123456789`. | | `targetImage` | The Wave container image name, e.g., `wave.seqera.io/wt/0123456789/library/ubuntu:latest`. | | `expiration` | The expiration timestamp of the Wave container using ISO-8601 format. | -## POST `/v1alpha2/container` +### POST `/v1alpha2/container` This endpoint allows you to submit a request to access a private container registry via Wave, or build a container image on-the-fly with a Dockerfile or Conda recipe file. The endpoint returns the name of the container request made available by Wave. -### Request body +#### Request body ```json { @@ -160,7 +166,7 @@ The endpoint returns the name of the container request made available by Wave. } ``` -#### Container token request attributes +**Container token request attributes** | Attribute | Description | | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -197,7 +203,7 @@ The endpoint returns the name of the container request made available by Wave. | `rImage` | Name of the R Docker image used to build CRAN containers (e.g., `rocker/r-ver:4.4.1`). | | `nameStrategy` | The name strategy to be used to create the name of the container built by Wave. Its values can be `none`, `tagPrefix`, or `imageSuffix`. | | -### Response +#### Response ```json { @@ -209,7 +215,7 @@ The endpoint returns the name of the container request made available by Wave. } ``` -#### Container token response attributes +**Container token response attributes** | Attribute | Description | | ---------------- | ---------------------------------------------------------------------------------------- | @@ -218,155 +224,155 @@ The endpoint returns the name of the container request made available by Wave. | `expiration` | The expiration timestamp of the Wave container using ISO-8601 format. | | `cached` | Indicates if the requested image is built or in progress. | -### Examples - -1. Create Docker image with Conda packages: - -##### Request - -```shell -curl --location 'http://localhost:9090/v1alpha2/container' \ ---header 'Content-Type: application/json' \ ---data '{ - "packages":{ - "type": "CONDA", - "entries": ["salmon", "bwa"], - "channels": ["conda-forge", "bioconda"] - } -}' -``` - -#### Response - -```json -{ - "containerToken":"732b73aa17c8", - "targetImage":"0625dce899da.ngrok.app/wt/732b73aa17c8/hrma017/dev:salmon_bwa--5e49881e6ad74121", - "expiration":"2024-04-09T21:19:01.715321Z", - "buildId":"5e49881e6ad74121_1", - "cached":false, - "freeze":false -} -``` - -2. Create Singularity image with Conda packages: - -##### Request - -```shell -curl --location 'http://localhost:9090/v1alpha2/container' \ ---header 'Content-Type: application/json' \ ---data '{ - "format": "sif", - "containerPlatform": "arm64", - "packages":{ - "type": "CONDA", - "entries": ["salmon"], - "channels": ["conda-forge", "bioconda"] - }, - "freeze": true, - "buildRepository": , - "towerAccessToken":, - "towerEndpoint": "http://localhost:8008/api" -}' -``` - -#### Response - -```json -{ - "targetImage":"oras://:salmon--6c084f2e43f86a78", - "buildId":"6c084f2e43f86a78_1", - "cached":false, - "freeze":true -} -``` - -:::note -You must add your container registry credentials in Seqera Platform to use the freeze feature. This is a requirement for Singularity. -::: +#### Examples -3. Create Docker image with CRAN packages: +- Create Docker image with Conda packages: -##### Request + **Request:** -```shell -curl --location 'http://localhost:9090/v1alpha2/container' \ ---header 'Content-Type: application/json' \ ---data '{ - "packages":{ - "type": "CRAN", - "entries": ["dplyr", "ggplot2"], - "channels": ["cran"], - "cranOpts": { - "rImage": "rocker/r-ver:4.4.1", - "basePackages": "littler r-cran-docopt" + ```shell + curl --location 'http://localhost:9090/v1alpha2/container' \ + --header 'Content-Type: application/json' \ + --data '{ + "packages":{ + "type": "CONDA", + "entries": ["salmon", "bwa"], + "channels": ["conda-forge", "bioconda"] } + }' + ``` + + **Response** + + ```json + { + "containerToken":"732b73aa17c8", + "targetImage":"0625dce899da.ngrok.app/wt/732b73aa17c8/hrma017/dev:salmon_bwa--5e49881e6ad74121", + "expiration":"2024-04-09T21:19:01.715321Z", + "buildId":"5e49881e6ad74121_1", + "cached":false, + "freeze":false } -}' -``` - -#### Response - -```json -{ - "requestId": "22d3c6c1cb06", - "containerToken": "22d3c6c1cb06", - "targetImage": "wave.seqera.io/wt/22d3c6c1cb06/wave/build:49b26ca0c3a07b1b", - "expiration": "2025-11-09T02:50:23.254497148Z", - "containerImage": "private.cr.seqera.io/wave/build:49b26ca0c3a07b1b", - "buildId": "bd-49b26ca0c3a07b1b_1", - "cached": false, - "freeze": false, - "mirror": false, - "scanId": "sc-a6acedfe6969f4bf_1" -} -``` - -4. Create Singularity image with CRAN packages: - -##### Request - -```shell -curl --location 'https://wave.seqera.io/v1alpha2/container' \ ---header 'Content-Type: application/json' \ ---data '{ - "format": "sif", - "containerPlatform": "linux/amd64", - "packages":{ - "type": "CRAN", - "entries": ["tidyverse", "data.table"], - "channels": ["cran"], - "cranOpts": { - "rImage": "rocker/r-ver:4.4.1", - "basePackages": "build-essential" + ``` + +- Create Singularity image with Conda packages: + + **Request** + + ```shell + curl --location 'http://localhost:9090/v1alpha2/container' \ + --header 'Content-Type: application/json' \ + --data '{ + "format": "sif", + "containerPlatform": "arm64", + "packages":{ + "type": "CONDA", + "entries": ["salmon"], + "channels": ["conda-forge", "bioconda"] + }, + "freeze": true, + "buildRepository": , + "towerAccessToken":, + "towerEndpoint": "http://localhost:8008/api" + }' + ``` + + **Response** + + ```json + { + "targetImage":"oras://:salmon--6c084f2e43f86a78", + "buildId":"6c084f2e43f86a78_1", + "cached":false, + "freeze":true + } + ``` + + :::note + To create Singularity images with the freeze feature, you must add your container registry credentials in Seqera Platform. + ::: + +- Create Docker image with CRAN packages: + + **Request** + + ```shell + curl --location 'http://localhost:9090/v1alpha2/container' \ + --header 'Content-Type: application/json' \ + --data '{ + "packages":{ + "type": "CRAN", + "entries": ["dplyr", "ggplot2"], + "channels": ["cran"], + "cranOpts": { + "rImage": "rocker/r-ver:4.4.1", + "basePackages": "littler r-cran-docopt" + } } - }, - "freeze": true, - "buildRepository": "", # hrma017/test - "towerAccessToken": "" -}' -``` - -#### Response - -```json -{ - "requestId": "6706d70da258", - "targetImage": "oras://hrma017/test:a4fd48144607aaa7", - "containerImage": "oras://hrma017/test:a4fd48144607aaa7", - "buildId": "bd-a4fd48144607aaa7_1", - "freeze": true, - "mirror": false, - "succeeded": true -} -``` + }' + ``` + + **Response** + + ```json + { + "requestId": "22d3c6c1cb06", + "containerToken": "22d3c6c1cb06", + "targetImage": "wave.seqera.io/wt/22d3c6c1cb06/wave/build:49b26ca0c3a07b1b", + "expiration": "2025-11-09T02:50:23.254497148Z", + "containerImage": "private.cr.seqera.io/wave/build:49b26ca0c3a07b1b", + "buildId": "bd-49b26ca0c3a07b1b_1", + "cached": false, + "freeze": false, + "mirror": false, + "scanId": "sc-a6acedfe6969f4bf_1" + } + ``` + +- Create Singularity image with CRAN packages: + + **Request** + + ```shell + curl --location 'https://wave.seqera.io/v1alpha2/container' \ + --header 'Content-Type: application/json' \ + --data '{ + "format": "sif", + "containerPlatform": "linux/amd64", + "packages":{ + "type": "CRAN", + "entries": ["tidyverse", "data.table"], + "channels": ["cran"], + "cranOpts": { + "rImage": "rocker/r-ver:4.4.1", + "basePackages": "build-essential" + } + }, + "freeze": true, + "buildRepository": "", # hrma017/test + "towerAccessToken": "" + }' + ``` + + **Response** + + ```json + { + "requestId": "6706d70da258", + "targetImage": "oras://hrma017/test:a4fd48144607aaa7", + "containerImage": "oras://hrma017/test:a4fd48144607aaa7", + "buildId": "bd-a4fd48144607aaa7_1", + "freeze": true, + "mirror": false, + "succeeded": true + } + ``` -## GET `/v1alpha1/builds/{buildId}/status` +### GET `/v1alpha1/builds/{buildId}/status` Provides status of build against buildId passed as path variable -### Response +#### Response ```json { @@ -382,7 +388,7 @@ Provides status of build against buildId passed as path variable Status can only be `PENDING` or `COMPLETED`. ::: -### Example +#### Examples ```shell % curl --location 'http://localhost:9090/v1alpha1/builds/6c084f2e43f86a78_1/status' @@ -395,7 +401,7 @@ Status can only be `PENDING` or `COMPLETED`. } ``` -## GET `/v1alpha1/builds/{buildId}/logs` +### GET `/v1alpha1/builds/{buildId}/logs` Supply logs corresponding to the specified buildId within the API request. @@ -405,9 +411,9 @@ Supply logs corresponding to the specified buildId within the API request. string ``` -### Example +#### Example -``` +```shell % curl --location 'http://localhost:9090/v1alpha1/builds//logs' INFO[0001] Retrieving image manifest alpine:latest INFO[0001] Retrieving image alpine:latest from registry index.docker.io @@ -425,11 +431,11 @@ INFO[0002] Pushing image to / INFO[0005] Pushed index.docker.io// ``` -## GET `/service-info` +### GET `/service-info` Provides basic information about the service status. -### Response +#### Response ```json { @@ -440,11 +446,11 @@ Provides basic information about the service status. } ``` -## POST `/v1alpha1/inspect` +### POST `/v1alpha1/inspect` This endpoint returns the metadata about provided container image -### Request +#### Request ```json { @@ -455,7 +461,7 @@ This endpoint returns the metadata about provided container image } ``` -#### Container inspect request attributes +**Container inspect request attributes** | Attribute | Description | | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -464,7 +470,7 @@ This endpoint returns the metadata about provided container image | `towerAccessToken` | Access token of the user account granting the access to the Seqera Platform service specified via `towerEndpoint` (optional). | | `towerWorkspaceId` | ID of the Seqera Platform workspace from where the container registry credentials are retrieved (optional). When omitted the personal workspace is used.| -### Response +#### Response ```json { @@ -519,72 +525,74 @@ This endpoint returns the metadata about provided container image You can find the explanation of the response attributes (here)[https://github.com/opencontainers/image-spec/blob/main/spec.md] ::: -### Example - -#### API call - -```shell -curl --location 'http://localhost:9090/v1alpha1/inspect' \ ---header 'Content-Type: application/json' \ ---data '{ - "containerImage": "docker.io//", - "towerAccessToken": "", - "towerEndpoint": "http://localhost:8000/api" -}' -``` - -##### Response +#### Examples -```json -{ - "container": { - "registry": "docker.io", - "hostName": "https://registry-1.docker.io", - "imageName": "//", - "reference": "9b80535d04eceefd", - "digest": "sha256:1fcabdb850dc7c46646b3796fca01aca5721330252b586058e0d326705374dd5", - "config": { - "architecture": "amd64", +- API call + + **Request** + + ```shell + curl --location 'http://localhost:9090/v1alpha1/inspect' \ + --header 'Content-Type: application/json' \ + --data '{ + "containerImage": "docker.io//", + "towerAccessToken": "", + "towerEndpoint": "http://localhost:8000/api" + }' + ``` + + **Response** + + ```json + { + "container": { + "registry": "docker.io", + "hostName": "https://registry-1.docker.io", + "imageName": "//", + "reference": "9b80535d04eceefd", + "digest": "sha256:1fcabdb850dc7c46646b3796fca01aca5721330252b586058e0d326705374dd5", "config": { - "env": [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "cmd": [ - "/bin/sh" - ], - "image": "sha256:9a5ce069f40cfe0f2270eafbff0a0f2fa08f1add73571af9f78209e96bb8a5e9" + "architecture": "amd64", + "config": { + "env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "cmd": [ + "/bin/sh" + ], + "image": "sha256:9a5ce069f40cfe0f2270eafbff0a0f2fa08f1add73571af9f78209e96bb8a5e9" + }, + "container": "4189cbc534955765760c227f328ec1cdd52e8550681c2bf9f8f990b27b644f9c", + "created": "2024-04-19T14:38:17.047396956Z", + "rootfs": { + "type": "layers", + "diff_ids": [ + "sha256:d4fc045c9e3a848011de66f34b81f052d4f2c15a17bb196d637e526349601820" + ] + } }, - "container": "4189cbc534955765760c227f328ec1cdd52e8550681c2bf9f8f990b27b644f9c", - "created": "2024-04-19T14:38:17.047396956Z", - "rootfs": { - "type": "layers", - "diff_ids": [ - "sha256:d4fc045c9e3a848011de66f34b81f052d4f2c15a17bb196d637e526349601820" + "manifest": { + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "digest": "sha256:639823e18eb8b62cf43e92bac114ae35c03c07449e4ee5c10f8ebf8d033877d6", + "size": 774 + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8", + "size": 3408729 + } ] - } - }, - "manifest": { - "schemaVersion": 2, - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "config": { - "mediaType": "application/vnd.docker.container.image.v1+json", - "digest": "sha256:639823e18eb8b62cf43e92bac114ae35c03c07449e4ee5c10f8ebf8d033877d6", - "size": 774 }, - "layers": [ - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "digest": "sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8", - "size": 3408729 - } - ] - }, - "v1": false, - "v2": true, - "oci": false + "v1": false, + "v2": true, + "oci": false + } } -} -``` + ``` ## Metrics APIs based on Redis @@ -602,11 +610,11 @@ All Metrics API endpoints use these query parameters: These APIs are used to retrieve metrics about container builds performed by Wave. -### GET `/v1alpha2/metrics/builds` +#### GET `/v1alpha2/metrics/builds` This endpoint is used to retrieve the builds performed by Wave. -### Response +#### Response ```json { @@ -622,45 +630,48 @@ This endpoint is used to retrieve the builds performed by Wave. #### Examples -```shell -curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds" -{ - "metric": "builds", - "count": 18, - "orgs": { - "seqera.io": 13, - "gmail.com": 5 - } -} -``` + **Requests** -```shell -curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds?date=2024-04-08&org=seqera.io" -{"count":4} -``` - -```shell -curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds?date=2024-04-08" -{ - "metric": "builds", - "count": 8, - "orgs": { - "gmail.com": 4, - "seqera.io": 4 + ```shell + curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds" + { + "metric": "builds", + "count": 18, + "orgs": { + "seqera.io": 13, + "gmail.com": 5 + } } -} -``` - -```shell -curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds?org=seqera.io" -{ - "metric": "builds", - "count": 13, - "orgs": { - "seqera.io": 13 + ``` + + ```shell + curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds?date=2024-04-08&org=seqera.io" + {"count":4} + ``` + + ```shell + curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds?date=2024-04-08" + { + "metric": "builds", + "count": 8, + "orgs": { + "gmail.com": 4, + "seqera.io": 4 + } } -} -``` + ``` + + ```shell + curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/builds?org=seqera.io" + { + "metric": "builds", + "count": 13, + "orgs": { + "seqera.io": 13 + } + } + ``` + ### Pull Metrics API These APIs are used to get the metrics about the container pulls through Wave. diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 6c00fb393..5117ca2fd 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -8,19 +8,9 @@ tags: [nextflow, wave, rate limits, guides] Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. This guide describes how to use Wave freeze to reduce API calls and avoid rate limits. -## API limits - -Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. - -If you provide a Platform access token, the following rate limits apply: - -- 250 container builds per hour -- 2,000 container pulls (manifest requests) per minute - -If you don't provide a Platform access token, the following rate limits apply: - -- 25 container builds per day -- 100 container pulls (manifest requests) per hour +:::note +Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. See [API limits](../api/index.md#api-limits) for more information. +::: ## How Wave pull rate limits work From 9d72d4c08f231e0c8a8b734a2d4102c2d17379f2 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 3 Dec 2025 10:32:02 +1300 Subject: [PATCH 34/39] Address comments --- docs/api.md | 81 +++++++++++++++++-------------- docs/nextflow/reduce-api-calls.md | 36 +++----------- 2 files changed, 51 insertions(+), 66 deletions(-) diff --git a/docs/api.md b/docs/api.md index 72e3da89d..5b36b40a7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -18,22 +18,41 @@ If an access token isn't provided, the following rate limits apply: - 25 container builds per day - 100 container pulls per hour -## APIs +### How Wave pull rate limits work -This section summarizes the API provided by the Wave container service. +When you pull a container image: -### POST `/container-token` +1. The Docker service downloads the container manifest (a JSON file detailing each layer of the final image). +1. The Docker service downloads each layer listed in the manifest file. -Deprecated endpoint allows you to submit a request to access a private container registry via Wave, or build a container image on-the-fly with a Dockerfile or Conda recipe file. +Wave defines a pull as downloading both the container manifest and all layers. Therefore: -The endpoint returns the name of the container request made available by Wave. +- The manifest request to Wave counts as one pull against your rate limit +- Layer and blob requests don't count against rate limits +- A container image with 100 layers counts as 1 pull -:::important +Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: -This API endpoint is deprecated in current versions of Wave. +- 50 concurrent pipeline runs +- Each run spawns 10,000 tasks +- Each task runs on it's own VM +- Each task pulls a container image +- 500,000 manifest requests are made + +This volume exceeds the 2,000 container pulls per minute limit and causes failed tasks and pipeline errors. + +## General API + +### POST `/container-token` +:::warning +This API endpoint is deprecated in current versions of Wave. ::: +Submit a request to access a private container registry via Wave, or build a container image on-the-fly with a Dockerfile or Conda recipe file. + +The endpoint returns the name of the container request made available by Wave. + #### Request body ```json @@ -114,9 +133,9 @@ This API endpoint is deprecated in current versions of Wave. ### POST `/v1alpha2/container` -This endpoint allows you to submit a request to access a private container registry via Wave, or build a container image on-the-fly with a Dockerfile or Conda recipe file. +Submit a request to access a private container registry via Wave, or build a container image on-the-fly with a Dockerfile or Conda recipe file. -The endpoint returns the name of the container request made available by Wave. +Returns the name of the container request made available by Wave. #### Request body @@ -370,7 +389,7 @@ The endpoint returns the name of the container request made available by Wave. ### GET `/v1alpha1/builds/{buildId}/status` -Provides status of build against buildId passed as path variable +Get status of build against `buildId` passed as path variable #### Response @@ -405,13 +424,13 @@ Status can only be `PENDING` or `COMPLETED`. Supply logs corresponding to the specified buildId within the API request. -### Response +#### Response ```text string ``` -#### Example +#### Examples ```shell % curl --location 'http://localhost:9090/v1alpha1/builds//logs' @@ -433,7 +452,7 @@ INFO[0005] Pushed index.docker.io// ### GET `/service-info` -Provides basic information about the service status. +Get basic information about the service status. #### Response @@ -448,7 +467,7 @@ Provides basic information about the service status. ### POST `/v1alpha1/inspect` -This endpoint returns the metadata about provided container image +Returns the metadata about provided container image #### Request @@ -529,7 +548,7 @@ You can find the explanation of the response attributes (here)[https://github.co - API call - **Request** + **Request** ```shell curl --location 'http://localhost:9090/v1alpha1/inspect' \ @@ -594,25 +613,21 @@ You can find the explanation of the response attributes (here)[https://github.co } ``` -## Metrics APIs based on Redis +## Metrics API -These APIs provide usage (builds and pulls) metrics of Wave for a specific date and/or a specific organization. -These APIs require basic authentication, so you must provide a username and password while calling these APIs. +These APIs provide usage (builds and pulls) metrics of Wave for a specific date and/or a organization. +They require basic authentication (i.e., a username and password). All Metrics API endpoints use these query parameters: | Name | Description | sample Value | |------|-----------------------------------------------------------------------|--------------| | date | Format: `yyyy-mm-dd`, The date of the required metrics. | 2024-04-08 | -| org | Domain of the organization used in emails, e.g., `org=seqera.io` | seqera.io | +| org | Domain of the organization used in emails, e.g., `org=seqera.io` | seqera.io | -### Build Metrics API +### GET `/v1alpha2/metrics/builds` -These APIs are used to retrieve metrics about container builds performed by Wave. - -#### GET `/v1alpha2/metrics/builds` - -This endpoint is used to retrieve the builds performed by Wave. +Get the builds performed by Wave. #### Response @@ -672,15 +687,11 @@ This endpoint is used to retrieve the builds performed by Wave. } ``` -### Pull Metrics API - -These APIs are used to get the metrics about the container pulls through Wave. - ### GET `/v1alpha2/metrics/pulls` -This endpoint is used to get the pulls performed through Wave. +Get the pulls performed through Wave. -### Response +#### Response ```json { @@ -736,15 +747,11 @@ curl -u foo:bar "http://localhost:9090/v1alpha2/metrics/pulls?org=seqera.io" } ``` -### Fusion Pull Metrics API - -These APIs are used to get the metrics about the Fusion-based container pulls through Wave. - ### GET `/v1alpha2/metrics/fusion/pulls` -This endpoint is used to get the pulls of Fusion-based containers performed through Wave. +Get the pulls of Fusion-based containers performed through Wave. -### Response +#### Response ```json { diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 5117ca2fd..911933a91 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -1,40 +1,17 @@ --- title: Reducing Wave API calls -description: Learn how to freeze containers and reduce API calls in large-scale Nextflow pipelines +description: Learn how to configure Nextflow to freeze containers and reduce API calls date created: 2025-09-30 date edited: 2025-10-31 tags: [nextflow, wave, rate limits, guides] --- -Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. This guide describes how to use Wave freeze to reduce API calls and avoid rate limits. +Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. This guide describes how to configure your Nextflow pipeline to use Wave freeze and reduce API calls to avoid rate limits. :::note Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. See [API limits](../api/index.md#api-limits) for more information. ::: -## How Wave pull rate limits work - -When you pull a container image: - -1. The Docker service downloads the container manifest (a JSON file detailing each layer of the final image). -1. The Docker service downloads each layer listed in the manifest file. - -Wave defines a pull as downloading both the container manifest and all layers. Therefore: - -- The manifest request to Wave counts as one pull against your rate limit -- Layer and blob requests don't count against rate limits -- A container image with 100 layers counts as 1 pull - -Rate limits affect pipelines with high concurrency. The following example demonstrates this issue: - -- 50 concurrent pipeline runs -- Each run spawns 10,000 tasks -- Each task runs on it's own VM -- Each task pulls a container image -- 500,000 manifest requests are made - -This volume exceeds the 2,000 container pulls per minute limit and causes failed tasks and pipeline errors. - ## How Wave freeze avoids rate limits Wave freeze builds your container image once and stores it in your registry. After the initial build, the source of the container image manifest and layers are redirected to your private registry by Wave. @@ -94,13 +71,14 @@ wave.build.cacheRepository = '' // Recommended (accelerates bu Replace the following: -- ``: your [Platform access token](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token) -- ``: the container registry URL where Wave uploads built images -- ``: the container registry URL for caching image layers built by the Wave service +- ``: Your [Platform access token](../tutorials/nextflow-wave.mdx#create-your-seqera-access-token) +- ``: The container registry URL where Wave uploads built images +- ``: The container registry URL for caching image layers built by the Wave service ## Container image tags -Use specific version tags (such as `ubuntu:22.04`) or SHA256 digests with Wave freeze. +**Recommended**: Use specific version tags (such as `ubuntu:22.04`) or SHA256 digests with Wave freeze. + Specific tags enable Wave to match content hashes and reuse frozen images. This ensures reproducibility and eliminates unnecessary rebuilds. Avoid using the `latest` tag because it points to different image versions over time. From a6df73fac868baa769aca65814d3ff29ccc4587b Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 3 Dec 2025 11:17:35 +1300 Subject: [PATCH 35/39] Fix link --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 911933a91..3ec53f5d3 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -9,7 +9,7 @@ tags: [nextflow, wave, rate limits, guides] Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. This guide describes how to configure your Nextflow pipeline to use Wave freeze and reduce API calls to avoid rate limits. :::note -Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. See [API limits](../api/index.md#api-limits) for more information. +Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. See [API limits](../api.md#api-limits) for more information. ::: ## How Wave freeze avoids rate limits From 8116a94a11898b9527d618950d1d0b5820d55bd3 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Wed, 3 Dec 2025 12:21:30 +1300 Subject: [PATCH 36/39] Update docs/nextflow/reduce-api-calls.md --- docs/nextflow/reduce-api-calls.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 3ec53f5d3..1bc78b5f9 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -106,5 +106,3 @@ Third-party registries (e.g., Docker Hub or Quay.io) require additional setup an - Manual credential configuration on each compute instance - Public endpoints for Wave to connect to -- Additional security configuration -- More complex authentication setup compared to native registries From d716e549fb46c5792b509fe90b7b982ddf5ddd15 Mon Sep 17 00:00:00 2001 From: Christopher Hakkaart Date: Wed, 3 Dec 2025 13:31:34 +1300 Subject: [PATCH 37/39] Apply suggestions --- docs/nextflow/reduce-api-calls.md | 40 +++++++++++++++++++------------ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 1bc78b5f9..7824080e5 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -6,7 +6,7 @@ date edited: 2025-10-31 tags: [nextflow, wave, rate limits, guides] --- -Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. This guide describes how to configure your Nextflow pipeline to use Wave freeze and reduce API calls to avoid rate limits. +Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. Wave freeze solves this by building your container once and storing it in your registry, so your head job communicates with Wave only once per container. Without freeze, all tasks communicate with Wave for every container, which may result in thousands of requests. This guide describes how to configure Wave freeze in your Nextflow pipeline to reduce API calls and avoid rate limits. :::note Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. See [API limits](../api.md#api-limits) for more information. @@ -14,20 +14,27 @@ Wave applies rate limits to container builds and pulls (manifest requests). Auth ## How Wave freeze avoids rate limits -Wave freeze builds your container image once and stores it in your registry. After the initial build, the source of the container image manifest and layers are redirected to your private registry by Wave. +Wave freeze provisions container images on-demand with the following characteristics: + +- Containers are built on-demand from a user-provided Dockerfile or Conda packages +- They have stable (non-ephemeral) container names +- They are stored in the container repository specified by `wave.build.repository` +- Build cache layers are stored in the repository specified by `wave.build.cacheRepository` + +After the initial build, Wave redirects the container manifest and layers to your private registry, so subsequent requests pull directly from your registry instead of making repeated Wave API calls. ### Building without Wave freeze When you run your pipeline without Wave freeze: -1. Each task requests a manifest from Wave. +1. Each task requests a manifest from Wave 1. Wave performs one of the following actions: - Retrieves the base image manifest from the source registry - Builds the image from a Dockerfile - Builds the image from a Conda definition -1. Wave injects the Fusion layer to the container image manifest. -1. Wave stores the final manifest on Seqera infrastructure. -1. Wave returns the modified manifest. +1. Wave injects the Fusion layer to the container image manifest +1. Wave stores the final manifest on Seqera infrastructure +1. Wave returns the modified manifest This approach exceeds rate limits with thousands of concurrent tasks. @@ -35,18 +42,21 @@ This approach exceeds rate limits with thousands of concurrent tasks. When you run your pipeline with Wave freeze for the first time: -1. The Nextflow head job sends your build request to Wave. -1. Wave checks whether the requested images already exist. -1. Wave builds any missing images and pushes the manifest and layers to your registry. -1. Wave returns the final registry URLs. -1. Your compute tasks pull images directly from your registry. +1. The Nextflow head job sends your build request to Wave +1. Wave checks whether the requested image already exist + - The content hash does not match +1. Wave builds of the container +1. Wave stores the container in your destination container registry +1. Wave returns the final registry URLs +1. Your compute tasks pull images directly from your registry When you run your pipeline with Wave freeze again: -1. The Nextflow head job contacts Wave to request the frozen images. -1. Wave finds the frozen images in your registry (matched by content hash). -1. Wave returns the container URLs in the destination container registry without rebuilding. -1. All tasks pull the image directly from your registry. +1. The Nextflow head job sends your build request to Wave +1. Wave checks whether the requested image already exist + - The content hash matches the previous build +1. Wave returns the container URLs in the destination container registry without rebuilding +1. Nextflow tasks pull the image directly from your registry With freeze enabled, only the first API call to Wave counts toward your quota. Wave reuses frozen images as long as the image and its configuration remain the same. From 512baa96b662c9d0dab1f7c7b2f32ec1a1bb770d Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Thu, 4 Dec 2025 10:26:24 +1300 Subject: [PATCH 38/39] Update docs/nextflow/reduce-api-calls.md --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index 7824080e5..f206b969e 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -6,7 +6,7 @@ date edited: 2025-10-31 tags: [nextflow, wave, rate limits, guides] --- -Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. Wave freeze solves this by building your container once and storing it in your registry, so your head job communicates with Wave only once per container. Without freeze, all tasks communicate with Wave for every container, which may result in thousands of requests. This guide describes how to configure Wave freeze in your Nextflow pipeline to reduce API calls and avoid rate limits. +Large-scale pipelines that pull container images across thousands of concurrent tasks can encounter Wave rate limits. Wave freeze solves this by building your container once and storing it in your registry, so your head job communicates with Wave only once per container. Without freeze, all tasks communicate with Wave for every container used within your pipeline. Depending on your specific pipeline configuration, this may result in a large volume of concurrent requests that trigger rate limits. :::note Wave applies rate limits to container builds and pulls (manifest requests). Authenticated users have higher rate limits than anonymous users. See [API limits](../api.md#api-limits) for more information. From 9d7b7f90d6fc94f1030f5e68753717eee82636e9 Mon Sep 17 00:00:00 2001 From: Chris Hakkaart Date: Thu, 4 Dec 2025 10:28:02 +1300 Subject: [PATCH 39/39] Update docs/nextflow/reduce-api-calls.md Co-authored-by: Gavin --- docs/nextflow/reduce-api-calls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nextflow/reduce-api-calls.md b/docs/nextflow/reduce-api-calls.md index f206b969e..554b90d44 100644 --- a/docs/nextflow/reduce-api-calls.md +++ b/docs/nextflow/reduce-api-calls.md @@ -42,7 +42,7 @@ This approach exceeds rate limits with thousands of concurrent tasks. When you run your pipeline with Wave freeze for the first time: -1. The Nextflow head job sends your build request to Wave +1. The Nextflow head job sends your container request to Wave 1. Wave checks whether the requested image already exist - The content hash does not match 1. Wave builds of the container